summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS3
-rw-r--r--.github/ISSUE_TEMPLATE.md21
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md18
-rw-r--r--.github/ISSUE_TEMPLATE/feature---enhancement-request.md19
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml24
-rw-r--r--AUTHORS.md5
-rw-r--r--COPYRIGHT.txt12
-rw-r--r--DONORS.md153
-rw-r--r--SConstruct27
-rw-r--r--core/SCsub1
-rw-r--r--core/array.cpp67
-rw-r--r--core/array.h5
-rw-r--r--core/bind/core_bind.cpp84
-rw-r--r--core/bind/core_bind.h115
-rw-r--r--core/class_db.cpp53
-rw-r--r--core/class_db.h7
-rw-r--r--core/color.cpp34
-rw-r--r--core/color.h4
-rw-r--r--core/command_queue_mt.h4
-rw-r--r--core/crypto/SCsub38
-rw-r--r--core/crypto/crypto.cpp170
-rw-r--r--core/crypto/crypto.h105
-rw-r--r--core/crypto/crypto_core.cpp (renamed from core/math/crypto_core.cpp)32
-rw-r--r--core/crypto/crypto_core.h (renamed from core/math/crypto_core.h)20
-rw-r--r--core/crypto/hashing_context.cpp137
-rw-r--r--core/crypto/hashing_context.h66
-rw-r--r--core/engine.cpp6
-rw-r--r--core/engine.h2
-rw-r--r--core/error_macros.h137
-rw-r--r--core/func_ref.cpp13
-rw-r--r--core/func_ref.h1
-rw-r--r--core/hash_map.h16
-rw-r--r--core/image.cpp150
-rw-r--r--core/image.h6
-rw-r--r--core/input_map.cpp7
-rw-r--r--core/io/config_file.cpp9
-rw-r--r--core/io/file_access_buffered.cpp12
-rw-r--r--core/io/file_access_buffered_fa.h5
-rw-r--r--core/io/file_access_compressed.cpp3
-rw-r--r--core/io/file_access_encrypted.cpp23
-rw-r--r--core/io/file_access_encrypted.h3
-rw-r--r--core/io/file_access_pack.cpp19
-rw-r--r--core/io/file_access_zip.cpp2
-rw-r--r--core/io/image_loader.h16
-rw-r--r--core/io/ip_address.cpp14
-rw-r--r--core/io/marshalls.cpp10
-rw-r--r--core/io/multiplayer_api.cpp308
-rw-r--r--core/io/multiplayer_api.h34
-rw-r--r--core/io/packet_peer.cpp8
-rw-r--r--core/io/pck_packer.cpp5
-rw-r--r--core/io/resource_format_binary.cpp49
-rw-r--r--core/io/resource_loader.cpp45
-rw-r--r--core/io/resource_loader.h3
-rw-r--r--core/io/resource_saver.cpp10
-rw-r--r--core/io/resource_saver.h4
-rw-r--r--core/io/stream_peer.cpp4
-rw-r--r--core/io/stream_peer_ssl.cpp68
-rw-r--r--core/io/stream_peer_ssl.h13
-rw-r--r--core/io/translation_loader_po.cpp25
-rw-r--r--core/io/xml_parser.cpp6
-rw-r--r--core/make_binders.py3
-rw-r--r--core/map.h6
-rw-r--r--core/math/SCsub33
-rw-r--r--core/math/a_star.cpp271
-rw-r--r--core/math/a_star.h37
-rw-r--r--core/math/basis.cpp5
-rw-r--r--core/math/basis.h4
-rw-r--r--core/math/bsp_tree.cpp4
-rw-r--r--core/math/bsp_tree.h4
-rw-r--r--core/math/camera_matrix.cpp4
-rw-r--r--core/math/camera_matrix.h4
-rw-r--r--core/math/delaunay.h4
-rw-r--r--core/math/disjoint_set.cpp31
-rw-r--r--core/math/disjoint_set.h155
-rw-r--r--core/math/expression.cpp34
-rw-r--r--core/math/expression.h2
-rw-r--r--core/math/geometry.cpp148
-rw-r--r--core/math/geometry.h224
-rw-r--r--core/math/math_funcs.cpp9
-rw-r--r--core/math/math_funcs.h41
-rw-r--r--core/math/octree.h9
-rw-r--r--core/math/quat.h4
-rw-r--r--core/math/transform.cpp5
-rw-r--r--core/math/transform.h76
-rw-r--r--core/math/transform_2d.h31
-rw-r--r--core/math/vector2.cpp13
-rw-r--r--core/math/vector2.h24
-rw-r--r--core/math/vector3.h44
-rw-r--r--core/message_queue.cpp11
-rw-r--r--core/method_bind.h4
-rw-r--r--core/node_path.cpp3
-rw-r--r--core/node_path.h4
-rw-r--r--core/oa_hash_map.h66
-rw-r--r--core/object.cpp79
-rw-r--r--core/object.h24
-rw-r--r--core/os/dir_access.cpp8
-rw-r--r--core/os/dir_access.h17
-rw-r--r--core/os/file_access.cpp8
-rw-r--r--core/os/input.cpp1
-rw-r--r--core/os/input.h1
-rw-r--r--core/os/input_event.cpp4
-rw-r--r--core/os/input_event.h4
-rw-r--r--core/os/keyboard.h4
-rw-r--r--core/os/main_loop.cpp8
-rw-r--r--core/os/main_loop.h7
-rw-r--r--core/os/memory.h4
-rw-r--r--core/os/os.cpp13
-rw-r--r--core/os/os.h10
-rw-r--r--core/os/semaphore.h4
-rw-r--r--core/os/thread.h4
-rw-r--r--core/pool_allocator.cpp13
-rw-r--r--core/pool_vector.cpp3
-rw-r--r--core/pool_vector.h14
-rw-r--r--core/project_settings.cpp28
-rw-r--r--core/project_settings.h4
-rw-r--r--core/reference.h3
-rw-r--r--core/register_core_types.cpp24
-rw-r--r--core/register_core_types.h4
-rw-r--r--core/resource.cpp8
-rw-r--r--core/resource.h4
-rw-r--r--core/rid.h4
-rw-r--r--core/script_debugger_local.cpp2
-rw-r--r--core/script_debugger_local.h2
-rw-r--r--core/script_debugger_remote.cpp152
-rw-r--r--core/script_debugger_remote.h21
-rw-r--r--core/script_language.cpp52
-rw-r--r--core/script_language.h13
-rw-r--r--core/set.h6
-rw-r--r--core/string_name.cpp3
-rw-r--r--core/string_name.h3
-rw-r--r--core/translation.cpp67
-rw-r--r--core/type_info.h19
-rw-r--r--core/ustring.cpp80
-rw-r--r--core/ustring.h8
-rw-r--r--core/variant.cpp19
-rw-r--r--core/variant.h4
-rw-r--r--core/variant_call.cpp70
-rw-r--r--core/variant_op.cpp2
-rw-r--r--core/variant_parser.cpp4
-rw-r--r--doc/classes/@GlobalScope.xml4
-rw-r--r--doc/classes/ARVRServer.xml2
-rw-r--r--doc/classes/AStar.xml82
-rw-r--r--doc/classes/AStar2D.xml82
-rw-r--r--doc/classes/AnimatedSprite.xml2
-rw-r--r--doc/classes/AnimatedSprite3D.xml2
-rw-r--r--doc/classes/AnimatedTexture.xml2
-rw-r--r--doc/classes/AnimationNode.xml2
-rw-r--r--doc/classes/AnimationPlayer.xml5
-rw-r--r--doc/classes/AnimationTree.xml2
-rw-r--r--doc/classes/Array.xml15
-rw-r--r--doc/classes/AtlasTexture.xml5
-rw-r--r--doc/classes/AudioServer.xml53
-rw-r--r--doc/classes/AudioStreamGenerator.xml1
-rw-r--r--doc/classes/AudioStreamGeneratorPlayback.xml1
-rw-r--r--doc/classes/AudioStreamPlayer.xml2
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml2
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml2
-rw-r--r--doc/classes/AudioStreamRandomPitch.xml2
-rw-r--r--doc/classes/AudioStreamSample.xml1
-rw-r--r--doc/classes/BakedLightmap.xml7
-rw-r--r--doc/classes/BaseButton.xml4
-rw-r--r--doc/classes/Basis.xml8
-rw-r--r--doc/classes/BitmapFont.xml2
-rw-r--r--doc/classes/Button.xml7
-rw-r--r--doc/classes/CPUParticles.xml57
-rw-r--r--doc/classes/CPUParticles2D.xml57
-rw-r--r--doc/classes/Camera.xml2
-rw-r--r--doc/classes/Camera2D.xml6
-rw-r--r--doc/classes/CanvasItem.xml2
-rw-r--r--doc/classes/CheckBox.xml1
-rw-r--r--doc/classes/CheckButton.xml1
-rw-r--r--doc/classes/ClassDB.xml4
-rw-r--r--doc/classes/CollisionObject2D.xml8
-rw-r--r--doc/classes/CollisionShape.xml2
-rw-r--r--doc/classes/CollisionShape2D.xml2
-rw-r--r--doc/classes/Control.xml137
-rw-r--r--doc/classes/Crypto.xml43
-rw-r--r--doc/classes/CryptoKey.xml29
-rw-r--r--doc/classes/CurveTexture.xml2
-rw-r--r--doc/classes/DirectionalLight.xml2
-rw-r--r--doc/classes/Directory.xml4
-rw-r--r--doc/classes/DynamicFont.xml2
-rw-r--r--doc/classes/EditorInterface.xml17
-rw-r--r--doc/classes/EditorPlugin.xml62
-rw-r--r--doc/classes/EditorSceneImporter.xml1
-rw-r--r--doc/classes/EditorVCSInterface.xml115
-rw-r--r--doc/classes/Engine.xml7
-rw-r--r--doc/classes/Environment.xml19
-rw-r--r--doc/classes/FileDialog.xml2
-rw-r--r--doc/classes/FuncRef.xml10
-rw-r--r--doc/classes/GIProbe.xml2
-rw-r--r--doc/classes/Geometry.xml25
-rw-r--r--doc/classes/GeometryInstance.xml14
-rw-r--r--doc/classes/GradientTexture.xml2
-rw-r--r--doc/classes/GraphEdit.xml10
-rw-r--r--doc/classes/GraphNode.xml3
-rw-r--r--doc/classes/HashingContext.xml41
-rw-r--r--doc/classes/Image.xml22
-rw-r--r--doc/classes/Input.xml27
-rw-r--r--doc/classes/InputEvent.xml5
-rw-r--r--doc/classes/JSONRPC.xml95
-rw-r--r--doc/classes/KinematicBody.xml2
-rw-r--r--doc/classes/KinematicBody2D.xml3
-rw-r--r--doc/classes/KinematicCollision.xml6
-rw-r--r--doc/classes/KinematicCollision2D.xml6
-rw-r--r--doc/classes/Light2D.xml2
-rw-r--r--doc/classes/LightOccluder2D.xml2
-rw-r--r--doc/classes/Line2D.xml6
-rw-r--r--doc/classes/LineEdit.xml3
-rw-r--r--doc/classes/MainLoop.xml20
-rw-r--r--doc/classes/Material.xml2
-rw-r--r--doc/classes/MeshInstance.xml2
-rw-r--r--doc/classes/MeshInstance2D.xml6
-rw-r--r--doc/classes/MeshTexture.xml4
-rw-r--r--doc/classes/MultiMesh.xml2
-rw-r--r--doc/classes/MultiMeshInstance.xml2
-rw-r--r--doc/classes/MultiMeshInstance2D.xml6
-rw-r--r--doc/classes/NavigationMeshInstance.xml2
-rw-r--r--doc/classes/NavigationPolygonInstance.xml2
-rw-r--r--doc/classes/NinePatchRect.xml4
-rw-r--r--doc/classes/Node.xml15
-rw-r--r--doc/classes/Node2D.xml2
-rw-r--r--doc/classes/OS.xml44
-rw-r--r--doc/classes/Object.xml2
-rw-r--r--doc/classes/PackedScene.xml12
-rw-r--r--doc/classes/PanoramaSky.xml2
-rw-r--r--doc/classes/Particles.xml4
-rw-r--r--doc/classes/Particles2D.xml6
-rw-r--r--doc/classes/ParticlesMaterial.xml29
-rw-r--r--doc/classes/Path.xml6
-rw-r--r--doc/classes/Path2D.xml5
-rw-r--r--doc/classes/Physics2DServer.xml2
-rw-r--r--doc/classes/Physics2DTestMotionResult.xml2
-rw-r--r--doc/classes/PointMesh.xml17
-rw-r--r--doc/classes/Polygon2D.xml2
-rw-r--r--doc/classes/PoolByteArray.xml13
-rw-r--r--doc/classes/PoolIntArray.xml1
-rw-r--r--doc/classes/Popup.xml7
-rw-r--r--doc/classes/PopupMenu.xml2
-rw-r--r--doc/classes/PrimitiveMesh.xml2
-rw-r--r--doc/classes/ProjectSettings.xml139
-rw-r--r--doc/classes/ProxyTexture.xml2
-rw-r--r--doc/classes/ResourceFormatLoaderCrypto.xml13
-rw-r--r--doc/classes/ResourceFormatSaverCrypto.xml13
-rw-r--r--doc/classes/RigidBody.xml2
-rw-r--r--doc/classes/RigidBody2D.xml4
-rw-r--r--doc/classes/SceneTree.xml9
-rw-r--r--doc/classes/ShaderMaterial.xml2
-rw-r--r--doc/classes/ShortCut.xml2
-rw-r--r--doc/classes/Skeleton.xml2
-rw-r--r--doc/classes/SpatialMaterial.xml10
-rw-r--r--doc/classes/SpringArm.xml2
-rw-r--r--doc/classes/Sprite.xml7
-rw-r--r--doc/classes/Sprite3D.xml5
-rw-r--r--doc/classes/SpriteBase3D.xml2
-rw-r--r--doc/classes/StaticBody.xml2
-rw-r--r--doc/classes/StaticBody2D.xml2
-rw-r--r--doc/classes/StreamPeerSSL.xml10
-rw-r--r--doc/classes/String.xml26
-rw-r--r--doc/classes/StyleBoxTexture.xml4
-rw-r--r--doc/classes/TextEdit.xml4
-rw-r--r--doc/classes/TextureButton.xml12
-rw-r--r--doc/classes/TextureLayered.xml9
-rw-r--r--doc/classes/TextureProgress.xml6
-rw-r--r--doc/classes/TextureRect.xml2
-rw-r--r--doc/classes/Theme.xml2
-rw-r--r--doc/classes/TileMap.xml2
-rw-r--r--doc/classes/TouchScreenButton.xml8
-rw-r--r--doc/classes/Transform.xml4
-rw-r--r--doc/classes/Transform2D.xml4
-rw-r--r--doc/classes/Tree.xml7
-rw-r--r--doc/classes/TreeItem.xml21
-rw-r--r--doc/classes/Variant.xml13
-rw-r--r--doc/classes/Vector2.xml35
-rw-r--r--doc/classes/Vector3.xml35
-rw-r--r--doc/classes/VehicleWheel.xml16
-rw-r--r--doc/classes/VideoPlayer.xml2
-rw-r--r--doc/classes/Viewport.xml2
-rw-r--r--doc/classes/VisualShaderNode.xml15
-rw-r--r--doc/classes/VisualShaderNodeCompare.xml45
-rw-r--r--doc/classes/VisualShaderNodeCubeMap.xml2
-rw-r--r--doc/classes/VisualShaderNodeCustom.xml149
-rw-r--r--doc/classes/VisualShaderNodeGlobalExpression.xml13
-rw-r--r--doc/classes/VisualShaderNodeGroupBase.xml4
-rw-r--r--doc/classes/VisualShaderNodeIs.xml21
-rw-r--r--doc/classes/VisualShaderNodeTexture.xml2
-rw-r--r--doc/classes/VisualShaderNodeTextureUniformTriplanar.xml13
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarMix.xml13
-rw-r--r--doc/classes/World.xml4
-rw-r--r--doc/classes/WorldEnvironment.xml2
-rw-r--r--doc/classes/X509Certificate.xml29
-rwxr-xr-xdoc/tools/makerst.py1
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp4
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp14
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp57
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h2
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp70
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h6
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp83
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h9
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp171
-rw-r--r--drivers/gles2/shaders/canvas.glsl31
-rw-r--r--drivers/gles2/shaders/canvas_shadow.glsl4
-rw-r--r--drivers/gles2/shaders/copy.glsl4
-rw-r--r--drivers/gles2/shaders/scene.glsl24
-rw-r--r--drivers/gles2/shaders/stdlib.glsl383
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp12
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp53
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h12
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp38
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp117
-rw-r--r--drivers/gles3/shader_gles3.h4
-rw-r--r--drivers/gles3/shaders/canvas.glsl28
-rw-r--r--drivers/gles3/shaders/canvas_shadow.glsl4
-rw-r--r--drivers/gles3/shaders/copy.glsl4
-rw-r--r--drivers/gles3/shaders/scene.glsl10
-rw-r--r--drivers/gles3/shaders/tonemap.glsl16
-rw-r--r--drivers/png/image_loader_png.h3
-rw-r--r--drivers/png/png_driver_common.cpp9
-rw-r--r--drivers/png/resource_saver_png.cpp11
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp25
-rw-r--r--drivers/register_driver_types.h4
-rw-r--r--drivers/unix/dir_access_unix.cpp31
-rw-r--r--drivers/unix/dir_access_unix.h4
-rw-r--r--drivers/unix/file_access_unix.cpp19
-rw-r--r--drivers/unix/file_access_unix.h4
-rw-r--r--drivers/unix/ip_unix.cpp4
-rw-r--r--drivers/unix/os_unix.cpp20
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/unix/semaphore_posix.h4
-rw-r--r--drivers/unix/thread_posix.h4
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp13
-rw-r--r--drivers/windows/file_access_windows.cpp22
-rw-r--r--drivers/windows/file_access_windows.h4
-rw-r--r--drivers/windows/mutex_windows.h4
-rw-r--r--drivers/windows/semaphore_windows.h4
-rw-r--r--drivers/windows/thread_windows.h4
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp21
-rw-r--r--editor/SCsub2
-rw-r--r--editor/animation_bezier_editor.cpp23
-rw-r--r--editor/animation_track_editor.cpp1024
-rw-r--r--editor/animation_track_editor.h8
-rw-r--r--editor/code_editor.cpp157
-rw-r--r--editor/code_editor.h6
-rw-r--r--editor/collada/collada.cpp18
-rw-r--r--editor/collada/collada.h4
-rw-r--r--editor/connections_dialog.cpp9
-rw-r--r--editor/create_dialog.cpp55
-rw-r--r--editor/create_dialog.h3
-rw-r--r--editor/doc/doc_data.cpp42
-rw-r--r--editor/editor_about.cpp4
-rw-r--r--editor/editor_about.h3
-rw-r--r--editor/editor_asset_installer.cpp18
-rw-r--r--editor/editor_audio_buses.cpp29
-rw-r--r--editor/editor_autoload_settings.cpp16
-rw-r--r--editor/editor_autoload_settings.h2
-rw-r--r--editor/editor_builders.py8
-rw-r--r--editor/editor_data.cpp24
-rw-r--r--editor/editor_data.h1
-rw-r--r--editor/editor_export.cpp46
-rw-r--r--editor/editor_file_dialog.cpp32
-rw-r--r--editor/editor_file_dialog.h3
-rw-r--r--editor/editor_file_system.cpp13
-rw-r--r--editor/editor_fonts.cpp38
-rw-r--r--editor/editor_help.cpp110
-rw-r--r--editor/editor_help.h10
-rw-r--r--editor/editor_help_search.cpp19
-rw-r--r--editor/editor_inspector.cpp32
-rw-r--r--editor/editor_log.cpp6
-rw-r--r--editor/editor_log.h3
-rw-r--r--editor/editor_network_profiler.cpp211
-rw-r--r--editor/editor_network_profiler.h72
-rw-r--r--editor/editor_node.cpp737
-rw-r--r--editor/editor_node.h34
-rw-r--r--editor/editor_plugin.cpp24
-rw-r--r--editor/editor_plugin.h13
-rw-r--r--editor/editor_plugin_settings.cpp88
-rw-r--r--editor/editor_properties.cpp112
-rw-r--r--editor/editor_properties.h2
-rw-r--r--editor/editor_properties_array_dict.cpp18
-rw-r--r--editor/editor_resource_preview.cpp11
-rw-r--r--editor/editor_run.cpp7
-rw-r--r--editor/editor_run.h2
-rw-r--r--editor/editor_sectioned_inspector.cpp27
-rw-r--r--editor/editor_sectioned_inspector.h2
-rw-r--r--editor/editor_settings.cpp137
-rw-r--r--editor/editor_settings.h3
-rw-r--r--editor/editor_spin_slider.cpp94
-rw-r--r--editor/editor_spin_slider.h1
-rw-r--r--editor/editor_themes.cpp75
-rw-r--r--editor/editor_vcs_interface.cpp194
-rw-r--r--editor/editor_vcs_interface.h83
-rw-r--r--editor/export_template_manager.cpp109
-rw-r--r--editor/file_type_cache.cpp5
-rw-r--r--editor/filesystem_dock.cpp417
-rw-r--r--editor/filesystem_dock.h8
-rw-r--r--editor/find_in_files.cpp10
-rw-r--r--editor/groups_editor.cpp213
-rw-r--r--editor/groups_editor.h20
-rw-r--r--editor/icons/icon_GUI_tree_option.svg5
-rw-r--r--editor/icons/icon_arrow_down.svg1
-rw-r--r--editor/icons/icon_arrow_up.svg6
-rw-r--r--editor/icons/icon_auto_key.svg57
-rw-r--r--editor/icons/icon_bus_vu_db.svg12
-rw-r--r--editor/icons/icon_camera_texture.svg5
-rw-r--r--editor/icons/icon_clipped_camera.svg3
-rw-r--r--editor/icons/icon_debug_skip_breakpoints_off.svg89
-rw-r--r--editor/icons/icon_debug_skip_breakpoints_on.svg106
-rw-r--r--editor/icons/icon_editor_curve_handle.svg1
-rw-r--r--editor/icons/icon_editor_path_sharp_handle.svg1
-rw-r--r--editor/icons/icon_editor_path_smooth_handle.svg1
-rw-r--r--editor/icons/icon_gizmo_c_p_u_particles.svg85
-rw-r--r--editor/icons/icon_height_map_shape.svg12
-rw-r--r--editor/icons/icon_interpolated_camera.svg2
-rw-r--r--editor/icons/icon_key_animation.svg66
-rw-r--r--editor/icons/icon_key_audio.svg66
-rw-r--r--editor/icons/icon_key_bezier.svg66
-rw-r--r--editor/icons/icon_key_call.svg65
-rw-r--r--editor/icons/icon_key_selected.svg77
-rw-r--r--editor/icons/icon_key_value.svg6
-rw-r--r--editor/icons/icon_key_xform.svg65
-rw-r--r--editor/icons/icon_mesh_texture.svg3
-rw-r--r--editor/icons/icon_point_mesh.svg7
-rw-r--r--editor/icons/icon_reparent_to_new_node.svg83
-rw-r--r--editor/icons/icon_rich_text_effect.svg6
-rw-r--r--editor/icons/icon_ruler.svg5
-rw-r--r--editor/icons/icon_shrink_bottom_dock.svg71
-rw-r--r--editor/icons/icon_skeleton_i_k.svg3
-rw-r--r--editor/icons/icon_soft_body.svg57
-rw-r--r--editor/icons/icon_spring_arm.svg6
-rw-r--r--editor/icons/icon_style_box_line.svg11
-rw-r--r--editor/icons/icon_timeline_indicator.svg1
-rw-r--r--editor/icons/icon_vulkan.svg127
-rw-r--r--editor/import/editor_import_collada.cpp75
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp1750
-rw-r--r--editor/import/editor_scene_importer_gltf.h215
-rw-r--r--editor/import/resource_importer_csv.cpp80
-rw-r--r--editor/import/resource_importer_csv.h57
-rw-r--r--editor/import/resource_importer_csv_translation.cpp3
-rw-r--r--editor/import/resource_importer_obj.cpp6
-rw-r--r--editor/import/resource_importer_scene.cpp68
-rw-r--r--editor/import/resource_importer_scene.h2
-rw-r--r--editor/import/resource_importer_wav.cpp24
-rw-r--r--editor/import_dock.cpp8
-rw-r--r--editor/inspector_dock.cpp6
-rw-r--r--editor/multi_node_edit.cpp4
-rw-r--r--editor/node_dock.cpp7
-rw-r--r--editor/plugin_config_dialog.cpp3
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp9
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp5
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h3
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp75
-rw-r--r--editor/plugins/animation_player_editor_plugin.h16
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp5
-rw-r--r--editor/plugins/animation_tree_player_editor_plugin.h3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp283
-rw-r--r--editor/plugins/asset_library_editor_plugin.h11
-rw-r--r--editor/plugins/camera_editor_plugin.h4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp561
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h54
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/curve_editor_plugin.cpp16
-rw-r--r--editor/plugins/editor_preview_plugins.cpp1
-rw-r--r--editor/plugins/item_list_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h3
-rw-r--r--editor/plugins/material_editor_plugin.cpp3
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp3
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp9
-rw-r--r--editor/plugins/multimesh_editor_plugin.h4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h3
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/particles_editor_plugin.cpp21
-rw-r--r--editor/plugins/particles_editor_plugin.h6
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp42
-rw-r--r--editor/plugins/path_2d_editor_plugin.h3
-rw-r--r--editor/plugins/path_editor_plugin.cpp3
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp40
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp3
-rw-r--r--editor/plugins/script_editor_plugin.cpp242
-rw-r--r--editor/plugins/script_editor_plugin.h3
-rw-r--r--editor/plugins/script_text_editor.cpp279
-rw-r--r--editor/plugins/script_text_editor.h6
-rw-r--r--editor/plugins/shader_editor_plugin.cpp71
-rw-r--r--editor/plugins/shader_editor_plugin.h8
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp359
-rw-r--r--editor/plugins/spatial_editor_plugin.h15
-rw-r--r--editor/plugins/sprite_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp66
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h3
-rw-r--r--editor/plugins/text_editor.cpp88
-rw-r--r--editor/plugins/text_editor.h7
-rw-r--r--editor/plugins/texture_editor_plugin.cpp3
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp34
-rw-r--r--editor/plugins/texture_region_editor_plugin.h6
-rw-r--r--editor/plugins/theme_editor_plugin.cpp85
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp139
-rw-r--r--editor/plugins/tile_map_editor_plugin.h6
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp135
-rw-r--r--editor/plugins/tile_set_editor_plugin.h7
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp597
-rw-r--r--editor/plugins/version_control_editor_plugin.h146
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp725
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h46
-rw-r--r--editor/project_export.cpp14
-rw-r--r--editor/project_manager.cpp1557
-rw-r--r--editor/project_manager.h16
-rw-r--r--editor/project_settings_editor.cpp97
-rw-r--r--editor/project_settings_editor.h4
-rw-r--r--editor/property_editor.cpp10
-rw-r--r--editor/property_editor.h4
-rw-r--r--editor/property_selector.cpp2
-rw-r--r--editor/pvrtc_compress.cpp53
-rw-r--r--editor/quick_open.cpp10
-rw-r--r--editor/scene_tree_dock.cpp250
-rw-r--r--editor/scene_tree_dock.h2
-rw-r--r--editor/scene_tree_editor.cpp104
-rw-r--r--editor/scene_tree_editor.h4
-rw-r--r--editor/script_create_dialog.cpp143
-rw-r--r--editor/script_create_dialog.h20
-rw-r--r--editor/script_editor_debugger.cpp228
-rw-r--r--editor/script_editor_debugger.h12
-rw-r--r--editor/settings_config_dialog.cpp6
-rw-r--r--editor/spatial_editor_gizmos.cpp153
-rw-r--r--editor/spatial_editor_gizmos.h12
-rw-r--r--editor/translations/af.po822
-rw-r--r--editor/translations/ar.po941
-rw-r--r--editor/translations/bg.po872
-rw-r--r--editor/translations/bn.po1002
-rw-r--r--editor/translations/ca.po1122
-rw-r--r--editor/translations/cs.po1034
-rw-r--r--editor/translations/da.po901
-rw-r--r--editor/translations/de.po1216
-rw-r--r--editor/translations/de_CH.po829
-rw-r--r--editor/translations/editor.pot720
-rw-r--r--editor/translations/el.po1716
-rw-r--r--editor/translations/eo.po850
-rw-r--r--editor/translations/es.po1186
-rw-r--r--editor/translations/es_AR.po1642
-rw-r--r--editor/translations/et.po879
-rw-r--r--editor/translations/eu.po11325
-rw-r--r--editor/translations/fa.po889
-rw-r--r--editor/translations/fi.po1517
-rw-r--r--editor/translations/fil.po775
-rw-r--r--editor/translations/fr.po1670
-rw-r--r--editor/translations/ga.po11327
-rw-r--r--editor/translations/he.po912
-rw-r--r--editor/translations/hi.po782
-rw-r--r--editor/translations/hr.po724
-rw-r--r--editor/translations/hu.po966
-rw-r--r--editor/translations/id.po3114
-rw-r--r--editor/translations/is.po747
-rw-r--r--editor/translations/it.po1783
-rw-r--r--editor/translations/ja.po2605
-rw-r--r--editor/translations/ka.po812
-rw-r--r--editor/translations/ko.po1393
-rw-r--r--editor/translations/lt.po797
-rw-r--r--editor/translations/lv.po807
-rw-r--r--editor/translations/mi.po720
-rw-r--r--editor/translations/ml.po720
-rw-r--r--editor/translations/ms.po735
-rw-r--r--editor/translations/nb.po943
-rw-r--r--editor/translations/nl.po1028
-rw-r--r--editor/translations/or.po11324
-rw-r--r--editor/translations/pl.po1232
-rw-r--r--editor/translations/pr.po820
-rw-r--r--editor/translations/pt_BR.po1419
-rw-r--r--editor/translations/pt_PT.po1145
-rw-r--r--editor/translations/ro.po903
-rw-r--r--editor/translations/ru.po1297
-rw-r--r--editor/translations/si.po736
-rw-r--r--editor/translations/sk.po819
-rw-r--r--editor/translations/sl.po916
-rw-r--r--editor/translations/sq.po860
-rw-r--r--editor/translations/sr_Cyrl.po949
-rw-r--r--editor/translations/sr_Latn.po826
-rw-r--r--editor/translations/sv.po899
-rw-r--r--editor/translations/ta.po736
-rw-r--r--editor/translations/te.po720
-rw-r--r--editor/translations/th.po987
-rw-r--r--editor/translations/tr.po1047
-rw-r--r--editor/translations/uk.po1110
-rw-r--r--editor/translations/ur_PK.po784
-rw-r--r--editor/translations/vi.po1029
-rw-r--r--editor/translations/zh_CN.po1385
-rw-r--r--editor/translations/zh_HK.po889
-rw-r--r--editor/translations/zh_TW.po1137
-rw-r--r--main/SCsub5
-rw-r--r--main/gamecontrollerdb.txt51
-rw-r--r--main/input_default.cpp11
-rw-r--r--main/input_default.h1
-rw-r--r--main/main.cpp84
-rw-r--r--main/main.h4
-rw-r--r--main/main_timer_sync.cpp4
-rw-r--r--main/main_timer_sync.h1
-rw-r--r--main/tests/test_gdscript.cpp14
-rw-r--r--main/tests/test_gui.h3
-rw-r--r--main/tests/test_math.cpp6
-rw-r--r--main/tests/test_oa_hash_map.cpp19
-rw-r--r--main/tests/test_physics.h4
-rw-r--r--main/tests/test_render.h4
-rw-r--r--main/tests/test_shader_lang.cpp7
-rw-r--r--main/tests/test_string.cpp44
-rw-r--r--methods.py36
-rw-r--r--misc/dist/html/full-size.html6
-rwxr-xr-xmisc/hooks/pre-commit-clang-format3
-rw-r--r--misc/ide/jetbrains/AndroidManifest.xml44
-rw-r--r--misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.jarbin54329 -> 0 bytes
-rw-r--r--misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xmisc/ide/jetbrains/gradlew172
-rw-r--r--misc/ide/jetbrains/gradlew.bat84
-rwxr-xr-xmisc/travis/clang-format.sh2
-rw-r--r--modules/SCsub6
-rw-r--r--modules/arkit/arkit_interface.h6
-rw-r--r--modules/arkit/arkit_interface.mm18
-rw-r--r--modules/arkit/arkit_session_delegate.h6
-rw-r--r--modules/arkit/arkit_session_delegate.mm6
-rw-r--r--modules/assimp/SCsub18
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp1677
-rw-r--r--modules/assimp/editor_scene_importer_assimp.h151
-rwxr-xr-x[-rw-r--r--]modules/assimp/godot_update_assimp.sh3
-rw-r--r--modules/assimp/import_state.h115
-rw-r--r--modules/assimp/import_utils.h448
-rw-r--r--modules/bmp/image_loader_bmp.cpp248
-rw-r--r--modules/bmp/image_loader_bmp.h8
-rw-r--r--modules/bullet/bullet_physics_server.cpp3
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp6
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp9
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp6
-rw-r--r--modules/bullet/pin_joint_bullet.cpp3
-rw-r--r--modules/bullet/rigid_body_bullet.h2
-rw-r--r--modules/bullet/shape_bullet.cpp3
-rw-r--r--modules/bullet/space_bullet.cpp10
-rw-r--r--modules/bullet/space_bullet.h2
-rw-r--r--modules/csg/csg.cpp12
-rw-r--r--modules/csg/csg_gizmos.cpp2
-rw-r--r--modules/csg/doc_classes/CSGBox.xml2
-rw-r--r--modules/csg/doc_classes/CSGCylinder.xml2
-rw-r--r--modules/csg/doc_classes/CSGMesh.xml4
-rw-r--r--modules/csg/doc_classes/CSGPolygon.xml2
-rw-r--r--modules/csg/doc_classes/CSGSphere.xml2
-rw-r--r--modules/csg/doc_classes/CSGTorus.xml2
-rw-r--r--modules/cvtt/SCsub19
-rw-r--r--modules/dds/texture_loader_dds.cpp10
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp11
-rw-r--r--modules/etc/SCsub4
-rw-r--r--modules/etc/texture_loader_pkm.cpp7
-rw-r--r--modules/gdnative/arvr/arvr_interface_gdnative.cpp3
-rw-r--r--modules/gdnative/doc_classes/GDNative.xml2
-rw-r--r--modules/gdnative/doc_classes/NativeScript.xml4
-rw-r--r--modules/gdnative/doc_classes/PluginScript.xml2
-rw-r--r--modules/gdnative/gdnative.cpp3
-rw-r--r--modules/gdnative/gdnative/array.cpp9
-rw-r--r--modules/gdnative/gdnative/string.cpp14
-rw-r--r--modules/gdnative/gdnative/vector2.cpp8
-rw-r--r--modules/gdnative/gdnative/vector3.cpp8
-rw-r--r--modules/gdnative/gdnative_api.json59
-rw-r--r--modules/gdnative/gdnative_builders.py2
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp45
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.h2
-rw-r--r--modules/gdnative/include/gdnative/array.h2
-rw-r--r--modules/gdnative/include/gdnative/string.h2
-rw-r--r--modules/gdnative/include/gdnative/vector2.h2
-rw-r--r--modules/gdnative/include/gdnative/vector3.h2
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h10
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp74
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp47
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp27
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp2
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp2
-rw-r--r--modules/gdscript/SCsub10
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml107
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml2
-rw-r--r--modules/gdscript/gdscript.cpp37
-rw-r--r--modules/gdscript/gdscript_compiler.cpp16
-rw-r--r--modules/gdscript/gdscript_editor.cpp40
-rw-r--r--modules/gdscript/gdscript_function.cpp76
-rw-r--r--modules/gdscript/gdscript_functions.cpp71
-rw-r--r--modules/gdscript/gdscript_functions.h3
-rw-r--r--modules/gdscript/gdscript_parser.cpp744
-rw-r--r--modules/gdscript/gdscript_parser.h9
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp45
-rw-r--r--modules/gdscript/gdscript_tokenizer.h6
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp759
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.h103
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp213
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h93
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp88
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.h60
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp391
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.h73
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp504
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.h91
-rw-r--r--modules/gdscript/language_server/lsp.hpp1506
-rw-r--r--modules/gdscript/register_types.cpp22
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml2
-rw-r--r--modules/gridmap/grid_map.cpp11
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp32
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h10
-rw-r--r--modules/hdr/image_loader_hdr.cpp14
-rw-r--r--modules/hdr/image_loader_hdr.h3
-rw-r--r--modules/jpg/image_loader_jpegd.h3
-rw-r--r--modules/jsonrpc/SCsub7
-rw-r--r--modules/jsonrpc/config.py5
-rw-r--r--modules/jsonrpc/jsonrpc.cpp171
-rw-r--r--modules/jsonrpc/jsonrpc.h70
-rw-r--r--modules/jsonrpc/register_types.cpp40
-rw-r--r--modules/jsonrpc/register_types.h32
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp285
-rw-r--r--modules/mbedtls/crypto_mbedtls.h124
-rwxr-xr-xmodules/mbedtls/register_types.cpp6
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.cpp151
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.h73
-rwxr-xr-xmodules/mbedtls/stream_peer_mbedtls.cpp (renamed from modules/mbedtls/stream_peer_mbed_tls.cpp)101
-rwxr-xr-xmodules/mbedtls/stream_peer_mbedtls.h (renamed from modules/mbedtls/stream_peer_mbed_tls.h)24
-rw-r--r--modules/mono/.gitignore2
-rw-r--r--modules/mono/SCsub16
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py10
-rw-r--r--modules/mono/build_scripts/make_android_mono_config.py19
-rw-r--r--modules/mono/build_scripts/mono_configure.py8
-rw-r--r--modules/mono/build_scripts/mono_reg_utils.py2
-rw-r--r--modules/mono/class_db_api_json.cpp8
-rw-r--r--modules/mono/class_db_api_json.h11
-rw-r--r--modules/mono/csharp_script.cpp137
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs94
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs219
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs207
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs45
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj53
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs13
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs21
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs46
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs88
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs35
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs107
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.sln6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs)43
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs18
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs52
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs)8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs259
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildTab.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs)85
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs (renamed from modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs)18
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs11
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs396
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs231
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj26
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs166
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs212
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs (renamed from modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs)63
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs47
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs13
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs64
-rw-r--r--modules/mono/editor/bindings_generator.cpp126
-rw-r--r--modules/mono/editor/bindings_generator.h2
-rw-r--r--modules/mono/editor/csharp_project.cpp10
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp64
-rw-r--r--modules/mono/editor/godotsharp_export.cpp13
-rw-r--r--modules/mono/editor/script_class_parser.cpp18
-rw-r--r--modules/mono/glue/Managed/Files/AABB.cs3
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs81
-rw-r--r--modules/mono/glue/Managed/Files/Color.cs86
-rw-r--r--modules/mono/glue/Managed/Files/Colors.cs4
-rw-r--r--modules/mono/glue/Managed/Files/Dispatcher.cs13
-rw-r--r--modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs7
-rw-r--r--modules/mono/glue/Managed/Files/GodotTaskScheduler.cs9
-rw-r--r--modules/mono/glue/Managed/Files/Mathf.cs19
-rw-r--r--modules/mono/glue/Managed/Files/MathfEx.cs7
-rw-r--r--modules/mono/glue/Managed/Files/NodePath.cs2
-rw-r--r--modules/mono/glue/Managed/Files/Plane.cs3
-rw-r--r--modules/mono/glue/Managed/Files/Quat.cs13
-rw-r--r--modules/mono/glue/Managed/Files/Rect2.cs9
-rw-r--r--modules/mono/glue/Managed/Files/StringExtensions.cs60
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs3
-rw-r--r--modules/mono/glue/Managed/Files/Transform2D.cs8
-rw-r--r--modules/mono/glue/Managed/Files/Vector2.cs52
-rw-r--r--modules/mono/glue/Managed/Files/Vector3.cs49
-rw-r--r--modules/mono/glue/Managed/Managed.csproj5
-rw-r--r--modules/mono/glue/gd_glue.cpp12
-rw-r--r--modules/mono/glue/gd_glue.h2
-rw-r--r--modules/mono/godotsharp_defs.h4
-rw-r--r--modules/mono/icons/icon_c_#.svg5
-rw-r--r--modules/mono/mono_gd/android_mono_config.h43
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp607
-rw-r--r--modules/mono/mono_gd/gd_mono.h28
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp10
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp8
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp17
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp9
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp21
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp37
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h2
-rw-r--r--modules/mono/signal_awaiter_utils.cpp6
-rw-r--r--modules/mono/utils/string_utils.cpp15
-rw-r--r--modules/opensimplex/doc_classes/NoiseTexture.xml2
-rw-r--r--modules/opus/audio_stream_opus.cpp3
-rw-r--r--modules/pvr/texture_loader_pvr.cpp3
-rw-r--r--modules/recast/navigation_mesh_generator.cpp19
-rw-r--r--modules/regex/SCsub1
-rw-r--r--modules/regex/doc_classes/RegExMatch.xml4
-rw-r--r--modules/squish/image_compress_squish.cpp3
-rw-r--r--modules/svg/image_loader_svg.cpp6
-rw-r--r--modules/theora/video_stream_theora.cpp1
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h3
-rw-r--r--modules/tinyexr/image_saver_tinyexr.cpp279
-rw-r--r--modules/tinyexr/image_saver_tinyexr.h38
-rw-r--r--modules/tinyexr/register_types.cpp5
-rw-r--r--modules/vhacd/SCsub4
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptPreload.xml2
-rw-r--r--modules/visual_script/visual_script.cpp52
-rw-r--r--modules/visual_script/visual_script.h3
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp187
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h3
-rw-r--r--modules/visual_script/visual_script_editor.cpp20
-rw-r--r--modules/visual_script/visual_script_editor.h1
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp32
-rw-r--r--modules/visual_script/visual_script_nodes.cpp5
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp16
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp3
-rw-r--r--modules/webm/SCsub4
-rw-r--r--modules/webm/video_stream_webm.cpp3
-rw-r--r--modules/webp/image_loader_webp.cpp10
-rw-r--r--modules/webp/image_loader_webp.h3
-rw-r--r--modules/webrtc/register_types.cpp7
-rw-r--r--modules/webrtc/webrtc_data_channel.cpp2
-rw-r--r--modules/webrtc/webrtc_data_channel.h4
-rw-r--r--modules/webrtc/webrtc_data_channel_js.cpp8
-rw-r--r--modules/webrtc/webrtc_multiplayer.cpp6
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.cpp6
-rw-r--r--modules/websocket/emws_peer.cpp6
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp30
-rw-r--r--modules/websocket/wsl_client.cpp71
-rw-r--r--modules/websocket/wsl_peer.cpp4
-rw-r--r--modules/websocket/wsl_server.cpp55
-rw-r--r--modules/xatlas_unwrap/SCsub4
-rw-r--r--modules/xatlas_unwrap/register_types.cpp103
-rw-r--r--platform/SCsub11
-rw-r--r--platform/android/SCsub19
-rw-r--r--platform/android/audio_driver_opensl.cpp17
-rw-r--r--platform/android/detect.py70
-rw-r--r--platform/android/export/export.cpp259
-rw-r--r--platform/android/java/AndroidManifest.xml58
-rw-r--r--platform/android/java/README.md47
-rw-r--r--platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl144
-rw-r--r--platform/android/java/app/AndroidManifest.xml65
-rw-r--r--platform/android/java/app/build.gradle121
-rw-r--r--platform/android/java/app/config.gradle12
-rw-r--r--platform/android/java/app/src/com/godot/game/GodotApp.java10
-rw-r--r--platform/android/java/build.gradle176
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties3
-rw-r--r--platform/android/java/lib/AndroidManifest.xml19
-rw-r--r--platform/android/java/lib/CMakeLists.txt (renamed from misc/ide/jetbrains/CMakeLists.txt)2
-rw-r--r--platform/android/java/lib/THIRDPARTY.md39
-rw-r--r--platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl281
-rw-r--r--platform/android/java/lib/aidl/com/android/vending/licensing/ILicenseResultListener.aidl (renamed from platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.aidl)2
-rw-r--r--platform/android/java/lib/aidl/com/android/vending/licensing/ILicensingService.aidl (renamed from platform/android/java/src/com/google/android/vending/licensing/ILicensingService.aidl)2
-rw-r--r--platform/android/java/lib/build.gradle (renamed from misc/ide/jetbrains/build.gradle)51
-rw-r--r--platform/android/java/lib/patches/com.google.android.vending.expansion.downloader.patch300
-rw-r--r--platform/android/java/lib/patches/com.google.android.vending.licensing.patch42
-rw-r--r--platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png (renamed from platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png)bin1843 -> 1843 bytes
-rw-r--r--platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png (renamed from platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png)bin718 -> 718 bytes
-rw-r--r--platform/android/java/lib/res/drawable-nodpi/icon.png (renamed from platform/android/java/res/drawable-nodpi/icon.png)bin7569 -> 7569 bytes
-rw-r--r--platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png (renamed from platform/android/java/res/drawable-xhdpi/notify_panel_notification_icon_bg.png)bin462 -> 462 bytes
-rw-r--r--platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png (renamed from platform/android/java/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png)bin2830 -> 2830 bytes
-rw-r--r--platform/android/java/lib/res/layout/downloading_expansion.xml (renamed from platform/android/java/res/layout/downloading_expansion.xml)0
-rw-r--r--platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml (renamed from platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml)0
-rw-r--r--platform/android/java/lib/res/values-ar/strings.xml (renamed from platform/android/java/res/values-ar/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-bg/strings.xml (renamed from platform/android/java/res/values-bg/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-ca/strings.xml (renamed from platform/android/java/res/values-ca/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-cs/strings.xml (renamed from platform/android/java/res/values-cs/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-da/strings.xml (renamed from platform/android/java/res/values-da/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-de/strings.xml (renamed from platform/android/java/res/values-de/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-el/strings.xml (renamed from platform/android/java/res/values-el/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-en/strings.xml (renamed from platform/android/java/res/values-en/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-es-rES/strings.xml (renamed from platform/android/java/res/values-es-rES/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-es/strings.xml (renamed from platform/android/java/res/values-es/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-fa/strings.xml (renamed from platform/android/java/res/values-fa/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-fi/strings.xml (renamed from platform/android/java/res/values-fi/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-fr/strings.xml (renamed from platform/android/java/res/values-fr/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-hi/strings.xml (renamed from platform/android/java/res/values-hi/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-hr/strings.xml (renamed from platform/android/java/res/values-hr/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-hu/strings.xml (renamed from platform/android/java/res/values-hu/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-in/strings.xml (renamed from platform/android/java/res/values-in/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-it/strings.xml (renamed from platform/android/java/res/values-it/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-iw/strings.xml (renamed from platform/android/java/res/values-iw/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-ja/strings.xml (renamed from platform/android/java/res/values-ja/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-ko/strings.xml (renamed from platform/android/java/res/values-ko/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-lt/strings.xml (renamed from platform/android/java/res/values-lt/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-lv/strings.xml (renamed from platform/android/java/res/values-lv/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-nb/strings.xml (renamed from platform/android/java/res/values-nb/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-nl/strings.xml (renamed from platform/android/java/res/values-nl/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-pl/strings.xml (renamed from platform/android/java/res/values-pl/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-pt/strings.xml (renamed from platform/android/java/res/values-pt/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-ro/strings.xml (renamed from platform/android/java/res/values-ro/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-ru/strings.xml (renamed from platform/android/java/res/values-ru/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-sk/strings.xml (renamed from platform/android/java/res/values-sk/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-sl/strings.xml (renamed from platform/android/java/res/values-sl/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-sr/strings.xml (renamed from platform/android/java/res/values-sr/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-sv/strings.xml (renamed from platform/android/java/res/values-sv/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-th/strings.xml (renamed from platform/android/java/res/values-th/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-tl/strings.xml (renamed from platform/android/java/res/values-tl/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-tr/strings.xml (renamed from platform/android/java/res/values-tr/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-uk/strings.xml (renamed from platform/android/java/res/values-uk/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-vi/strings.xml (renamed from platform/android/java/res/values-vi/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-zh-rCN/strings.xml (renamed from platform/android/java/res/values-zh-rCN/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-zh-rHK/strings.xml (renamed from platform/android/java/res/values-zh-rHK/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values-zh-rTW/strings.xml (renamed from platform/android/java/res/values-zh-rTW/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values/strings.xml (renamed from platform/android/java/res/values/strings.xml)0
-rw-r--r--platform/android/java/lib/res/values/styles.xml (renamed from platform/android/java/res/values/styles.xml)0
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Constants.java (renamed from platform/android/java/src/com/google/android/vending/expansion/downloader/Constants.java)165
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java80
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java297
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java201
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java367
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java (renamed from platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java)56
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderService.java (renamed from platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderService.java)28
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IStub.java (renamed from platform/android/java/src/com/google/android/vending/expansion/downloader/IStub.java)6
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/SystemFacade.java129
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java112
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java92
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java229
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java852
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java1346
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java510
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java200
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/AESObfuscator.java110
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/APKExpansionPolicy.java414
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/DeviceLimiter.java (renamed from platform/android/java/src/com/google/android/vending/licensing/DeviceLimiter.java)4
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/LicenseChecker.java389
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/LicenseCheckerCallback.java (renamed from platform/android/java/src/com/google/android/vending/licensing/LicenseCheckerCallback.java)26
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/LicenseValidator.java231
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/NullDeviceLimiter.java (renamed from platform/android/java/src/com/google/android/vending/licensing/NullDeviceLimiter.java)6
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java (renamed from platform/android/java/src/com/google/android/vending/licensing/Obfuscator.java)8
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/Policy.java (renamed from platform/android/java/src/com/google/android/vending/licensing/Policy.java)26
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/PreferenceObfuscator.java80
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/ResponseData.java81
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/ServerManagedPolicy.java300
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/StrictPolicy.java (renamed from platform/android/java/src/com/google/android/vending/licensing/StrictPolicy.java)75
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/ValidationException.java (renamed from platform/android/java/src/com/google/android/vending/licensing/ValidationException.java)14
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64.java578
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64DecoderException.java (renamed from platform/android/java/src/com/google/android/vending/licensing/util/Base64DecoderException.java)14
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/licensing/util/URIQueryDecoder.java (renamed from platform/android/java/src/com/google/android/vending/licensing/util/URIQueryDecoder.java)50
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Dictionary.java (renamed from platform/android/java/src/org/godotengine/godot/Dictionary.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java (renamed from platform/android/java/src/org/godotengine/godot/Godot.java)145
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java (renamed from platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java (renamed from platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java (renamed from platform/android/java/src/org/godotengine/godot/GodotIO.java)8
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java (renamed from platform/android/java/src/org/godotengine/godot/GodotInstrumentation.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java226
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java (renamed from platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java (renamed from platform/android/java/src/org/godotengine/godot/GodotRenderer.java)17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotView.java (renamed from platform/android/java/src/org/godotengine/godot/GodotView.java)32
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java (renamed from platform/android/java/src/org/godotengine/godot/input/GodotEditText.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java (renamed from platform/android/java/src/org/godotengine/godot/input/GodotInputHandler.java)6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java (renamed from platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java)1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java (renamed from platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java (renamed from platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java (renamed from platform/android/java/src/org/godotengine/godot/input/Joystick.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java (renamed from platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java)1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java (renamed from platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java)11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java (renamed from platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java (renamed from platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java)1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java (renamed from platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java)7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java (renamed from platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java (renamed from platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java)11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java (renamed from platform/android/java/src/org/godotengine/godot/utils/Crypt.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java (renamed from platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java (renamed from platform/android/java/src/org/godotengine/godot/utils/GLUtils.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java (renamed from platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java)4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java (renamed from platform/android/java/src/org/godotengine/godot/utils/RequestParams.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java (renamed from platform/android/java/src/org/godotengine/godot/xr/XRMode.java)8
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java (renamed from platform/android/java/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java (renamed from platform/android/java/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java (renamed from platform/android/java/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java (renamed from platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java (renamed from platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java)0
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java (renamed from platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java)0
-rw-r--r--platform/android/java/settings.gradle (renamed from misc/ide/jetbrains/settings.gradle)3
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java78
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java290
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java193
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java355
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java126
-rwxr-xr-xplatform/android/java/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java111
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java92
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java224
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java833
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java1320
-rwxr-xr-xplatform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java469
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java191
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/AESObfuscator.java110
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/APKExpansionPolicy.java413
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.java100
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/ILicensingService.java100
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/LicenseChecker.java387
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/LicenseValidator.java232
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java78
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/ResponseData.java80
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/ServerManagedPolicy.java299
-rw-r--r--platform/android/java/src/com/google/android/vending/licensing/util/Base64.java556
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java76
-rw-r--r--platform/android/java_godot_lib_jni.cpp33
-rw-r--r--platform/android/java_godot_lib_jni.h4
-rw-r--r--platform/android/java_godot_wrapper.cpp19
-rw-r--r--platform/android/java_godot_wrapper.h4
-rw-r--r--platform/android/os_android.cpp14
-rw-r--r--platform/android/os_android.h1
-rw-r--r--platform/android/thread_jandroid.h4
-rw-r--r--platform/iphone/app_delegate.mm5
-rw-r--r--platform/iphone/camera_ios.mm2
-rw-r--r--platform/iphone/export/export.cpp15
-rw-r--r--platform/iphone/os_iphone.cpp9
-rw-r--r--platform/iphone/os_iphone.h1
-rw-r--r--platform/iphone/view_controller.h4
-rw-r--r--platform/iphone/view_controller.mm12
-rw-r--r--platform/javascript/audio_driver_javascript.cpp6
-rw-r--r--platform/javascript/detect.py4
-rw-r--r--platform/javascript/export/export.cpp13
-rw-r--r--platform/javascript/http_client_javascript.cpp12
-rw-r--r--platform/javascript/os_javascript.cpp28
-rw-r--r--platform/osx/dir_access_osx.h3
-rw-r--r--platform/osx/export/export.cpp23
-rw-r--r--platform/osx/os_osx.h28
-rw-r--r--platform/osx/os_osx.mm115
-rw-r--r--platform/server/detect.py7
-rw-r--r--platform/server/os_server.cpp4
-rw-r--r--platform/server/os_server.h4
-rw-r--r--platform/uwp/export/export.cpp79
-rw-r--r--platform/uwp/os_uwp.cpp9
-rw-r--r--platform/uwp/os_uwp.h3
-rw-r--r--platform/windows/camera_win.cpp12
-rw-r--r--platform/windows/os_windows.cpp77
-rw-r--r--platform/windows/os_windows.h4
-rw-r--r--platform/x11/context_gl_x11.h3
-rw-r--r--platform/x11/detect.py7
-rw-r--r--platform/x11/export/export.cpp3
-rw-r--r--platform/x11/joypad_linux.cpp2
-rw-r--r--platform/x11/key_mapping_x11.h3
-rw-r--r--platform/x11/os_x11.cpp32
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--platform/x11/power_x11.cpp4
-rw-r--r--scene/2d/animated_sprite.cpp13
-rw-r--r--scene/2d/area_2d.cpp19
-rw-r--r--scene/2d/camera_2d.cpp19
-rw-r--r--scene/2d/camera_2d.h3
-rw-r--r--scene/2d/canvas_item.cpp103
-rw-r--r--scene/2d/collision_object_2d.cpp7
-rw-r--r--scene/2d/collision_shape_2d.cpp22
-rw-r--r--scene/2d/cpu_particles_2d.cpp27
-rw-r--r--scene/2d/cpu_particles_2d.h8
-rw-r--r--scene/2d/line_builder.cpp2
-rw-r--r--scene/2d/navigation_2d.cpp4
-rw-r--r--scene/2d/navigation_polygon.cpp2
-rw-r--r--scene/2d/parallax_layer.cpp3
-rw-r--r--scene/2d/path_2d.cpp2
-rw-r--r--scene/2d/physics_body_2d.cpp59
-rw-r--r--scene/2d/ray_cast_2d.cpp19
-rw-r--r--scene/2d/sprite.cpp23
-rw-r--r--scene/2d/sprite.h3
-rw-r--r--scene/2d/tile_map.cpp15
-rw-r--r--scene/3d/SCsub10
-rw-r--r--scene/3d/area.cpp19
-rw-r--r--scene/3d/arvr_nodes.cpp15
-rw-r--r--scene/3d/audio_stream_player_3d.cpp149
-rw-r--r--scene/3d/audio_stream_player_3d.h1
-rw-r--r--scene/3d/camera.cpp25
-rw-r--r--scene/3d/camera.h4
-rw-r--r--scene/3d/collision_object.cpp5
-rw-r--r--scene/3d/collision_polygon.cpp2
-rw-r--r--scene/3d/cpu_particles.cpp23
-rw-r--r--scene/3d/cpu_particles.h8
-rw-r--r--scene/3d/light.cpp5
-rw-r--r--scene/3d/light.h4
-rw-r--r--scene/3d/mesh_instance.cpp37
-rw-r--r--scene/3d/mesh_instance.h10
-rw-r--r--scene/3d/multimesh_instance.h4
-rw-r--r--scene/3d/particles.h4
-rw-r--r--scene/3d/physics_body.cpp68
-rw-r--r--scene/3d/physics_body.h2
-rw-r--r--scene/3d/portal.h3
-rw-r--r--scene/3d/ray_cast.cpp2
-rw-r--r--scene/3d/room_instance.h4
-rw-r--r--scene/3d/skeleton.cpp303
-rw-r--r--scene/3d/skeleton.h66
-rw-r--r--scene/3d/soft_body.cpp10
-rw-r--r--scene/3d/spatial.cpp11
-rw-r--r--scene/3d/spatial.h4
-rw-r--r--scene/3d/sprite_3d.cpp57
-rw-r--r--scene/3d/sprite_3d.h6
-rw-r--r--scene/3d/vehicle_body.cpp68
-rw-r--r--scene/3d/vehicle_body.h11
-rw-r--r--scene/3d/visual_instance.cpp13
-rw-r--r--scene/3d/visual_instance.h4
-rw-r--r--scene/3d/world_environment.h4
-rw-r--r--scene/animation/animation_blend_space_1d.cpp2
-rw-r--r--scene/animation/animation_blend_space_2d.cpp2
-rw-r--r--scene/animation/animation_cache.cpp21
-rw-r--r--scene/animation/animation_node_state_machine.cpp4
-rw-r--r--scene/animation/animation_player.cpp19
-rw-r--r--scene/animation/animation_player.h3
-rw-r--r--scene/animation/animation_tree.cpp3
-rw-r--r--scene/animation/animation_tree_player.cpp26
-rw-r--r--scene/animation/skeleton_ik.cpp2
-rw-r--r--scene/animation/tween.cpp50
-rw-r--r--scene/gui/base_button.cpp3
-rw-r--r--scene/gui/base_button.h3
-rw-r--r--scene/gui/button.cpp289
-rw-r--r--scene/gui/button.h9
-rw-r--r--scene/gui/check_box.cpp2
-rw-r--r--scene/gui/check_button.cpp2
-rw-r--r--scene/gui/color_picker.cpp34
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/control.cpp131
-rw-r--r--scene/gui/control.h4
-rw-r--r--scene/gui/dialogs.cpp44
-rw-r--r--scene/gui/dialogs.h3
-rw-r--r--scene/gui/file_dialog.cpp11
-rw-r--r--scene/gui/file_dialog.h4
-rw-r--r--scene/gui/gradient_edit.cpp10
-rw-r--r--scene/gui/graph_edit.cpp50
-rw-r--r--scene/gui/graph_node.cpp10
-rw-r--r--scene/gui/label.h4
-rw-r--r--scene/gui/line_edit.cpp254
-rw-r--r--scene/gui/line_edit.h19
-rw-r--r--scene/gui/menu_button.h4
-rw-r--r--scene/gui/nine_patch_rect.h4
-rw-r--r--scene/gui/option_button.cpp68
-rw-r--r--scene/gui/option_button.h4
-rw-r--r--scene/gui/panel.h4
-rw-r--r--scene/gui/popup.cpp3
-rw-r--r--scene/gui/popup.h3
-rw-r--r--scene/gui/popup_menu.cpp6
-rw-r--r--scene/gui/popup_menu.h4
-rw-r--r--scene/gui/progress_bar.cpp2
-rw-r--r--scene/gui/range.cpp4
-rw-r--r--scene/gui/range.h4
-rw-r--r--scene/gui/rich_text_effect.cpp122
-rw-r--r--scene/gui/rich_text_effect.h87
-rw-r--r--scene/gui/rich_text_label.cpp475
-rw-r--r--scene/gui/rich_text_label.h150
-rw-r--r--scene/gui/scroll_bar.h4
-rw-r--r--scene/gui/scroll_container.cpp21
-rw-r--r--scene/gui/separator.h4
-rw-r--r--scene/gui/spin_box.cpp27
-rw-r--r--scene/gui/tab_container.cpp16
-rw-r--r--scene/gui/tab_container.h3
-rw-r--r--scene/gui/text_edit.cpp1166
-rw-r--r--scene/gui/text_edit.h36
-rw-r--r--scene/gui/texture_button.cpp16
-rw-r--r--scene/gui/texture_rect.h4
-rw-r--r--scene/gui/tree.cpp66
-rw-r--r--scene/gui/tree.h10
-rw-r--r--scene/gui/viewport_container.cpp1
-rw-r--r--scene/main/http_request.cpp13
-rw-r--r--scene/main/instance_placeholder.cpp2
-rw-r--r--scene/main/node.cpp133
-rw-r--r--scene/main/node.h11
-rw-r--r--scene/main/scene_tree.cpp96
-rw-r--r--scene/main/scene_tree.h6
-rwxr-xr-xscene/main/timer.cpp6
-rw-r--r--scene/main/viewport.cpp29
-rw-r--r--scene/main/viewport.h3
-rw-r--r--scene/register_scene_types.cpp18
-rw-r--r--scene/register_scene_types.h4
-rw-r--r--scene/resources/animation.cpp25
-rw-r--r--scene/resources/animation.h4
-rw-r--r--scene/resources/audio_stream_sample.cpp3
-rw-r--r--scene/resources/curve.cpp40
-rw-r--r--scene/resources/default_theme/default_theme.cpp12
-rw-r--r--scene/resources/default_theme/default_theme.h3
-rwxr-xr-xscene/resources/default_theme/make_header.py5
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/default_theme/toggle_off_disabled.pngbin1676 -> 932 bytes
-rw-r--r--scene/resources/default_theme/toggle_on_disabled.pngbin1698 -> 1039 bytes
-rw-r--r--scene/resources/dynamic_font.cpp23
-rw-r--r--scene/resources/environment.cpp10
-rw-r--r--scene/resources/font.cpp11
-rw-r--r--scene/resources/font.h3
-rw-r--r--scene/resources/material.cpp26
-rw-r--r--scene/resources/material.h9
-rw-r--r--scene/resources/mesh.cpp23
-rw-r--r--scene/resources/mesh.h3
-rw-r--r--scene/resources/mesh_data_tool.cpp3
-rw-r--r--scene/resources/packed_scene.cpp13
-rw-r--r--scene/resources/particles_material.cpp30
-rw-r--r--scene/resources/particles_material.h7
-rw-r--r--scene/resources/primitive_meshes.cpp16
-rw-r--r--scene/resources/primitive_meshes.h15
-rw-r--r--scene/resources/resource_format_text.cpp8
-rw-r--r--scene/resources/room.h3
-rw-r--r--scene/resources/skin.cpp102
-rw-r--r--scene/resources/skin.h54
-rw-r--r--scene/resources/style_box.cpp11
-rw-r--r--scene/resources/style_box.h4
-rw-r--r--scene/resources/text_file.cpp5
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--scene/resources/texture.h4
-rw-r--r--scene/resources/theme.cpp30
-rw-r--r--scene/resources/theme.h9
-rw-r--r--scene/resources/tile_set.cpp18
-rw-r--r--scene/resources/visual_shader.cpp282
-rw-r--r--scene/resources/visual_shader.h63
-rw-r--r--scene/resources/visual_shader_nodes.cpp632
-rw-r--r--scene/resources/visual_shader_nodes.h163
-rw-r--r--servers/arvr/arvr_interface.h2
-rw-r--r--servers/audio/audio_stream.cpp42
-rw-r--r--servers/audio/audio_stream.h2
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp8
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp2
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp2
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp2
-rw-r--r--servers/audio/effects/audio_effect_record.cpp2
-rw-r--r--servers/audio/voice_rb_sw.h3
-rw-r--r--servers/audio_server.cpp64
-rw-r--r--servers/audio_server.h23
-rw-r--r--servers/camera_server.h2
-rw-r--r--servers/physics/body_sw.cpp1
-rw-r--r--servers/physics/collision_object_sw.h6
-rw-r--r--servers/physics/collision_solver_sw.cpp4
-rw-r--r--servers/physics/gjk_epa.h5
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp1
-rw-r--r--servers/physics/physics_server_sw.cpp26
-rw-r--r--servers/physics/shape_sw.cpp10
-rw-r--r--servers/physics/space_sw.cpp6
-rw-r--r--servers/physics_2d/body_2d_sw.cpp56
-rw-r--r--servers/physics_2d/body_2d_sw.h1
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp2
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp23
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp28
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h6
-rw-r--r--servers/physics_2d/space_2d_sw.cpp6
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/shader_language.cpp2207
-rw-r--r--servers/visual/shader_language.h82
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--servers/visual/visual_server_canvas.cpp10
-rw-r--r--servers/visual/visual_server_raster.h4
-rw-r--r--servers/visual/visual_server_viewport.cpp19
-rw-r--r--servers/visual/visual_server_wrap_mt.h4
-rw-r--r--servers/visual_server.cpp15
-rw-r--r--servers/visual_server.h4
-rw-r--r--thirdparty/README.md50
-rw-r--r--thirdparty/assimp/assimp/config.h23
-rw-r--r--thirdparty/assimp/code/CApi/AssimpCExport.cpp156
-rw-r--r--thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp (renamed from thirdparty/assimp/code/CInterfaceIOWrapper.cpp)0
-rw-r--r--thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h (renamed from thirdparty/assimp/code/CInterfaceIOWrapper.h)0
-rw-r--r--thirdparty/assimp/code/Common/Assimp.cpp695
-rw-r--r--thirdparty/assimp/code/Common/BaseImporter.cpp (renamed from thirdparty/assimp/code/BaseImporter.cpp)33
-rw-r--r--thirdparty/assimp/code/Common/BaseProcess.cpp (renamed from thirdparty/assimp/code/BaseProcess.cpp)2
-rw-r--r--thirdparty/assimp/code/Common/BaseProcess.h (renamed from thirdparty/assimp/code/BaseProcess.h)0
-rw-r--r--thirdparty/assimp/code/Common/Bitmap.cpp (renamed from thirdparty/assimp/code/Bitmap.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/CreateAnimMesh.cpp (renamed from thirdparty/assimp/code/CreateAnimMesh.cpp)4
-rw-r--r--thirdparty/assimp/code/Common/DefaultIOStream.cpp (renamed from thirdparty/assimp/code/DefaultIOStream.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultIOSystem.cpp (renamed from thirdparty/assimp/code/DefaultIOSystem.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultLogger.cpp (renamed from thirdparty/assimp/code/DefaultLogger.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultProgressHandler.h (renamed from thirdparty/assimp/code/DefaultProgressHandler.h)0
-rw-r--r--thirdparty/assimp/code/Common/Exporter.cpp (renamed from thirdparty/assimp/code/Exporter.cpp)32
-rw-r--r--thirdparty/assimp/code/Common/FileLogStream.h (renamed from thirdparty/assimp/code/FileLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/FileSystemFilter.h (renamed from thirdparty/assimp/code/FileSystemFilter.h)0
-rw-r--r--thirdparty/assimp/code/Common/IFF.h102
-rw-r--r--thirdparty/assimp/code/Common/Importer.cpp (renamed from thirdparty/assimp/code/Importer.cpp)19
-rw-r--r--thirdparty/assimp/code/Common/Importer.h (renamed from thirdparty/assimp/code/Importer.h)0
-rw-r--r--thirdparty/assimp/code/Common/ImporterRegistry.cpp (renamed from thirdparty/assimp/code/ImporterRegistry.cpp)96
-rw-r--r--thirdparty/assimp/code/Common/PolyTools.h (renamed from thirdparty/assimp/code/PolyTools.h)0
-rw-r--r--thirdparty/assimp/code/Common/PostStepRegistry.cpp (renamed from thirdparty/assimp/code/PostStepRegistry.cpp)63
-rw-r--r--thirdparty/assimp/code/Common/RemoveComments.cpp (renamed from thirdparty/assimp/code/RemoveComments.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SGSpatialSort.cpp (renamed from thirdparty/assimp/code/SGSpatialSort.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SceneCombiner.cpp (renamed from thirdparty/assimp/code/SceneCombiner.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePreprocessor.cpp (renamed from thirdparty/assimp/code/ScenePreprocessor.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePreprocessor.h (renamed from thirdparty/assimp/code/ScenePreprocessor.h)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePrivate.h (renamed from thirdparty/assimp/code/ScenePrivate.h)0
-rw-r--r--thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp (renamed from thirdparty/assimp/code/SkeletonMeshBuilder.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SpatialSort.cpp (renamed from thirdparty/assimp/code/SpatialSort.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp (renamed from thirdparty/assimp/code/SplitByBoneCountProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SplitByBoneCountProcess.h (renamed from thirdparty/assimp/code/SplitByBoneCountProcess.h)0
-rw-r--r--thirdparty/assimp/code/Common/StandardShapes.cpp (renamed from thirdparty/assimp/code/StandardShapes.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/StdOStreamLogStream.h (renamed from thirdparty/assimp/code/StdOStreamLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/Subdivision.cpp (renamed from thirdparty/assimp/code/Subdivision.cpp)7
-rw-r--r--thirdparty/assimp/code/Common/TargetAnimation.cpp (renamed from thirdparty/assimp/code/TargetAnimation.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/TargetAnimation.h (renamed from thirdparty/assimp/code/TargetAnimation.h)0
-rw-r--r--thirdparty/assimp/code/Common/Version.cpp (renamed from thirdparty/assimp/code/Version.cpp)2
-rw-r--r--thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp (renamed from thirdparty/assimp/code/VertexTriangleAdjacency.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/VertexTriangleAdjacency.h (renamed from thirdparty/assimp/code/VertexTriangleAdjacency.h)0
-rw-r--r--thirdparty/assimp/code/Common/Win32DebugLogStream.h (renamed from thirdparty/assimp/code/Win32DebugLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/assbin_chunks.h196
-rw-r--r--thirdparty/assimp/code/Common/scene.cpp (renamed from thirdparty/assimp/code/scene.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/simd.cpp (renamed from thirdparty/assimp/code/simd.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/simd.h (renamed from thirdparty/assimp/code/simd.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXAnimation.cpp (renamed from thirdparty/assimp/code/FBXAnimation.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp (renamed from thirdparty/assimp/code/FBXBinaryTokenizer.cpp)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXCommon.h (renamed from thirdparty/assimp/code/FBXCommon.h)4
-rw-r--r--thirdparty/assimp/code/FBX/FBXCompileConfig.h (renamed from thirdparty/assimp/code/FBXCompileConfig.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.cpp (renamed from thirdparty/assimp/code/FBXConverter.cpp)290
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.h (renamed from thirdparty/assimp/code/FBXConverter.h)30
-rw-r--r--thirdparty/assimp/code/FBX/FBXDeformer.cpp (renamed from thirdparty/assimp/code/FBXDeformer.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.cpp (renamed from thirdparty/assimp/code/FBXDocument.cpp)8
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.h (renamed from thirdparty/assimp/code/FBXDocument.h)4
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp (renamed from thirdparty/assimp/code/FBXDocumentUtil.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocumentUtil.h (renamed from thirdparty/assimp/code/FBXDocumentUtil.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportNode.cpp (renamed from thirdparty/assimp/code/FBXExportNode.cpp)11
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportNode.h (renamed from thirdparty/assimp/code/FBXExportNode.h)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportProperty.cpp (renamed from thirdparty/assimp/code/FBXExportProperty.cpp)257
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportProperty.h (renamed from thirdparty/assimp/code/FBXExportProperty.h)48
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.cpp (renamed from thirdparty/assimp/code/FBXExporter.cpp)150
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.h (renamed from thirdparty/assimp/code/FBXExporter.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXImportSettings.h (renamed from thirdparty/assimp/code/FBXImportSettings.h)39
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.cpp (renamed from thirdparty/assimp/code/FBXImporter.cpp)18
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.h (renamed from thirdparty/assimp/code/FBXImporter.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXMaterial.cpp (renamed from thirdparty/assimp/code/FBXMaterial.cpp)44
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp (renamed from thirdparty/assimp/code/FBXMeshGeometry.cpp)18
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.h (renamed from thirdparty/assimp/code/FBXMeshGeometry.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXModel.cpp (renamed from thirdparty/assimp/code/FBXModel.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp (renamed from thirdparty/assimp/code/FBXNodeAttribute.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXParser.cpp (renamed from thirdparty/assimp/code/FBXParser.cpp)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXParser.h (renamed from thirdparty/assimp/code/FBXParser.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXProperties.cpp (renamed from thirdparty/assimp/code/FBXProperties.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXProperties.h (renamed from thirdparty/assimp/code/FBXProperties.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXTokenizer.cpp (renamed from thirdparty/assimp/code/FBXTokenizer.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXTokenizer.h (renamed from thirdparty/assimp/code/FBXTokenizer.h)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXUtil.cpp (renamed from thirdparty/assimp/code/FBXUtil.cpp)135
-rw-r--r--thirdparty/assimp/code/FBX/FBXUtil.h (renamed from thirdparty/assimp/code/FBXUtil.h)23
-rw-r--r--thirdparty/assimp/code/FIReader.cpp1834
-rw-r--r--thirdparty/assimp/code/MMD/MMDCpp14.h (renamed from thirdparty/assimp/code/MMDCpp14.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.cpp (renamed from thirdparty/assimp/code/MMDImporter.cpp)12
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.h (renamed from thirdparty/assimp/code/MMDImporter.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmdParser.h (renamed from thirdparty/assimp/code/MMDPmdParser.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.cpp (renamed from thirdparty/assimp/code/MMDPmxParser.cpp)6
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.h (renamed from thirdparty/assimp/code/MMDPmxParser.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDVmdParser.h (renamed from thirdparty/assimp/code/MMDVmdParser.h)0
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.cpp (renamed from thirdparty/assimp/code/MaterialSystem.cpp)12
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.h (renamed from thirdparty/assimp/code/MaterialSystem.h)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp (renamed from thirdparty/assimp/code/CalcTangentsProcess.cpp)6
-rw-r--r--thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h (renamed from thirdparty/assimp/code/CalcTangentsProcess.h)4
-rw-r--r--thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp (renamed from thirdparty/assimp/code/ComputeUVMappingProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h (renamed from thirdparty/assimp/code/ComputeUVMappingProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp (renamed from thirdparty/assimp/code/ConvertToLHProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h (renamed from thirdparty/assimp/code/ConvertToLHProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp (renamed from thirdparty/assimp/code/DeboneProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/DeboneProcess.h (renamed from thirdparty/assimp/code/DeboneProcess.h)17
-rw-r--r--thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp (renamed from thirdparty/assimp/code/DropFaceNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h (renamed from thirdparty/assimp/code/DropFaceNormalsProcess.h)11
-rw-r--r--thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp (renamed from thirdparty/assimp/code/EmbedTexturesProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h (renamed from thirdparty/assimp/code/EmbedTexturesProcess.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp (renamed from thirdparty/assimp/code/FindDegenerates.cpp)1
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindDegenerates.h (renamed from thirdparty/assimp/code/FindDegenerates.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp (renamed from thirdparty/assimp/code/FindInstancesProcess.cpp)12
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h (renamed from thirdparty/assimp/code/FindInstancesProcess.h)4
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp (renamed from thirdparty/assimp/code/FindInvalidDataProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h (renamed from thirdparty/assimp/code/FindInvalidDataProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp (renamed from thirdparty/assimp/code/FixNormalsStep.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/FixNormalsStep.h (renamed from thirdparty/assimp/code/FixNormalsStep.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp115
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h76
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp (renamed from thirdparty/assimp/code/GenFaceNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h (renamed from thirdparty/assimp/code/GenFaceNormalsProcess.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp (renamed from thirdparty/assimp/code/GenVertexNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h (renamed from thirdparty/assimp/code/GenVertexNormalsProcess.h)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp (renamed from thirdparty/assimp/code/ImproveCacheLocality.cpp)65
-rw-r--r--thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h (renamed from thirdparty/assimp/code/ImproveCacheLocality.h)7
-rw-r--r--thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp (renamed from thirdparty/assimp/code/JoinVerticesProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h (renamed from thirdparty/assimp/code/JoinVerticesProcess.h)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp (renamed from thirdparty/assimp/code/LimitBoneWeightsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h (renamed from thirdparty/assimp/code/LimitBoneWeightsProcess.h)34
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp (renamed from thirdparty/assimp/code/MakeVerboseFormat.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h (renamed from thirdparty/assimp/code/MakeVerboseFormat.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp (renamed from thirdparty/assimp/code/OptimizeGraph.cpp)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeGraph.h (renamed from thirdparty/assimp/code/OptimizeGraph.h)27
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp (renamed from thirdparty/assimp/code/OptimizeMeshes.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h (renamed from thirdparty/assimp/code/OptimizeMeshes.h)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp (renamed from thirdparty/assimp/code/PretransformVertices.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/PretransformVertices.h (renamed from thirdparty/assimp/code/PretransformVertices.h)15
-rw-r--r--thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp (renamed from thirdparty/assimp/code/ProcessHelper.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ProcessHelper.h (renamed from thirdparty/assimp/code/ProcessHelper.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp (renamed from thirdparty/assimp/code/RemoveRedundantMaterials.cpp)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h (renamed from thirdparty/assimp/code/RemoveRedundantMaterials.h)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp (renamed from thirdparty/assimp/code/RemoveVCProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h (renamed from thirdparty/assimp/code/RemoveVCProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp208
-rw-r--r--thirdparty/assimp/code/PostProcessing/ScaleProcess.h (renamed from thirdparty/assimp/code/ScaleProcess.h)15
-rw-r--r--thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp (renamed from thirdparty/assimp/code/SortByPTypeProcess.cpp)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h (renamed from thirdparty/assimp/code/SortByPTypeProcess.h)11
-rw-r--r--thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp (renamed from thirdparty/assimp/code/SplitLargeMeshes.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h (renamed from thirdparty/assimp/code/SplitLargeMeshes.h)9
-rw-r--r--thirdparty/assimp/code/PostProcessing/TextureTransform.cpp (renamed from thirdparty/assimp/code/TextureTransform.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/TextureTransform.h (renamed from thirdparty/assimp/code/TextureTransform.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp (renamed from thirdparty/assimp/code/TriangulateProcess.cpp)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/TriangulateProcess.h (renamed from thirdparty/assimp/code/TriangulateProcess.h)8
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp (renamed from thirdparty/assimp/code/ValidateDataStructure.cpp)33
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h (renamed from thirdparty/assimp/code/ValidateDataStructure.h)3
-rw-r--r--thirdparty/assimp/code/RawLoader.cpp331
-rw-r--r--thirdparty/assimp/code/ScaleProcess.cpp103
-rw-r--r--thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes12
-rw-r--r--thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html1789
-rw-r--r--thirdparty/assimp/include/assimp/.editorconfig8
-rw-r--r--thirdparty/assimp/include/assimp/BaseImporter.h61
-rw-r--r--thirdparty/assimp/include/assimp/Exporter.hpp2
-rw-r--r--thirdparty/assimp/include/assimp/ParsingUtils.h3
-rw-r--r--thirdparty/assimp/include/assimp/aabb.h76
-rw-r--r--thirdparty/assimp/include/assimp/camera.h5
-rw-r--r--thirdparty/assimp/include/assimp/color4.inl4
-rw-r--r--thirdparty/assimp/include/assimp/config.h.in40
-rw-r--r--thirdparty/assimp/include/assimp/defs.h21
-rw-r--r--thirdparty/assimp/include/assimp/irrXMLWrapper.h144
-rw-r--r--thirdparty/assimp/include/assimp/material.h46
-rw-r--r--thirdparty/assimp/include/assimp/mesh.h11
-rw-r--r--thirdparty/assimp/include/assimp/postprocess.h13
-rw-r--r--thirdparty/assimp/include/assimp/scene.h9
-rw-r--r--thirdparty/freetype/include/freetype/freetype.h15
-rw-r--r--thirdparty/freetype/include/freetype/fterrors.h4
-rw-r--r--thirdparty/freetype/include/freetype/ftglyph.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftimage.h16
-rw-r--r--thirdparty/freetype/include/freetype/ftmodapi.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftoutln.h8
-rw-r--r--thirdparty/freetype/include/freetype/ftwinfnt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftcalc.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftobjs.h6
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftstream.h11
-rw-r--r--thirdparty/freetype/include/freetype/internal/fttrace.h1
-rw-r--r--thirdparty/freetype/include/freetype/internal/internal.h1
-rw-r--r--thirdparty/freetype/include/freetype/internal/psaux.h8
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svgldict.h4
-rw-r--r--thirdparty/freetype/include/freetype/internal/sfnt.h1
-rw-r--r--thirdparty/freetype/include/freetype/internal/t1types.h4
-rw-r--r--thirdparty/freetype/include/freetype/internal/tttypes.h83
-rw-r--r--thirdparty/freetype/include/freetype/internal/wofftypes.h112
-rw-r--r--thirdparty/freetype/src/autofit/afblue.c7
-rw-r--r--thirdparty/freetype/src/autofit/afblue.dat10
-rw-r--r--thirdparty/freetype/src/autofit/afblue.h139
-rw-r--r--thirdparty/freetype/src/autofit/afcjk.c5
-rw-r--r--thirdparty/freetype/src/autofit/afglobal.c11
-rw-r--r--thirdparty/freetype/src/autofit/aflatin.c58
-rw-r--r--thirdparty/freetype/src/autofit/afranges.c15
-rw-r--r--thirdparty/freetype/src/autofit/afscript.h6
-rw-r--r--thirdparty/freetype/src/autofit/afstyles.h7
-rw-r--r--thirdparty/freetype/src/base/ftbbox.c12
-rw-r--r--thirdparty/freetype/src/base/ftbitmap.c15
-rw-r--r--thirdparty/freetype/src/base/fterrors.c1
-rw-r--r--thirdparty/freetype/src/base/ftinit.c3
-rw-r--r--thirdparty/freetype/src/base/ftlcdfil.c12
-rw-r--r--thirdparty/freetype/src/base/ftobjs.c4
-rw-r--r--thirdparty/freetype/src/base/ftoutln.c13
-rw-r--r--thirdparty/freetype/src/base/ftstroke.c56
-rw-r--r--thirdparty/freetype/src/base/ftver.rc4
-rw-r--r--thirdparty/freetype/src/bdf/bdf.h6
-rw-r--r--thirdparty/freetype/src/bdf/bdfdrivr.c30
-rw-r--r--thirdparty/freetype/src/bdf/bdflib.c219
-rw-r--r--thirdparty/freetype/src/cache/rules.mk2
-rw-r--r--thirdparty/freetype/src/cff/cffdrivr.c4
-rw-r--r--thirdparty/freetype/src/cff/cffobjs.c2
-rw-r--r--thirdparty/freetype/src/cff/cffparse.c155
-rw-r--r--thirdparty/freetype/src/cff/cffparse.h13
-rw-r--r--thirdparty/freetype/src/gzip/ftgzip.c2
-rw-r--r--thirdparty/freetype/src/gzip/infblock.c5
-rw-r--r--thirdparty/freetype/src/gzip/infcodes.c4
-rw-r--r--thirdparty/freetype/src/gzip/inflate.c10
-rw-r--r--thirdparty/freetype/src/pcf/pcf.h3
-rw-r--r--thirdparty/freetype/src/pcf/pcfdrivr.c12
-rw-r--r--thirdparty/freetype/src/pcf/pcfread.c180
-rw-r--r--thirdparty/freetype/src/pfr/pfrobjs.c2
-rw-r--r--thirdparty/freetype/src/psaux/afmparse.c3
-rw-r--r--thirdparty/freetype/src/psaux/psfixed.h3
-rw-r--r--thirdparty/freetype/src/psaux/psfont.c6
-rw-r--r--thirdparty/freetype/src/psaux/psobjs.c8
-rw-r--r--thirdparty/freetype/src/psaux/psobjs.h8
-rw-r--r--thirdparty/freetype/src/raster/ftraster.c72
-rw-r--r--thirdparty/freetype/src/sfnt/rules.mk1
-rw-r--r--thirdparty/freetype/src/sfnt/sfdriver.c18
-rw-r--r--thirdparty/freetype/src/sfnt/sfnt.c1
-rw-r--r--thirdparty/freetype/src/sfnt/sfobjs.c399
-rw-r--r--thirdparty/freetype/src/sfnt/sfobjs.h2
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff.c434
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff.h41
-rw-r--r--thirdparty/freetype/src/sfnt/ttcmap.c5
-rw-r--r--thirdparty/freetype/src/sfnt/ttmtx.c6
-rw-r--r--thirdparty/freetype/src/smooth/ftgrays.c299
-rw-r--r--thirdparty/freetype/src/smooth/ftsmooth.c2
-rw-r--r--thirdparty/freetype/src/truetype/ttgload.c123
-rw-r--r--thirdparty/freetype/src/truetype/ttgxvar.c94
-rw-r--r--thirdparty/freetype/src/truetype/ttgxvar.h1
-rw-r--r--thirdparty/freetype/src/truetype/ttinterp.c391
-rw-r--r--thirdparty/freetype/src/truetype/ttobjs.c45
-rw-r--r--thirdparty/freetype/src/truetype/ttpload.c6
-rw-r--r--thirdparty/freetype/src/type1/t1driver.c4
-rw-r--r--thirdparty/freetype/src/type1/t1load.c31
-rw-r--r--thirdparty/freetype/src/type42/t42drivr.c4
-rw-r--r--thirdparty/freetype/src/type42/t42objs.c21
-rw-r--r--thirdparty/freetype/src/type42/t42parse.c13
-rw-r--r--thirdparty/glad/KHR/khrplatform.h12
-rw-r--r--thirdparty/glad/glad.c2
-rw-r--r--thirdparty/glad/glad/glad.h10
-rw-r--r--thirdparty/jpeg-compressor/jpgd.cpp55
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aes.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aesni.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/arc4.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1write.h13
-rw-r--r--thirdparty/mbedtls/include/mbedtls/base64.h9
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bignum.h11
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bn_mul.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/camellia.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ccm.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/certs.h240
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cipher.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cmac.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/compat-1.3.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/config.h24
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ctr_drbg.h10
-rw-r--r--thirdparty/mbedtls/include/mbedtls/des.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/dhm.h3
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdh.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdsa.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecjpake.h5
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp.h132
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp_internal.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/error.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/gcm.h10
-rw-r--r--thirdparty/mbedtls/include/mbedtls/havege.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hkdf.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hmac_drbg.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md2.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md4.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md5.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/net.h5
-rw-r--r--thirdparty/mbedtls/include/mbedtls/nist_kw.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/padlock.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pem.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs12.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs5.h10
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_util.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/poly1305.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ripemd160.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/rsa.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha1.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha256.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha512.h5
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl.h20
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cache.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cookie.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_internal.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ticket.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509.h4
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crt.h2
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_csr.h8
-rw-r--r--thirdparty/mbedtls/include/mbedtls/xtea.h4
-rw-r--r--thirdparty/mbedtls/library/aes.c98
-rw-r--r--thirdparty/mbedtls/library/asn1write.c28
-rw-r--r--thirdparty/mbedtls/library/bignum.c191
-rw-r--r--thirdparty/mbedtls/library/ccm.c16
-rw-r--r--thirdparty/mbedtls/library/certs.c2040
-rw-r--r--thirdparty/mbedtls/library/chacha20.c10
-rw-r--r--thirdparty/mbedtls/library/debug.c44
-rw-r--r--thirdparty/mbedtls/library/des.c79
-rw-r--r--thirdparty/mbedtls/library/dhm.c16
-rw-r--r--thirdparty/mbedtls/library/ecdh.c27
-rw-r--r--thirdparty/mbedtls/library/ecdsa.c9
-rw-r--r--thirdparty/mbedtls/library/ecp.c20
-rw-r--r--thirdparty/mbedtls/library/ecp_curves.c60
-rw-r--r--thirdparty/mbedtls/library/entropy_poll.c29
-rw-r--r--thirdparty/mbedtls/library/havege.c2
-rw-r--r--thirdparty/mbedtls/library/md4.c30
-rw-r--r--thirdparty/mbedtls/library/md5.c21
-rw-r--r--thirdparty/mbedtls/library/oid.c53
-rw-r--r--thirdparty/mbedtls/library/poly1305.c8
-rw-r--r--thirdparty/mbedtls/library/ripemd160.c39
-rw-r--r--thirdparty/mbedtls/library/sha1.c36
-rw-r--r--thirdparty/mbedtls/library/sha256.c31
-rw-r--r--thirdparty/mbedtls/library/sha512.c21
-rw-r--r--thirdparty/mbedtls/library/ssl_ciphersuites.c57
-rw-r--r--thirdparty/mbedtls/library/version_features.c3
-rw-r--r--thirdparty/mbedtls/library/x509.c62
-rw-r--r--thirdparty/mbedtls/library/x509_crl.c10
-rw-r--r--thirdparty/mbedtls/library/x509_crt.c51
-rw-r--r--thirdparty/mbedtls/library/x509_csr.c15
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c47
-rw-r--r--thirdparty/mbedtls/library/x509write_csr.c36
-rw-r--r--thirdparty/misc/stb_vorbis.c11
-rw-r--r--thirdparty/pcre2/AUTHORS6
-rw-r--r--thirdparty/pcre2/LICENCE6
-rw-r--r--thirdparty/pcre2/src/config.h15
-rw-r--r--thirdparty/pcre2/src/pcre2.h108
-rw-r--r--thirdparty/pcre2/src/pcre2_auto_possess.c14
-rw-r--r--thirdparty/pcre2/src/pcre2_chartables.c18
-rw-r--r--thirdparty/pcre2/src/pcre2_compile.c678
-rw-r--r--thirdparty/pcre2/src/pcre2_context.c22
-rw-r--r--thirdparty/pcre2/src/pcre2_convert.c2
-rw-r--r--thirdparty/pcre2/src/pcre2_dfa_match.c71
-rw-r--r--thirdparty/pcre2/src/pcre2_error.c19
-rw-r--r--thirdparty/pcre2/src/pcre2_extuni.c4
-rw-r--r--thirdparty/pcre2/src/pcre2_internal.h257
-rw-r--r--thirdparty/pcre2/src/pcre2_intmodedep.h5
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_compile.c2230
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_match.c6
-rw-r--r--thirdparty/pcre2/src/pcre2_maketables.c26
-rw-r--r--thirdparty/pcre2/src/pcre2_match.c88
-rw-r--r--thirdparty/pcre2/src/pcre2_match_data.c8
-rw-r--r--thirdparty/pcre2/src/pcre2_script_run.c441
-rw-r--r--thirdparty/pcre2/src/pcre2_study.c16
-rw-r--r--thirdparty/pcre2/src/pcre2_substitute.c67
-rw-r--r--thirdparty/pcre2/src/pcre2_tables.c71
-rw-r--r--thirdparty/pcre2/src/pcre2_ucd.c7213
-rw-r--r--thirdparty/pcre2/src/pcre2_ucp.h1
-rw-r--r--thirdparty/pcre2/src/pcre2_xclass.c6
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfigInternal.h2
-rw-r--r--thirdparty/pcre2/src/sljit/sljitExecAllocator.c46
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.c11
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_64.c20
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c11
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c13
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c164
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_common.c2
-rw-r--r--thirdparty/tinyexr/tinyexr.h206
-rw-r--r--thirdparty/xatlas/avoid-failing-on-bad-geometry.patch157
-rw-r--r--thirdparty/xatlas/build-fix-limits.patch14
-rw-r--r--thirdparty/xatlas/xatlas.cpp12186
-rw-r--r--thirdparty/xatlas/xatlas.h338
-rw-r--r--thirdparty/zstd/common/compiler.h7
-rw-r--r--thirdparty/zstd/common/zstd_internal.h64
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c292
-rw-r--r--thirdparty/zstd/compress/zstd_compress_internal.h104
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.c92
-rw-r--r--thirdparty/zstd/compress/zstd_fast.c49
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.c15
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.c2
-rw-r--r--thirdparty/zstd/compress/zstd_opt.c77
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.c25
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.h1
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c21
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.c29
-rw-r--r--thirdparty/zstd/zstd.h74
-rw-r--r--version.py2
1656 files changed, 139073 insertions, 62890 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 399fca03e8..3bbe47af2a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -30,7 +30,6 @@ doc_classes/* @godotengine/documentation
/modules/bullet/ @AndreaCatania
/modules/csg/ @BastiaanOlij
/modules/enet/ @godotengine/network
-/modules/gdnative/ @karroffel
/modules/gdnative/*arvr/ @BastiaanOlij
/modules/gdscript/ @vnen @bojidar-bg
/modules/mbedtls/ @godotengine/network
@@ -45,6 +44,6 @@ doc_classes/* @godotengine/documentation
/platform/uwp/ @vnen
/server/physics*/ @reduz @AndreaCatania
-/server/visual*/ @reduz @karroffel
+/server/visual*/ @reduz
/thirdparty/ @akien-mga
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 1ca0b3694c..0000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-<!-- Please search existing issues for potential duplicates before filing yours:
-https://github.com/godotengine/godot/issues?q=is%3Aissue
--->
-
-**Godot version:**
-<!-- Specify commit hash if non-official. -->
-
-
-**OS/device including version:**
-<!-- Specify GPU model and drivers if graphics-related. -->
-
-
-**Issue description:**
-<!-- What happened, and what was expected. -->
-
-
-**Steps to reproduce:**
-
-
-**Minimal reproduction project:**
-<!-- Recommended as it greatly speeds up debugging. Drag and drop a zip archive to upload it. -->
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000000..91528465c0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,18 @@
+---
+name: Bug report
+about: Report a bug in Godot
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Godot version:**
+
+**OS/device including version:**
+
+**Issue description:**
+
+**Steps to reproduce:**
+
+**Minimal reproduction project:**
diff --git a/.github/ISSUE_TEMPLATE/feature---enhancement-request.md b/.github/ISSUE_TEMPLATE/feature---enhancement-request.md
new file mode 100644
index 0000000000..496e0197ca
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature---enhancement-request.md
@@ -0,0 +1,19 @@
+---
+name: Feature / Enhancement Request
+about: Adding new features or improving existing ones.
+title: 'IMPORTANT: This repository no longer accepts feature / enhancement requests.'
+labels: ''
+assignees: ''
+
+---
+
+**IMPORTANT, PLEASE READ**
+
+Feature / Enhancement requests are no longer accepted in the main Godot repository.
+Please open an item by filling the relevant fields in the *Proposals* repository:
+
+https://github.com/godotengine/godot-proposals/issues/new/choose
+
+Do not submit to this repository or your issue will be closed.
+
+**IMPORTANT, PLEASE READ**
diff --git a/.gitignore b/.gitignore
index f43f68f25f..0ee2a8b382 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# Godot auto generated files
*.gen.*
+.import/
# Documentation generated by doxygen or from classes.xml
doc/_build/
diff --git a/.travis.yml b/.travis.yml
index b52e40200f..a763fa5376 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,10 @@ language: cpp
# OS config, depends on actual 'os' in build matrix
dist: xenial
-sudo: false
+
+stages:
+ - check
+ - build
env:
global:
@@ -18,6 +21,7 @@ cache:
matrix:
include:
- name: Static checks (clang-format)
+ stage: check
env: STATIC_CHECKS=yes
os: linux
compiler: gcc
@@ -29,6 +33,7 @@ matrix:
- clang-format-8
- name: Linux editor (debug, GCC 9, with Mono)
+ stage: build
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-9
@@ -52,6 +57,7 @@ matrix:
branch_pattern: coverity_scan
- name: Linux export template (release, Clang)
+ stage: build
env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
os: linux
compiler: clang
@@ -61,22 +67,26 @@ matrix:
- *linux_deps
- name: Android export template (release_debug, Clang)
+ stage: build
env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
os: linux
compiler: clang
- name: macOS editor (debug, Clang)
+ stage: build
env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang
os: osx
compiler: clang
- name: iOS export template (debug, Clang)
+ stage: build
env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang
os: osx
compiler: clang
- - 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"
+ - name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running)
+ stage: build
+ 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" TEST_PROJECT=yes
os: linux
compiler: gcc-9
addons:
@@ -88,6 +98,7 @@ matrix:
- *linux_deps
- name: Linux export template (release_debug, GCC 5, without 3D support)
+ stage: build
env: PLATFORM=x11 TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-5 EXTRA_ARGS="disable_3d=yes"
os: linux
compiler: gcc
@@ -124,5 +135,10 @@ script:
- if [ "$STATIC_CHECKS" = "yes" ]; then
sh ./misc/travis/clang-format.sh;
else
- scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS;
+ scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS &&
+ if [ "$TEST_PROJECT" = "yes" ]; then
+ git clone --depth 1 "https://github.com/godotengine/godot-tests.git";
+ sed -i "s:custom_template/release=\"\":custom_template/release=\"$(readlink -e bin/godot_server.x11.opt.tools.64)\":" godot-tests/tests/project_export/export_presets.cfg;
+ godot-tests/tests/project_export/test_project.sh "bin/godot_server.x11.opt.tools.64";
+ fi
fi
diff --git a/AUTHORS.md b/AUTHORS.md
index 43b4917382..523f253228 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -36,6 +36,7 @@ name is available.
Andy Moss (MillionOstrich)
Anish Bhobe (KidRigger)
Anton Yabchinskiy (a12n)
+ Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Bastiaan Olij (BastiaanOlij)
@@ -56,6 +57,7 @@ name is available.
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
DualMatrix
+ Emmanuel Barroga (sparkart)
Emmanuel Leblond (touilleMan)
Eric Lasota (elasota)
est31
@@ -68,6 +70,7 @@ name is available.
Gerrit Großkopf (Grosskopf)
Gilles Roudiere (groud)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
+ Hanif A (hbina)
Hein-Pieter van Braam (hpvb)
Hiroshi Ogawa (hi-ogawa)
homer666
@@ -104,6 +107,7 @@ name is available.
Masoud BH (masoudbh3)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
+ merumelu
Michael Alexsander Silva Dias (YeldhamDev)
mrezai
Nathan Warden (NathanWarden)
@@ -128,6 +132,7 @@ name is available.
romulox-x
Ruslan Mustakov (endragor)
Saniko (sanikoyes)
+ santouits
SaracenOne
sersoong
Simon Wenner (swenner)
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 326581a492..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/
@@ -301,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
@@ -330,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/
@@ -351,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
diff --git a/DONORS.md b/DONORS.md
index 947c12923b..ce58721697 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -17,11 +17,12 @@ generous deed immortalized in the next stable release of Godot Engine.
## Gold sponsors
Gamblify <https://www.gamblify.com>
+ Moonwards <https://www.moonwards.com>
## Mini sponsors
+ AD Ford
Alan Beauchamp
- Aleksandar Kordic
Anandarup Mallik
Andrew Dunai
Brandon Lamb
@@ -30,12 +31,16 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoph Woinke
Denis Malyavin
Edward Flick
+ Gamechuck
GameDev.net
GameDev.tv
+ Grady
Hein-Pieter van Braam
Jacob McKenney
Javary Co.
+ Jeppe Zapp
Justin Arnold
+ Justo Delgado Baudí
Kyle Szklenski
Leonard Meagher
Matthieu Huvé
@@ -46,7 +51,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Patrick Aarstad
Slobodan Milnovic
Stephan Lanfermann
- Stephen Telford
Steve
VilliHaukka
Xananax
@@ -56,10 +60,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Andrei
cheese65536
+ Daniel Hartmann
+ Dave
David Gehrig
Ed Morley
Florian Krick
- Grady
Jakub Grzesik
K9Kraken
Manuele Finocchiaro
@@ -70,56 +75,62 @@ generous deed immortalized in the next stable release of Godot Engine.
Zaven Muradyan
Alexander Trey Saunders
- Allen Schade
Asher Glick
Austen McRae
+ beVR
Brian van der Stel
+ Cameron MacNair
Carlo Cabanilla
Daniel James
David Giardi
+ David Snopek
+ Default Name
Edward E
Florian Breisch
Gero
+ GiulianoB
Javier Roman
Jay Horton
- Jon Smith
+ Jonathan Turner
Jon Woodward
- Justo Delgado Baudí
+ Jose Fernando Alexandre
Karl Werf
Kommentgames
- Krzysztof Dluzniewski
Luke
- Moonwards
+ Maciej Pendolski
+ Matthew Hillier
Mored1984
- paul gruenbacher
Paul LaMotte
Péter Magyar
Rob Messick
- Ross Esmond
Ryan Badour
Scott Wadden
Sergey
Shawn Yu
Svenne Krap
+ thechris
Tom Langwaldt
+ tukon
William Wold
- Wyatt Goodin
Alex Khayrullin
+ Branwyn Tylwyth
Chris Goddard
Chris Serino
Christian Padilla
Conrad Curry
Craig Smith
+ Darrian Little
Dean Harmon
Ian Richard Kunert
Ivan Trombley
Joan Fons
+ Joshua Flores
Krzysztof Jankowski
Lord Bloodhound
Lucas Ferreira Franca
- Michele Zilli
Nathan Lundquist
+ Nicklas Breum
Pascal Grüter
Petr Malac
Rami
@@ -135,9 +146,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Xavier PATRICELLI
Adam Neumann
- Alessandra Pereyra
Alexander J Maynard
Alexey Dyadchenko
+ André Frélicot
+ andres eduardo lopez
Andrew Bowen
Asdf
Ben Botwin
@@ -147,50 +159,48 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoph Schröder
Cody Parker
D
- Daniel
Daniel Eichler
David White
- Deadly Lampshade
Eric
+ Eric Churches
Eric Monson
Eugenio Hugo Salgüero Jáñez
flesk
- Francisco Javier Moreno Carracedo
gavlig
GGGames.org
- Giles Montgomery
Guilherme Felipe de C. G. da Silva
Heath Hayes
Hysteria
Idzard Kwadijk
Jared White
- Jesse Nave
+ Joe Flood
Jose Malheiro
- Joshua Flores
Joshua Lesperance
Juan T Chen
Juraj Móza
Kasper Jeppesen
+ kinfox
Klaus The.
Klavdij Voncina
- Leandro Voltolino
Maarten Elings
+ Marcelo Dornbusch Lopes
Markus Fehr
Markus Wiesner
Martin Eigel
Marvin
Matt Eunson
- Matthew Hillier
Max Bulai
Max R.R. Collada
M H
Nick Nikitin
Oliver Dick
- Paolo Munoz
+ Patrick Ting
Paul Hocker
Paul Von Zimmerman
Pete Goodwin
+ pl
Ranoller
+ Romildo Franco
Samuel Judd
Scott Pilet
spilldata
@@ -198,60 +208,59 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Krampl
Tobias Bocanegra
Urho
- WytRabbit
- Xavier Fumado Beltran
+ Zie Weaver
## Silver donors
1D_Inc
+ Abby Jones
Abraham Haskins
Adam Brunnmeier
Adam Carr
Adam Nakonieczny
Adam Smeltzer
Adisibio
+ Adrian Demetrescu
+ Aggelos Arnaoutis
Agustinus Arya
Aidan O'Flannagain
+ Albin Jonasson Svärdsby
Alder Stefano
Alessandro Senese
- Alexander Gillberg
Alexander Koppe
Alex Davies-Moore
- Alice Robinson
+ Allen Schade
Andreas Evers
Andreas Krampitz
+ Andreas Lundmark
Andreas Schüle
- Andrew Peart
+ André Simões
+ Andrés Rodríguez
+ Andrzej Skalski
Anthony Bongiovanni
Anthony Staunton
+ Anton Kurkin
Antony K. Jones
+ AP Condomines
Arda Erol
- Artem Bashev
Arthur S. Muszynski
- Artistofdeath
Aubrey Falconer
Avencherus
B A
Balázs Batári
- Bastian Böhm
Beliar
Benedikt
Ben Phelan
Ben Vercammen
- Ben Woodley
- Berbank
Bernd Jänichen
Black Block
Blair Allen
Bobby CC Wong
- Boyquotes
- Branwyn Tylwyth
Bryan Stevenson
Caleb Dumitry
Carwyn Edwards
Chris Brown
Chris Chapin
- Chris Gonzales
Christian Baune
Christian Winter
Christoffer Sundbom
@@ -260,18 +269,22 @@ generous deed immortalized in the next stable release of Godot Engine.
Cobaltum
Collin Shooltz
Dag Sundin Söderström
+ Dan H. Bentsen
Daniel Johnson
+ DanielMaximiano
+ Daniel Pontillo
Daniel Reed
- Danny Welch
- Dave Watts
+ Daniel Tebbutt
David Bullock
David Cravens
David May
- Dimitri Stanojevic
+ David Rapisarda
+ David Woodard
Dominic Cooney
Dominik Wetzel
- DrevanTonder
+ Donovan Hutcheon
Duobix
+ Eduardo Teixeira
Edward Herbert
Egon Elbre
Ellen Marie Dash
@@ -280,18 +293,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Eric Ellingson
Eric Martini
Eric Williams
+ EugeneTel
Evan Rose
Felix Kollmann
fengjiongmax
Flaredown
FuDiggity
G3Dev sàrl
+ Gadzhi Kharkharov
+ gamedev by Celio
Gary Hulst
- Gerrit Großkopf
+ George Marques
gmmath
- Grant Clarke
Greg Olson
Greg P
+ Greyson Richey
Guldoman
Hal A
Heribert Hirth
@@ -299,7 +315,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Hunter Jones
Hylpher
ialex32x
- Igor Buzatovic
Iiari
IndustrialRobot
Isaac Morton
@@ -326,28 +341,33 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Bonazza
Jon Sully
Jose Aleman
+ Jose Andrés Mejias Rojas
Joseph Catrambone
Josh 'Cheeseness' Bush
Juanfran
Juan Negrier
+ Juan Velandia
Judd
Jueast
Julian Murgia
- Kasier Bald0
+ Justin Spedding
+ Kaiser Bald0
+ Kamuna
+ Kauzig
KC Chan
+ Keedong Park
kickmaniac
Kiyohiro Kawamura (kyorohiro)
+ Kjetil Haugland
Klagsam
Klassix
KR McGinley
KsyTek Games
Kuan Cheang
kycho
- Leviathan Hunter
Levi Lindsey
Linus Lind Lundgren
Lionel Gaillard
- Luis Moraes
LunaticInAHat
Lurkars
Macil
@@ -355,61 +375,75 @@ generous deed immortalized in the next stable release of Godot Engine.
Malcolm
Malik Ahmed
Malik Nejer
- Marc Urlus
Marcus Richter
+ Markus Lohaus
Markus Michael Egger
Martin Holas
+ Martin Liška
+ Matt Edwards
Matthew Little
Maxwell
medecau
mhilbrunner
Michael Dürwald
Michael Gringauz
+ Michael Haney
Michael Labbe
Mikael Olsson
Mikayla Hutchinson
+ Mike Birkhead
Mike Cunningham
Mitchell J. Wagner
- mlevin cantu
MoM
- Moritz Laass
MuffinManKen
+ Nathan Fish
Natrim
nee
Neil Blakey-Milner
Nerdforge
Nicholas
+ Nicholas Bettencourt
+ Nick Macholl
Niclas Eriksen
Nicolás Montaña
Nicolas SAN AGUSTIN
+ Nima Farid
Nithin Jino
NZ
+ Olivier
Omar Delarosa
+ omzee
Oscar Norlander
Pafka
Pan Ip
+ Pat LaBine
Patrick Forringer
Patrick Nafarrete
Paul Gieske
Paul Mason
Paweł Kowal
- Philip O. Staiger
+ Philip Cohoe
Pierre-Igor Berthet
- Pietro Vertechi
Pitsanu Tongprasin
Point08
Poryg
Rafa Laguna
Rafal Wyszomirski
Raphael Leroux
+ Remi Rampin
Rémi Verschelde
+ Rezgi
Ricardo Alcantara
Robert Farr (Larington)
Robert Hernandez
+ Robert Larnach
Rodrigo Loli
Roger Smith
Roland RzÄ…sa
Roman Tinkov
+ Ronan Jouchet
+ Ryan
+ Ryan Brooks
Ryan Groom
Ryan Hentz
Saad Khoudmi
@@ -418,46 +452,51 @@ generous deed immortalized in the next stable release of Godot Engine.
Sasori Olkof
Scott D. Yelich
Sebastian Michailidis
+ sgnsajgon
+ Shane
Shane Sicienski
Shane Spoor
Simon Ledam
Simon Wenner
SK
Sootstone
- Stonepyre
- Thibault Barbaroux
+ Taylor Fahlman
thomas
Thomas Bell
Thomas Kelly
Thomas Kurz
tiansheng li
- Tim
Tim Drumheller
Tim Gudex
- Timo Schmidt
Timothy B. MacDonald
Tobbun
+ Tom Fulp
+ Tom Glenn
Tom Larrow
Torsten Crass
Travis O'Brien
Trent Skinner
+ Triptych
+ Troy Bonneau
Tryggve Sollid
Turgut Temucin
Tyler Stafos
UltyX
Vaiktorg
- Valeria Viana Gusmao
- Veodok
Victor
Vigilant Watch
+ Vincent Cloutier
waka nya
+ Walter Byers
Wayne Haak
werner mendizabal
Wiley Thompson
Will
William Hogben
Wout Standaert
- Yeung Si Xiang
+ Wyatt Goodin
+ Yegor
+ 蕭惟å…
## Bronze donors
diff --git a/SConstruct b/SConstruct
index 7b0c644aea..128c5b0e92 100644
--- a/SConstruct
+++ b/SConstruct
@@ -311,6 +311,10 @@ if selected_platform in platform_list:
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
+ # Enable C++11 support
+ if not env.msvc:
+ env.Append(CXXFLAGS=['-std=c++11'])
+
# Configure compiler warnings
if env.msvc:
# Truncations, narrowing conversions, signed/unsigned comparisons...
@@ -422,7 +426,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()
@@ -480,6 +484,13 @@ if selected_platform in platform_list:
if env['minizip']:
env.Append(CPPDEFINES=['MINIZIP_ENABLED'])
+ editor_module_list = ['regex']
+ for x in editor_module_list:
+ if not env['module_' + x + '_enabled']:
+ if env['tools']:
+ print("Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
+ sys.exit(255)
+
if not env['verbose']:
methods.no_verbose(sys, env)
@@ -522,13 +533,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 85e5f1b089..ed9a0a231d 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -159,6 +159,7 @@ env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]
# Chain load SCsubs
SConscript('os/SCsub')
SConscript('math/SCsub')
+SConscript('crypto/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
diff --git a/core/array.cpp b/core/array.cpp
index a334af2c04..ac30df08bc 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -133,18 +133,12 @@ void Array::erase(const Variant &p_value) {
}
Variant Array::front() const {
- if (_p->array.size() == 0) {
- ERR_EXPLAIN("Can't take value from empty array");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
return operator[](0);
}
Variant Array::back() const {
- if (_p->array.size() == 0) {
- ERR_EXPLAIN("Can't take value from empty array");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
return operator[](_p->array.size() - 1);
}
@@ -228,6 +222,63 @@ Array Array::duplicate(bool p_deep) const {
return new_arr;
}
+
+int Array::_fix_slice_index(int p_index, int p_arr_len, int p_top_mod) {
+ p_index = CLAMP(p_index, -p_arr_len, p_arr_len + p_top_mod);
+ if (p_index < 0) {
+ p_index = (p_index % p_arr_len + p_arr_len) % p_arr_len; // positive modulo
+ }
+ return p_index;
+}
+
+int Array::_clamp_index(int p_index) const {
+ return CLAMP(p_index, -size() + 1, size() - 1);
+}
+
+#define ARRAY_GET_DEEP(idx, is_deep) is_deep ? get(idx).duplicate(is_deep) : get(idx)
+
+Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
+ Array new_arr;
+
+ p_begin = Array::_fix_slice_index(p_begin, size(), -1); // can't start out of range
+ p_end = Array::_fix_slice_index(p_end, size(), 0);
+
+ int x = p_begin;
+ int new_arr_i = 0;
+
+ ERR_FAIL_COND_V(p_step == 0, new_arr);
+ if (Array::_clamp_index(p_begin) == Array::_clamp_index(p_end)) { // don't include element twice
+ new_arr.resize(1);
+ // new_arr[0] = 1;
+ new_arr[0] = ARRAY_GET_DEEP(Array::_clamp_index(p_begin), p_deep);
+ return new_arr;
+ } else {
+ int element_count = ceil((int)MAX(0, (p_end - p_begin) / p_step)) + 1;
+ if (element_count == 1) { // delta going in wrong direction to reach end
+ new_arr.resize(0);
+ return new_arr;
+ }
+ new_arr.resize(element_count);
+ }
+
+ // if going backwards, have to have a different terminating condition
+ if (p_step < 0) {
+ while (x >= p_end) {
+ new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
+ x += p_step;
+ new_arr_i += 1;
+ }
+ } else if (p_step > 0) {
+ while (x <= p_end) {
+ new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
+ x += p_step;
+ new_arr_i += 1;
+ }
+ }
+
+ return new_arr;
+}
+
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
diff --git a/core/array.h b/core/array.h
index d4e937a486..7a754d53ea 100644
--- a/core/array.h
+++ b/core/array.h
@@ -44,6 +44,9 @@ class Array {
void _ref(const Array &p_from) const;
void _unref() const;
+ int _clamp_index(int p_index) const;
+ static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod);
+
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
@@ -91,6 +94,8 @@ public:
Array duplicate(bool p_deep = false) const;
+ Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
+
Variant min() const;
Variant max() const;
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 34bbdb2c75..5161f8bab2 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -30,11 +30,11 @@
#include "core_bind.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/file_access_compressed.h"
#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"
@@ -73,10 +73,7 @@ RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool
Error err = OK;
RES ret = ResourceLoader::load(p_path, p_type_hint, p_no_cache, &err);
- if (err != OK) {
- ERR_EXPLAIN("Error loading resource: '" + p_path + "'");
- ERR_FAIL_V(ret);
- }
+ ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'.");
return ret;
}
@@ -148,10 +145,7 @@ _ResourceLoader::_ResourceLoader() {
}
Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) {
- if (p_resource.is_null()) {
- ERR_EXPLAIN("Can't save empty resource to path: " + String(p_path))
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path: " + String(p_path) + ".");
return ResourceSaver::save(p_path, p_resource, p_flags);
}
@@ -191,10 +185,31 @@ _ResourceSaver::_ResourceSaver() {
/////////////////OS
+void _OS::global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta) {
+
+ OS::get_singleton()->global_menu_add_item(p_menu, p_label, p_signal, p_meta);
+}
+
+void _OS::global_menu_add_separator(const String &p_menu) {
+
+ OS::get_singleton()->global_menu_add_separator(p_menu);
+}
+
+void _OS::global_menu_remove_item(const String &p_menu, int p_idx) {
+
+ OS::get_singleton()->global_menu_remove_item(p_menu, p_idx);
+}
+
+void _OS::global_menu_clear(const String &p_menu) {
+
+ OS::get_singleton()->global_menu_clear(p_menu);
+}
+
Point2 _OS::get_mouse_position() const {
return OS::get_singleton()->get_mouse_position();
}
+
void _OS::set_window_title(const String &p_title) {
OS::get_singleton()->set_window_title(p_title);
@@ -208,6 +223,7 @@ int _OS::get_mouse_button_state() const {
String _OS::get_unique_id() const {
return OS::get_singleton()->get_unique_id();
}
+
bool _OS::has_touchscreen_ui_hint() const {
return OS::get_singleton()->has_touchscreen_ui_hint();
@@ -217,6 +233,7 @@ void _OS::set_clipboard(const String &p_text) {
OS::get_singleton()->set_clipboard(p_text);
}
+
String _OS::get_clipboard() const {
return OS::get_singleton()->get_clipboard();
@@ -263,12 +280,14 @@ void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeab
vm.resizable = p_resizeable;
OS::get_singleton()->set_video_mode(vm, p_screen);
}
+
Size2 _OS::get_video_mode(int p_screen) const {
OS::VideoMode vm;
vm = OS::get_singleton()->get_video_mode(p_screen);
return Size2(vm.width, vm.height);
}
+
bool _OS::is_video_mode_fullscreen(int p_screen) const {
OS::VideoMode vm;
@@ -727,22 +746,16 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
- ERR_EXPLAIN("Invalid second value of: " + itos(second));
- ERR_FAIL_COND_V(second > 59, 0);
+ ERR_FAIL_COND_V_MSG(second > 59, 0, "Invalid second value of: " + itos(second) + ".");
- ERR_EXPLAIN("Invalid minute value of: " + itos(minute));
- ERR_FAIL_COND_V(minute > 59, 0);
+ ERR_FAIL_COND_V_MSG(minute > 59, 0, "Invalid minute value of: " + itos(minute) + ".");
- ERR_EXPLAIN("Invalid hour value of: " + itos(hour));
- ERR_FAIL_COND_V(hour > 23, 0);
+ ERR_FAIL_COND_V_MSG(hour > 23, 0, "Invalid hour value of: " + itos(hour) + ".");
- ERR_EXPLAIN("Invalid month value of: " + itos(month));
- ERR_FAIL_COND_V(month > 12 || month == 0, 0);
+ ERR_FAIL_COND_V_MSG(month > 12 || month == 0, 0, "Invalid month value of: " + itos(month) + ".");
// Do this check after month is tested as valid
- ERR_EXPLAIN("Invalid day value of: " + itos(day) + " which is larger than " + itos(MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1]) + " or 0");
- ERR_FAIL_COND_V(day > MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1] || day == 0, 0);
-
+ ERR_FAIL_COND_V_MSG(day > MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1] || day == 0, 0, "Invalid day value of: " + itos(day) + " which is larger than " + itos(MONTH_DAYS_TABLE[LEAPYEAR(year)][month - 1]) + " or 0.");
// Calculate all the seconds from months past in this year
uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY;
@@ -1137,6 +1150,11 @@ void _OS::_bind_methods() {
//ClassDB::bind_method(D_METHOD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0));
//ClassDB::bind_method(D_METHOD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("global_menu_add_item", "menu", "label", "id", "meta"), &_OS::global_menu_add_item);
+ ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu"), &_OS::global_menu_add_separator);
+ ClassDB::bind_method(D_METHOD("global_menu_remove_item", "menu", "idx"), &_OS::global_menu_remove_item);
+ ClassDB::bind_method(D_METHOD("global_menu_clear", "menu"), &_OS::global_menu_clear);
+
ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count);
ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
ClassDB::bind_method(D_METHOD("get_current_video_driver"), &_OS::get_current_video_driver);
@@ -1414,6 +1432,11 @@ PoolVector<Plane> _Geometry::build_capsule_planes(float p_radius, float p_height
return Geometry::build_capsule_planes(p_radius, p_height, p_sides, p_lats, p_axis);
}
+bool _Geometry::is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) {
+
+ return Geometry::is_point_in_circle(p_point, p_circle_pos, p_circle_radius);
+}
+
real_t _Geometry::segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) {
return Geometry::segment_intersects_circle(p_from, p_to, p_circle_pos, p_circle_radius);
@@ -1666,11 +1689,6 @@ Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_d
return ret;
}
-Vector<Point2> _Geometry::transform_points_2d(const Vector<Point2> &p_points, const Transform2D &p_mat) {
-
- return Geometry::transform_points_2d(p_points, p_mat);
-}
-
Dictionary _Geometry::make_atlas(const Vector<Size2> &p_rects) {
Dictionary ret;
@@ -1709,6 +1727,7 @@ void _Geometry::_bind_methods() {
ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &_Geometry::build_box_planes);
ClassDB::bind_method(D_METHOD("build_cylinder_planes", "radius", "height", "sides", "axis"), &_Geometry::build_cylinder_planes, DEFVAL(Vector3::AXIS_Z));
ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &_Geometry::build_capsule_planes, DEFVAL(Vector3::AXIS_Z));
+ ClassDB::bind_method(D_METHOD("is_point_in_circle", "point", "circle_position", "circle_radius"), &_Geometry::is_point_in_circle);
ClassDB::bind_method(D_METHOD("segment_intersects_circle", "segment_from", "segment_to", "circle_position", "circle_radius"), &_Geometry::segment_intersects_circle);
ClassDB::bind_method(D_METHOD("segment_intersects_segment_2d", "from_a", "to_a", "from_b", "to_b"), &_Geometry::segment_intersects_segment_2d);
ClassDB::bind_method(D_METHOD("line_intersects_line_2d", "from_a", "dir_a", "from_b", "dir_b"), &_Geometry::line_intersects_line_2d);
@@ -1749,8 +1768,6 @@ void _Geometry::_bind_methods() {
ClassDB::bind_method(D_METHOD("offset_polygon_2d", "polygon", "delta", "join_type"), &_Geometry::offset_polygon_2d, DEFVAL(JOIN_SQUARE));
ClassDB::bind_method(D_METHOD("offset_polyline_2d", "polyline", "delta", "join_type", "end_type"), &_Geometry::offset_polyline_2d, DEFVAL(JOIN_SQUARE), DEFVAL(END_SQUARE));
- ClassDB::bind_method(D_METHOD("transform_points_2d", "points", "transform"), &_Geometry::transform_points_2d);
-
ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &_Geometry::make_atlas);
BIND_ENUM_CONSTANT(OPERATION_UNION);
@@ -2621,8 +2638,7 @@ void _Thread::_start_func(void *ud) {
}
}
- ERR_EXPLAIN("Could not call function '" + t->target_method.operator String() + "'' starting thread ID: " + t->get_id() + " Reason: " + reason);
- ERR_FAIL();
+ ERR_FAIL_MSG("Could not call function '" + t->target_method.operator String() + "'' starting thread ID: " + t->get_id() + " Reason: " + reason + ".");
}
}
@@ -2704,10 +2720,7 @@ _Thread::_Thread() {
_Thread::~_Thread() {
- if (active) {
- ERR_EXPLAIN("Reference to a Thread object object was lost while the thread is still running...");
- }
- ERR_FAIL_COND(active);
+ ERR_FAIL_COND_MSG(active, "Reference to a Thread object object was lost while the thread is still running...");
}
/////////////////////////////////////
@@ -2941,6 +2954,10 @@ float _Engine::get_physics_jitter_fix() const {
return Engine::get_singleton()->get_physics_jitter_fix();
}
+float _Engine::get_physics_interpolation_fraction() const {
+ return Engine::get_singleton()->get_physics_interpolation_fraction();
+}
+
void _Engine::set_target_fps(int p_fps) {
Engine::get_singleton()->set_target_fps(p_fps);
}
@@ -3029,6 +3046,7 @@ void _Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second);
ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix);
ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix);
+ ClassDB::bind_method(D_METHOD("get_physics_interpolation_fraction"), &_Engine::get_physics_interpolation_fraction);
ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps);
ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 3be5a08752..693b85710a 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -109,11 +109,11 @@ public:
};
enum PowerState {
- POWERSTATE_UNKNOWN, /**< cannot determine power status */
- POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */
- POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */
- POWERSTATE_CHARGING, /**< Plugged in, charging battery */
- POWERSTATE_CHARGED /**< Plugged in, battery charged */
+ POWERSTATE_UNKNOWN, // Cannot determine power status.
+ POWERSTATE_ON_BATTERY, // Not plugged in, running on the battery.
+ POWERSTATE_NO_BATTERY, // Plugged in, no battery available.
+ POWERSTATE_CHARGING, // Plugged in, charging battery.
+ POWERSTATE_CHARGED // Plugged in, battery charged.
};
enum Weekday {
@@ -127,8 +127,8 @@ public:
};
enum Month {
- /// Start at 1 to follow Windows SYSTEMTIME structure
- /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
+ // Start at 1 to follow Windows SYSTEMTIME structure
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
MONTH_JANUARY = 1,
MONTH_FEBRUARY,
MONTH_MARCH,
@@ -143,6 +143,11 @@ public:
MONTH_DECEMBER
};
+ void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
+ void global_menu_add_separator(const String &p_menu);
+ void global_menu_remove_item(const String &p_menu, int p_idx);
+ void global_menu_clear(const String &p_menu);
+
Point2 get_mouse_position() const;
void set_window_title(const String &p_title);
int get_mouse_button_state() const;
@@ -259,24 +264,6 @@ public:
bool is_scancode_unicode(uint32_t p_unicode) const;
int find_scancode_from_string(const String &p_code) const;
- /*
- struct Date {
-
- int year;
- Month month;
- int day;
- Weekday weekday;
- bool dst;
- };
-
- struct Time {
-
- int hour;
- int min;
- int sec;
- };
-*/
-
void set_use_file_access_save_and_swap(bool p_enable);
void set_native_icon(const String &p_filename);
@@ -404,6 +391,7 @@ public:
PoolVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
PoolVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
PoolVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
+ bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3 &p_vector);
@@ -420,17 +408,17 @@ public:
OPERATION_INTERSECTION,
OPERATION_XOR
};
- // 2D polygon boolean operations
- Array merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // union (add)
- Array clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // difference (subtract)
- Array intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // common area (multiply)
- Array exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // all but common area (xor)
+ // 2D polygon boolean operations.
+ Array merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Union (add).
+ Array clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Difference (subtract).
+ Array intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Common area (multiply).
+ Array exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // All but common area (xor).
- // 2D polyline vs polygon operations
- Array clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // cut
- Array intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // chop
+ // 2D polyline vs polygon operations.
+ Array clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Cut.
+ Array intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Chop.
- // 2D offset polygons/polylines
+ // 2D offset polygons/polylines.
enum PolyJoinType {
JOIN_SQUARE,
JOIN_ROUND,
@@ -446,8 +434,6 @@ public:
Array offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE);
Array offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, PolyEndType p_end_type = END_SQUARE);
- Vector<Point2> transform_points_2d(const Vector<Point2> &p_points, const Transform2D &p_mat);
-
Dictionary make_atlas(const Vector<Size2> &p_rects);
_Geometry();
@@ -486,24 +472,24 @@ public:
Error open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass);
Error open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ);
- Error open(const String &p_path, ModeFlags p_mode_flags); ///< open a file
- void close(); ///< close a file
- bool is_open() const; ///< true when file is open
+ Error open(const String &p_path, ModeFlags p_mode_flags); // open a file.
+ void close(); // Close a file.
+ bool is_open() const; // True when file is open.
- String get_path() const; /// returns the path for the current open file
- String get_path_absolute() const; /// returns the absolute path for the current open file
+ String get_path() const; // Returns the path for the current open file.
+ String get_path_absolute() const; // Returns the absolute path for the current open file.
- void seek(int64_t p_position); ///< seek to a given position
- void seek_end(int64_t p_position = 0); ///< seek from the end of file
- int64_t get_position() const; ///< get position in the file
- int64_t get_len() const; ///< get size of the file
+ void seek(int64_t p_position); // Seek to a given position.
+ void seek_end(int64_t p_position = 0); // Seek from the end of file.
+ int64_t get_position() const; // Get position in the file.
+ int64_t get_len() const; // Get size of the file.
- bool eof_reached() const; ///< reading passed EOF
+ bool eof_reached() const; // Reading passed EOF.
- uint8_t get_8() const; ///< get a byte
- uint16_t get_16() const; ///< get 16 bits uint
- uint32_t get_32() const; ///< get 32 bits uint
- uint64_t get_64() const; ///< get 64 bits uint
+ uint8_t get_8() const; // Get a byte.
+ uint16_t get_16() const; // Get 16 bits uint.
+ uint32_t get_32() const; // Get 32 bits uint.
+ uint64_t get_64() const; // Get 64 bits uint.
float get_float() const;
double get_double() const;
@@ -511,27 +497,27 @@ public:
Variant get_var(bool p_allow_objects = false) const;
- PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
+ PoolVector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes.
String get_line() const;
Vector<String> get_csv_line(const String &p_delim = ",") const;
String get_as_text() const;
String get_md5(const String &p_path) const;
String get_sha256(const String &p_path) const;
- /**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
+ /* Use this for files WRITTEN in _big_ endian machines (ie, amiga/mac).
* It's not about the current CPU type but file formats.
- * this flags get reset to false (little endian) on each open
+ * This flags get reset to false (little endian) on each open.
*/
void set_endian_swap(bool p_swap);
bool get_endian_swap();
- Error get_error() const; ///< get last error
+ Error get_error() const; // Get last error.
- void store_8(uint8_t p_dest); ///< store a byte
- void store_16(uint16_t p_dest); ///< store 16 bits uint
- void store_32(uint32_t p_dest); ///< store 32 bits uint
- void store_64(uint64_t p_dest); ///< store 64 bits uint
+ void store_8(uint8_t p_dest); // Store a byte.
+ void store_16(uint16_t p_dest); // Store 16 bits uint.
+ void store_32(uint32_t p_dest); // Store 32 bits uint.
+ void store_64(uint64_t p_dest); // Store 64 bits uint.
void store_float(float p_dest);
void store_double(double p_dest);
@@ -544,11 +530,11 @@ public:
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
- void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
+ void store_buffer(const PoolVector<uint8_t> &p_buffer); // Store an array of bytes.
void store_var(const Variant &p_var, bool p_full_objects = false);
- bool file_exists(const String &p_name) const; ///< return true if a file exists
+ bool file_exists(const String &p_name) const; // Return true if a file exists.
uint64_t get_modified_time(const String &p_file) const;
@@ -570,18 +556,18 @@ protected:
public:
Error open(const String &p_path);
- Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); ///< This starts dir listing
+ Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); // This starts dir listing.
String get_next();
bool current_is_dir() const;
- void list_dir_end(); ///<
+ void list_dir_end();
int get_drive_count();
String get_drive(int p_drive);
int get_current_drive();
- Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
- String get_current_dir(); ///< return current dir location
+ Error change_dir(String p_dir); // Can be relative or absolute, return false on success.
+ String get_current_dir(); // Return current dir location.
Error make_dir(String p_dir);
Error make_dir_recursive(String p_dir);
@@ -746,6 +732,7 @@ public:
void set_physics_jitter_fix(float p_threshold);
float get_physics_jitter_fix() const;
+ float get_physics_interpolation_fraction() const;
void set_target_fps(int p_fps);
int get_target_fps() const;
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 794d990083..3ad59bc309 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -480,6 +480,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
PropertySetGet *psg = t->property_setget.getptr(F->get());
+ ERR_FAIL_COND_V(!psg, 0);
hash = hash_djb2_one_64(F->get().hash(), hash);
hash = hash_djb2_one_64(psg->setter.hash(), hash);
@@ -835,10 +836,7 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
#ifdef DEBUG_METHODS_ENABLED
ClassInfo *check = type;
while (check) {
- if (check->signal_map.has(sname)) {
- ERR_EXPLAIN("Type " + String(p_class) + " already has signal: " + String(sname));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(check->signal_map.has(sname), "Type " + String(p_class) + " already has signal: " + String(sname) + ".");
check = check->inherits_ptr;
}
#endif
@@ -923,16 +921,11 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
if (p_setter) {
mb_set = get_method(p_class, p_setter);
#ifdef DEBUG_METHODS_ENABLED
- if (!mb_set) {
- ERR_EXPLAIN("Invalid Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name);
- ERR_FAIL();
- } else {
- int exp_args = 1 + (p_index >= 0 ? 1 : 0);
- if (mb_set->get_argument_count() != exp_args) {
- ERR_EXPLAIN("Invalid Function for Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name);
- ERR_FAIL();
- }
- }
+
+ ERR_FAIL_COND_MSG(!mb_set, "Invalid setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name + ".");
+
+ int exp_args = 1 + (p_index >= 0 ? 1 : 0);
+ ERR_FAIL_COND_MSG(mb_set->get_argument_count() != exp_args, "Invalid function for setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name + ".");
#endif
}
@@ -942,25 +935,15 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
mb_get = get_method(p_class, p_getter);
#ifdef DEBUG_METHODS_ENABLED
- if (!mb_get) {
- ERR_EXPLAIN("Invalid Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name);
- ERR_FAIL();
- } else {
+ ERR_FAIL_COND_MSG(!mb_get, "Invalid getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name + ".");
- int exp_args = 0 + (p_index >= 0 ? 1 : 0);
- if (mb_get->get_argument_count() != exp_args) {
- ERR_EXPLAIN("Invalid Function for Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name);
- ERR_FAIL();
- }
- }
+ int exp_args = 0 + (p_index >= 0 ? 1 : 0);
+ ERR_FAIL_COND_MSG(mb_get->get_argument_count() != exp_args, "Invalid function for getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name + ".");
#endif
}
#ifdef DEBUG_METHODS_ENABLED
- if (type->property_setget.has(p_pinfo.name)) {
- ERR_EXPLAIN("Object " + p_class + " already has property: " + p_pinfo.name);
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), "Object " + p_class + " already has property: " + p_pinfo.name + ".");
#endif
OBJTYPE_WLOCK
@@ -1239,32 +1222,26 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
#ifdef DEBUG_ENABLED
- if (has_method(instance_type, mdname)) {
- ERR_EXPLAIN("Class " + String(instance_type) + " already has a method " + String(mdname));
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(has_method(instance_type, mdname), NULL, "Class " + String(instance_type) + " already has a method " + String(mdname) + ".");
#endif
ClassInfo *type = classes.getptr(instance_type);
if (!type) {
- ERR_PRINTS("Couldn't bind method '" + mdname + "' for instance: " + instance_type);
memdelete(p_bind);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Couldn't bind method '" + mdname + "' for instance: " + instance_type + ".");
}
if (type->method_map.has(mdname)) {
memdelete(p_bind);
// overloading not supported
- ERR_EXPLAIN("Method already bound: " + instance_type + "::" + mdname);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Method already bound: " + instance_type + "::" + mdname + ".");
}
#ifdef DEBUG_METHODS_ENABLED
if (method_name.args.size() > p_bind->get_argument_count()) {
memdelete(p_bind);
- ERR_EXPLAIN("Method definition provides more arguments than the method actually has: " + instance_type + "::" + mdname);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Method definition provides more arguments than the method actually has: " + instance_type + "::" + mdname + ".");
}
p_bind->set_argument_names(method_name.args);
diff --git a/core/class_db.h b/core/class_db.h
index 3d9a695f02..092469beb7 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -35,10 +35,6 @@
#include "core/object.h"
#include "core/print_string.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/** To bind more then 6 parameters include this:
* #include "core/method_bind_ext.gen.inc"
*/
@@ -310,8 +306,7 @@ public:
if (type->method_map.has(p_name)) {
memdelete(bind);
// overloading not supported
- ERR_EXPLAIN("Method already bound: " + instance_type + "::" + p_name);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Method already bound: " + instance_type + "::" + p_name + ".");
}
type->method_map[p_name] = bind;
#ifdef DEBUG_METHODS_ENABLED
diff --git a/core/color.cpp b/core/color.cpp
index 1843532124..a54a3115cc 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -335,36 +335,23 @@ Color Color::html(const String &p_color) {
} else if (color.length() == 6) {
alpha = false;
} else {
- ERR_EXPLAIN("Invalid Color Code: " + p_color);
- ERR_FAIL_V(Color());
+ ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + ".");
}
int a = 255;
if (alpha) {
a = _parse_col(color, 0);
- if (a < 0) {
- ERR_EXPLAIN("Invalid Color Code: " + p_color);
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + ".");
}
int from = alpha ? 2 : 0;
int r = _parse_col(color, from + 0);
- if (r < 0) {
- ERR_EXPLAIN("Invalid Color Code: " + p_color);
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + ".");
int g = _parse_col(color, from + 2);
- if (g < 0) {
- ERR_EXPLAIN("Invalid Color Code: " + p_color);
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + ".");
int b = _parse_col(color, from + 4);
- if (b < 0) {
- ERR_EXPLAIN("Invalid Color Code: " + p_color);
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_color + ".");
return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
}
@@ -425,12 +412,8 @@ Color Color::named(const String &p_name) {
name = name.to_lower();
const Map<String, Color>::Element *color = _named_colors.find(name);
- if (color) {
- return color->value();
- } else {
- ERR_EXPLAIN("Invalid Color Name: " + p_name);
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_NULL_V_MSG(color, Color(), "Invalid color name: " + p_name + ".");
+ return color->value();
}
String _to_hex(float p_val) {
@@ -523,8 +506,7 @@ Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
// FIXME: Remove once Godot 3.1 has been released
float Color::gray() const {
- ERR_EXPLAIN("Color.gray() is deprecated and will be removed in a future version. Use Color.get_v() for a better grayscale approximation.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("Color.gray() is deprecated and will be removed in a future version. Use Color.get_v() for a better grayscale approximation.");
return (r + g + b) / 3.0;
}
diff --git a/core/color.h b/core/color.h
index 77f95b5dc9..8fb78d1ced 100644
--- a/core/color.h
+++ b/core/color.h
@@ -33,9 +33,7 @@
#include "core/math/math_funcs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
struct Color {
union {
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 3789eda5db..98f5bc56d7 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -37,10 +37,6 @@
#include "core/simple_type.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#define COMMA(N) _COMMA_##N
#define _COMMA_0
#define _COMMA_1 ,
diff --git a/core/crypto/SCsub b/core/crypto/SCsub
new file mode 100644
index 0000000000..0a3f05d87a
--- /dev/null
+++ b/core/crypto/SCsub
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env_crypto = env.Clone()
+
+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_crypto.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_crypto.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_crypto.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
new file mode 100644
index 0000000000..925a01b36a
--- /dev/null
+++ b/core/crypto/crypto.cpp
@@ -0,0 +1,170 @@
+/*************************************************************************/
+/* crypto.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.h"
+
+#include "core/engine.h"
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
+
+/// Resources
+
+CryptoKey *(*CryptoKey::_create)() = NULL;
+CryptoKey *CryptoKey::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void CryptoKey::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
+}
+
+X509Certificate *(*X509Certificate::_create)() = NULL;
+X509Certificate *X509Certificate::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void X509Certificate::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
+}
+
+/// Crypto
+
+void (*Crypto::_load_default_certificates)(String p_path) = NULL;
+Crypto *(*Crypto::_create)() = NULL;
+Crypto *Crypto::create() {
+ if (_create)
+ return _create();
+ return memnew(Crypto);
+}
+
+void Crypto::load_default_certificates(String p_path) {
+
+ if (_load_default_certificates)
+ _load_default_certificates(p_path);
+}
+
+void Crypto::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
+ ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa);
+ ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
+}
+
+PoolByteArray Crypto::generate_random_bytes(int p_bytes) {
+ ERR_FAIL_V_MSG(PoolByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
+}
+
+Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) {
+ ERR_FAIL_V_MSG(NULL, "generate_rsa is not available when mbedtls module is disabled.");
+}
+
+Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
+ ERR_FAIL_V_MSG(NULL, "generate_self_signed_certificate is not available when mbedtls module is disabled.");
+}
+
+Crypto::Crypto() {
+}
+
+/// Resource loader/saver
+
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "crt") {
+ X509Certificate *cert = X509Certificate::create();
+ if (cert)
+ cert->load(p_path);
+ return cert;
+ } else if (el == "key") {
+ CryptoKey *key = CryptoKey::create();
+ if (key)
+ key->load(p_path);
+ return key;
+ }
+ return NULL;
+}
+
+void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("crt");
+ p_extensions->push_back("key");
+}
+
+bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
+
+ return p_type == "X509Certificate" || p_type == "CryptoKey";
+}
+
+String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "crt")
+ return "X509Certificate";
+ else if (el == "key")
+ return "CryptoKey";
+ return "";
+}
+
+Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+
+ Error err;
+ Ref<X509Certificate> cert = p_resource;
+ Ref<CryptoKey> key = p_resource;
+ if (cert.is_valid()) {
+ err = cert->save(p_path);
+ } else if (key.is_valid()) {
+ err = key->save(p_path);
+ } else {
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ }
+ ERR_FAIL_COND_V(err != OK, err);
+ return OK;
+}
+
+void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+
+ const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
+ const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
+ if (cert) {
+ p_extensions->push_back("crt");
+ }
+ if (key) {
+ p_extensions->push_back("key");
+ }
+}
+bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
+
+ return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
+}
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
new file mode 100644
index 0000000000..2de81f5b57
--- /dev/null
+++ b/core/crypto/crypto.h
@@ -0,0 +1,105 @@
+/*************************************************************************/
+/* crypto.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_H
+#define CRYPTO_H
+
+#include "core/reference.h"
+#include "core/resource.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+
+class CryptoKey : public Resource {
+ GDCLASS(CryptoKey, Resource);
+
+protected:
+ static void _bind_methods();
+ static CryptoKey *(*_create)();
+
+public:
+ static CryptoKey *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class X509Certificate : public Resource {
+ GDCLASS(X509Certificate, Resource);
+
+protected:
+ static void _bind_methods();
+ static X509Certificate *(*_create)();
+
+public:
+ static X509Certificate *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class Crypto : public Reference {
+ GDCLASS(Crypto, Reference);
+
+protected:
+ static void _bind_methods();
+ static Crypto *(*_create)();
+ static void (*_load_default_certificates)(String p_path);
+
+public:
+ static Crypto *create();
+ static void load_default_certificates(String p_path);
+
+ virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual Ref<CryptoKey> generate_rsa(int p_bytes);
+ virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
+
+ Crypto();
+};
+
+class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
+
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverCrypto : public ResourceFormatSaver {
+ GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
+
+public:
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+ virtual bool recognize(const RES &p_resource) const;
+};
+
+#endif // CRYPTO_H
diff --git a/core/math/crypto_core.cpp b/core/crypto/crypto_core.cpp
index d7ba54e469..51c2e3c9e5 100644
--- a/core/math/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -52,7 +52,7 @@ Error CryptoCore::MD5Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::MD5Context::update(const 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;
}
@@ -62,6 +62,32 @@ Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
return ret ? FAILED : OK;
}
+// SHA1
+CryptoCore::SHA1Context::SHA1Context() {
+ ctx = memalloc(sizeof(mbedtls_sha1_context));
+ mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
+}
+
+CryptoCore::SHA1Context::~SHA1Context() {
+ mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
+ memfree((mbedtls_sha1_context *)ctx);
+}
+
+Error CryptoCore::SHA1Context::start() {
+ int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
+ int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
+ int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
+ return ret ? FAILED : OK;
+}
+
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
@@ -78,12 +104,12 @@ Error CryptoCore::SHA256Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::SHA256Context::update(const 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]) {
+Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
diff --git a/core/math/crypto_core.h b/core/crypto/crypto_core.h
index e28cb5a792..c859d612d4 100644
--- a/core/math/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -46,10 +46,24 @@ public:
~MD5Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
+ Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
+ class SHA1Context {
+
+ private:
+ void *ctx; // To include, or not to include...
+
+ public:
+ SHA1Context();
+ ~SHA1Context();
+
+ Error start();
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[20]);
+ };
+
class SHA256Context {
private:
@@ -60,8 +74,8 @@ public:
~SHA256Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
- Error finish(unsigned char r_hash[16]);
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[32]);
};
class AESContext {
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
new file mode 100644
index 0000000000..bd863f546b
--- /dev/null
+++ b/core/crypto/hashing_context.cpp
@@ -0,0 +1,137 @@
+/*************************************************************************/
+/* hashing_context.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 "hashing_context.h"
+
+#include "core/crypto/crypto_core.h"
+
+Error HashingContext::start(HashType p_type) {
+ ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
+ _create_ctx(p_type);
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNAVAILABLE);
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->start();
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->start();
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->start();
+ }
+ return ERR_UNAVAILABLE;
+}
+
+Error HashingContext::update(PoolByteArray p_chunk) {
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
+ size_t len = p_chunk.size();
+ PoolByteArray::Read r = p_chunk.read();
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
+ }
+ return ERR_UNAVAILABLE;
+}
+
+PoolByteArray HashingContext::finish() {
+ ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
+ PoolByteArray out;
+ Error err = FAILED;
+ switch (type) {
+ case HASH_MD5:
+ out.resize(16);
+ err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA1:
+ out.resize(20);
+ err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA256:
+ out.resize(32);
+ err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
+ break;
+ }
+ _delete_ctx();
+ ERR_FAIL_COND_V(err != OK, PoolByteArray());
+ return out;
+}
+
+void HashingContext::_create_ctx(HashType p_type) {
+ type = p_type;
+ switch (type) {
+ case HASH_MD5:
+ ctx = memnew(CryptoCore::MD5Context);
+ break;
+ case HASH_SHA1:
+ ctx = memnew(CryptoCore::SHA1Context);
+ break;
+ case HASH_SHA256:
+ ctx = memnew(CryptoCore::SHA256Context);
+ break;
+ default:
+ ctx = NULL;
+ }
+}
+
+void HashingContext::_delete_ctx() {
+
+ switch (type) {
+ case HASH_MD5:
+ memdelete((CryptoCore::MD5Context *)ctx);
+ break;
+ case HASH_SHA1:
+ memdelete((CryptoCore::SHA1Context *)ctx);
+ break;
+ case HASH_SHA256:
+ memdelete((CryptoCore::SHA256Context *)ctx);
+ break;
+ }
+ ctx = NULL;
+}
+
+void HashingContext::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
+ ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
+ ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
+ BIND_ENUM_CONSTANT(HASH_MD5);
+ BIND_ENUM_CONSTANT(HASH_SHA1);
+ BIND_ENUM_CONSTANT(HASH_SHA256);
+}
+
+HashingContext::HashingContext() {
+ ctx = NULL;
+}
+
+HashingContext::~HashingContext() {
+ if (ctx != NULL)
+ _delete_ctx();
+}
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
new file mode 100644
index 0000000000..aa69636f2c
--- /dev/null
+++ b/core/crypto/hashing_context.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* hashing_context.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 HASHING_CONTEXT_H
+#define HASHING_CONTEXT_H
+
+#include "core/reference.h"
+
+class HashingContext : public Reference {
+ GDCLASS(HashingContext, Reference);
+
+public:
+ enum HashType {
+ HASH_MD5,
+ HASH_SHA1,
+ HASH_SHA256
+ };
+
+private:
+ void *ctx;
+ HashType type;
+
+protected:
+ static void _bind_methods();
+ void _create_ctx(HashType p_type);
+ void _delete_ctx();
+
+public:
+ Error start(HashType p_type);
+ Error update(PoolByteArray p_chunk);
+ PoolByteArray finish();
+
+ HashingContext();
+ ~HashingContext();
+};
+
+VARIANT_ENUM_CAST(HashingContext::HashType);
+
+#endif // HASHING_CONTEXT_H
diff --git a/core/engine.cpp b/core/engine.cpp
index 2d8473fbd9..937439faaf 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -197,10 +197,7 @@ void Engine::add_singleton(const Singleton &p_singleton) {
Object *Engine::get_singleton_object(const String &p_name) const {
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
- if (!E) {
- ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!E, NULL, "Failed to retrieve non-existent singleton '" + p_name + "'.");
return E->get();
};
@@ -227,6 +224,7 @@ Engine::Engine() {
frames_drawn = 0;
ips = 60;
physics_jitter_fix = 0.5;
+ _physics_interpolation_fraction = 0.0f;
_frame_delay = 0;
_fps = 1;
_target_fps = 0;
diff --git a/core/engine.h b/core/engine.h
index 15665fee29..192e8e67a0 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -63,6 +63,7 @@ private:
float _time_scale;
bool _pixel_snap;
uint64_t _physics_frames;
+ float _physics_interpolation_fraction;
uint64_t _idle_frames;
bool _in_physics;
@@ -95,6 +96,7 @@ public:
bool is_in_physics_frame() const { return _in_physics; }
uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
float get_idle_frame_step() const { return _frame_step; }
+ float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
void set_time_scale(float p_scale);
float get_time_scale() const;
diff --git a/core/error_macros.h b/core/error_macros.h
index 69874e280b..65802de9d2 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -140,6 +140,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
+#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
+ do { \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+ return; \
+ } \
+ _err_error_exists = false; \
+ } while (0); // (*)
+
/** An index has failed if m_index<0 or m_index >=m_size, the function exits.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
@@ -154,6 +164,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
+#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
+ do { \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+ return m_retval; \
+ } \
+ _err_error_exists = false; \
+ } while (0); // (*)
+
/** An index has failed if m_index >=m_size, the function exits.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
@@ -168,6 +188,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
+#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
+ do { \
+ if (unlikely((m_index) >= (m_size))) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+ return m_retval; \
+ } \
+ _err_error_exists = false; \
+ } while (0); // (*)
+
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
* We'll return a null reference and try to keep running.
*/
@@ -179,6 +209,15 @@ extern bool _err_error_exists;
} \
} while (0); // (*)
+#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
+ do { \
+ if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), true); \
+ GENERATE_TRAP \
+ } \
+ } while (0); // (*)
+
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
@@ -192,6 +231,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_FAIL_NULL_MSG(m_param, m_msg) \
+ { \
+ if (unlikely(!m_param)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
+ return; \
+ } \
+ _err_error_exists = false; \
+ }
+
#define ERR_FAIL_NULL_V(m_param, m_retval) \
{ \
if (unlikely(!m_param)) { \
@@ -201,6 +250,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
+ { \
+ if (unlikely(!m_param)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
+ return m_retval; \
+ } \
+ _err_error_exists = false; \
+ }
+
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
@@ -214,6 +273,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_FAIL_COND_MSG(m_cond, m_msg) \
+ { \
+ if (unlikely(m_cond)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \
+ return; \
+ } \
+ _err_error_exists = false; \
+ }
+
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
*/
@@ -225,6 +294,15 @@ extern bool _err_error_exists;
} \
}
+#define CRASH_COND_MSG(m_cond, m_msg) \
+ { \
+ if (unlikely(m_cond)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \
+ GENERATE_TRAP \
+ } \
+ }
+
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
* This function returns an error value, if returning Error, please select the most
@@ -240,6 +318,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
+ { \
+ if (unlikely(m_cond)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. returned: " _STR(m_retval)); \
+ return m_retval; \
+ } \
+ _err_error_exists = false; \
+ }
+
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration.
*/
@@ -253,6 +341,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_CONTINUE_MSG(m_cond, m_msg) \
+ { \
+ if (unlikely(m_cond)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \
+ continue; \
+ } \
+ _err_error_exists = false; \
+ }
+
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break
*/
@@ -266,6 +364,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_BREAK_MSG(m_cond, m_msg) \
+ { \
+ if (unlikely(m_cond)) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
+ break; \
+ } \
+ _err_error_exists = false; \
+ }
+
/** Print an error string and return
*/
@@ -276,6 +384,12 @@ extern bool _err_error_exists;
return; \
}
+#define ERR_FAIL_MSG(m_msg) \
+ { \
+ ERR_EXPLAIN(m_msg); \
+ ERR_FAIL(); \
+ }
+
/** Print an error string and return with value
*/
@@ -286,6 +400,12 @@ extern bool _err_error_exists;
return m_value; \
}
+#define ERR_FAIL_V_MSG(m_value, m_msg) \
+ { \
+ ERR_EXPLAIN(m_msg); \
+ ERR_FAIL_V(m_value); \
+ }
+
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
*/
@@ -295,6 +415,12 @@ extern bool _err_error_exists;
GENERATE_TRAP \
}
+#define CRASH_NOW_MSG(m_msg) \
+ { \
+ ERR_EXPLAIN(m_msg); \
+ CRASH_NOW(); \
+ }
+
/** Print an error string.
*/
@@ -355,4 +481,15 @@ extern bool _err_error_exists;
} \
}
+#define WARN_DEPRECATED_MSG(m_msg) \
+ { \
+ static volatile bool warning_shown = false; \
+ if (!warning_shown) { \
+ ERR_EXPLAIN(m_msg); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future", ERR_HANDLER_WARNING); \
+ _err_error_exists = false; \
+ warning_shown = true; \
+ } \
+ }
+
#endif
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index 3d03137d09..66ef27f6b9 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -46,6 +46,17 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::Call
return obj->call(function, p_args, p_argcount, r_error);
}
+Variant FuncRef::call_funcv(const Array &p_args) {
+
+ ERR_FAIL_COND_V(id == 0, Variant());
+
+ Object *obj = ObjectDB::get_instance(id);
+
+ ERR_FAIL_COND_V(!obj, Variant());
+
+ return obj->callv(function, p_args);
+}
+
void FuncRef::set_instance(Object *p_obj) {
ERR_FAIL_NULL(p_obj);
@@ -77,6 +88,8 @@ void FuncRef::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs);
}
+ ClassDB::bind_method(D_METHOD("call_funcv", "arg_array"), &FuncRef::call_funcv);
+
ClassDB::bind_method(D_METHOD("set_instance", "instance"), &FuncRef::set_instance);
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
diff --git a/core/func_ref.h b/core/func_ref.h
index a143b58bf0..af0bf63203 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -44,6 +44,7 @@ protected:
public:
Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant call_funcv(const Array &p_args);
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
bool is_valid() const;
diff --git a/core/hash_map.h b/core/hash_map.h
index 1513d7a65b..81ddc376d0 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -151,11 +151,7 @@ private:
return;
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
- if (!new_hash_table) {
-
- ERR_PRINT("Out of Memory");
- return;
- }
+ ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory.");
for (int i = 0; i < (1 << new_hash_table_power); i++) {
@@ -208,10 +204,7 @@ private:
/* if element doesn't exist, create it */
Element *e = memnew(Element);
- if (!e) {
- ERR_EXPLAIN("Out of memory");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!e, NULL, "Out of memory.");
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
e->next = hash_table[index];
@@ -498,10 +491,7 @@ public:
} else { /* get the next key */
const Element *e = get_element(*p_key);
- if (!e) {
- ERR_EXPLAIN("Invalid key supplied")
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!e, NULL, "Invalid key supplied.");
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
diff --git a/core/image.cpp b/core/image.cpp
index a88395204a..900efb0eb0 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -83,6 +83,7 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
};
SavePNGFunc Image::save_png_func = NULL;
+SaveEXRFunc Image::save_exr_func = NULL;
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
@@ -240,27 +241,27 @@ int Image::get_format_block_size(Format p_format) {
case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1:
return 4;
- } break;
+ }
case FORMAT_PVRTC2:
case FORMAT_PVRTC2A: {
return 4;
- } break;
+ }
case FORMAT_PVRTC4A:
case FORMAT_PVRTC4: {
return 4;
- } break;
+ }
case FORMAT_ETC: {
return 4;
- } break;
+ }
case FORMAT_BPTC_RGBA:
case FORMAT_BPTC_RGBF:
case FORMAT_BPTC_RGBFU: {
return 4;
- } break;
+ }
case FORMAT_ETC2_R11: //etc2
case FORMAT_ETC2_R11S: //signed: NOT srgb.
case FORMAT_ETC2_RG11:
@@ -270,7 +271,7 @@ int Image::get_format_block_size(Format p_format) {
case FORMAT_ETC2_RGB8A1: {
return 4;
- } break;
+ }
default: {
}
}
@@ -422,8 +423,7 @@ void Image::convert(Format p_new_format) {
if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
- ERR_EXPLAIN("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
} else if (format > FORMAT_RGBA8 || p_new_format > FORMAT_RGBA8) {
@@ -753,15 +753,14 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (int32_t buffer_x = 0; buffer_x < dst_width; buffer_x++) {
- float src_real_x = buffer_x * x_scale;
- int32_t src_x = src_real_x;
-
- int32_t start_x = MAX(0, src_x - half_kernel + 1);
- int32_t end_x = MIN(src_width - 1, src_x + half_kernel);
+ // The corresponding point on the source image
+ float src_x = (buffer_x + 0.5f) * x_scale; // Offset by 0.5 so it uses the pixel's center
+ int32_t start_x = MAX(0, int32_t(src_x) - half_kernel + 1);
+ int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel);
// Create the kernel used by all the pixels of the column
for (int32_t target_x = start_x; target_x <= end_x; target_x++)
- kernel[target_x - start_x] = _lanczos((src_real_x - target_x) / scale_factor);
+ kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor);
for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) {
@@ -804,14 +803,12 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (int32_t dst_y = 0; dst_y < dst_height; dst_y++) {
- float buffer_real_y = dst_y * y_scale;
- int32_t buffer_y = buffer_real_y;
-
- int32_t start_y = MAX(0, buffer_y - half_kernel + 1);
- int32_t end_y = MIN(src_height - 1, buffer_y + half_kernel);
+ float buffer_y = (dst_y + 0.5f) * y_scale;
+ int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1);
+ int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel);
for (int32_t target_y = start_y; target_y <= end_y; target_y++)
- kernel[target_y - start_y] = _lanczos((buffer_real_y - target_y) / scale_factor);
+ kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor);
for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) {
@@ -852,7 +849,7 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, float p_alpha, uint32_t p_width, uint32_t p_height, uint32_t p_pixel_size) {
- uint16_t alpha = CLAMP((uint16_t)(p_alpha * 256.0f), 0, 256);
+ uint16_t alpha = MIN((uint16_t)(p_alpha * 256.0f), 256);
for (uint32_t i = 0; i < p_width * p_height * p_pixel_size; i++) {
@@ -866,10 +863,7 @@ bool Image::is_size_po2() const {
void Image::resize_to_po2(bool p_square) {
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot resize in indexed, compressed or custom image formats.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
int w = next_power_of_2(width);
int h = next_power_of_2(height);
@@ -885,15 +879,9 @@ void Image::resize_to_po2(bool p_square) {
void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
- if (data.size() == 0) {
- ERR_EXPLAIN("Cannot resize image before creating it, use create() or create_from_data() first.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use create() or create_from_data() first.");
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot resize in indexed, compressed or custom image formats.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */;
@@ -1106,10 +1094,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot crop in compressed or custom image formats.");
+
ERR_FAIL_COND(p_x < 0);
ERR_FAIL_COND(p_y < 0);
ERR_FAIL_COND(p_width <= 0);
@@ -1163,10 +1149,7 @@ void Image::crop(int p_width, int p_height) {
void Image::flip_y() {
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
bool used_mipmaps = has_mipmaps();
if (used_mipmaps) {
@@ -1199,10 +1182,7 @@ void Image::flip_y() {
void Image::flip_x() {
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot flip_x in indexed, compressed or custom image formats.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats.");
bool used_mipmaps = has_mipmaps();
if (used_mipmaps) {
@@ -1461,15 +1441,9 @@ void Image::normalize() {
Error Image::generate_mipmaps(bool p_renormalize) {
- if (!_can_modify(format)) {
- ERR_EXPLAIN("Cannot generate mipmaps in indexed, compressed or custom image formats.");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats.");
- if (width == 0 || height == 0) {
- ERR_EXPLAIN("Cannot generate mipmaps with width or height equal to 0.");
- ERR_FAIL_V(ERR_UNCONFIGURED);
- }
+ ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0.");
int mmcount;
@@ -1620,10 +1594,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
int mm;
int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
- if (size != p_data.size()) {
- ERR_EXPLAIN("Expected data size of " + itos(size) + " bytes in Image::create(), got instead " + itos(p_data.size()) + " bytes.");
- ERR_FAIL_COND(p_data.size() != size);
- }
+ ERR_FAIL_COND_MSG(p_data.size() != size, "Expected data size of " + itos(size) + " bytes in Image::create(), got instead " + itos(p_data.size()) + " bytes.");
height = p_height;
width = p_width;
@@ -1917,6 +1888,14 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
+Error Image::save_exr(const String &p_path, bool p_grayscale) const {
+
+ if (save_exr_func == NULL)
+ return ERR_UNAVAILABLE;
+
+ return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
+}
+
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
int mm;
@@ -2405,10 +2384,7 @@ Color Image::get_pixel(int p_x, int p_y) const {
uint8_t *ptr = write_lock.ptr();
#ifdef DEBUG_ENABLED
- if (!ptr) {
- ERR_EXPLAIN("Image must be locked with 'lock()' before using get_pixel()");
- ERR_FAIL_V(Color());
- }
+ ERR_FAIL_COND_V_MSG(!ptr, Color(), "Image must be locked with 'lock()' before using get_pixel().");
ERR_FAIL_INDEX_V(p_x, width, Color());
ERR_FAIL_INDEX_V(p_y, height, Color());
@@ -2421,38 +2397,36 @@ Color Image::get_pixel(int p_x, int p_y) const {
case FORMAT_L8: {
float l = ptr[ofs] / 255.0;
return Color(l, l, l, 1);
- } break;
+ }
case FORMAT_LA8: {
float l = ptr[ofs * 2 + 0] / 255.0;
float a = ptr[ofs * 2 + 1] / 255.0;
return Color(l, l, l, a);
- } break;
+ }
case FORMAT_R8: {
float r = ptr[ofs] / 255.0;
return Color(r, 0, 0, 1);
- } break;
+ }
case FORMAT_RG8: {
float r = ptr[ofs * 2 + 0] / 255.0;
float g = ptr[ofs * 2 + 1] / 255.0;
return Color(r, g, 0, 1);
- } break;
+ }
case FORMAT_RGB8: {
float r = ptr[ofs * 3 + 0] / 255.0;
float g = ptr[ofs * 3 + 1] / 255.0;
float b = ptr[ofs * 3 + 2] / 255.0;
return Color(r, g, b, 1);
-
- } break;
+ }
case FORMAT_RGBA8: {
float r = ptr[ofs * 4 + 0] / 255.0;
float g = ptr[ofs * 4 + 1] / 255.0;
float b = ptr[ofs * 4 + 2] / 255.0;
float a = ptr[ofs * 4 + 3] / 255.0;
return Color(r, g, b, a);
-
- } break;
+ }
case FORMAT_RGBA4444: {
uint16_t u = ((uint16_t *)ptr)[ofs];
float r = (u & 0xF) / 15.0;
@@ -2460,8 +2434,7 @@ Color Image::get_pixel(int p_x, int p_y) const {
float b = ((u >> 8) & 0xF) / 15.0;
float a = ((u >> 12) & 0xF) / 15.0;
return Color(r, g, b, a);
-
- } break;
+ }
case FORMAT_RGBA5551: {
uint16_t u = ((uint16_t *)ptr)[ofs];
@@ -2470,25 +2443,25 @@ Color Image::get_pixel(int p_x, int p_y) const {
float b = ((u >> 10) & 0x1F) / 15.0;
float a = ((u >> 15) & 0x1) / 1.0;
return Color(r, g, b, a);
- } break;
+ }
case FORMAT_RF: {
float r = ((float *)ptr)[ofs];
return Color(r, 0, 0, 1);
- } break;
+ }
case FORMAT_RGF: {
float r = ((float *)ptr)[ofs * 2 + 0];
float g = ((float *)ptr)[ofs * 2 + 1];
return Color(r, g, 0, 1);
- } break;
+ }
case FORMAT_RGBF: {
float r = ((float *)ptr)[ofs * 3 + 0];
float g = ((float *)ptr)[ofs * 3 + 1];
float b = ((float *)ptr)[ofs * 3 + 2];
return Color(r, g, b, 1);
- } break;
+ }
case FORMAT_RGBAF: {
float r = ((float *)ptr)[ofs * 4 + 0];
@@ -2496,25 +2469,25 @@ Color Image::get_pixel(int p_x, int p_y) const {
float b = ((float *)ptr)[ofs * 4 + 2];
float a = ((float *)ptr)[ofs * 4 + 3];
return Color(r, g, b, a);
- } break;
+ }
case FORMAT_RH: {
uint16_t r = ((uint16_t *)ptr)[ofs];
return Color(Math::half_to_float(r), 0, 0, 1);
- } break;
+ }
case FORMAT_RGH: {
uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0];
uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1];
return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1);
- } break;
+ }
case FORMAT_RGBH: {
uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0];
uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1];
uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2];
return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1);
- } break;
+ }
case FORMAT_RGBAH: {
uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0];
@@ -2522,18 +2495,14 @@ Color Image::get_pixel(int p_x, int p_y) const {
uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2];
uint16_t a = ((uint16_t *)ptr)[ofs * 4 + 3];
return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a));
- } break;
+ }
case FORMAT_RGBE9995: {
return Color::from_rgbe9995(((uint32_t *)ptr)[ofs]);
-
- } break;
+ }
default: {
- ERR_EXPLAIN("Can't get_pixel() on compressed image, sorry.");
- ERR_FAIL_V(Color());
+ ERR_FAIL_V_MSG(Color(), "Can't get_pixel() on compressed image, sorry.");
}
}
-
- return Color();
}
void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) {
@@ -2544,10 +2513,7 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
uint8_t *ptr = write_lock.ptr();
#ifdef DEBUG_ENABLED
- if (!ptr) {
- ERR_EXPLAIN("Image must be locked with 'lock()' before using set_pixel()");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!ptr, "Image must be locked with 'lock()' before using set_pixel().");
ERR_FAIL_INDEX(p_x, width);
ERR_FAIL_INDEX(p_y, height);
@@ -2659,8 +2625,7 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
} break;
default: {
- ERR_EXPLAIN("Can't set_pixel() on compressed image, sorry.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Can't set_pixel() on compressed image, sorry.");
}
}
}
@@ -2752,6 +2717,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+ ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
diff --git a/core/image.h b/core/image.h
index cc796789cd..f29a30cda0 100644
--- a/core/image.h
+++ b/core/image.h
@@ -49,11 +49,14 @@ class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
+typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
+
class Image : public Resource {
GDCLASS(Image, Resource);
public:
static SavePNGFunc save_png_func;
+ static SaveEXRFunc save_exr_func;
enum {
MAX_WIDTH = 16384, // force a limit somehow
@@ -217,9 +220,7 @@ public:
/**
* Resize the image, using the preferred interpolation method.
- * Indexed-Color images always use INTERPOLATE_NEAREST.
*/
-
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
@@ -258,6 +259,7 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ Error save_exr(const String &p_path, bool p_grayscale) const;
/**
* create an empty image
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 04911787a8..2a8ac435fe 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -192,17 +192,14 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength) const {
Map<StringName, Action>::Element *E = input_map.find(p_action);
- if (!E) {
- ERR_EXPLAIN("Request for nonexistent InputMap action: " + String(p_action));
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action: " + String(p_action) + ".");
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
if (p_pressed != NULL)
*p_pressed = input_event_action->is_pressed();
if (p_strength != NULL)
- *p_strength = (*p_pressed) ? input_event_action->get_strength() : 0.0f;
+ *p_strength = (p_pressed != NULL && *p_pressed) ? input_event_action->get_strength() : 0.0f;
return input_event_action->get_action() == p_action;
}
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index f7fb72c089..9063e028be 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -86,10 +86,7 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
if (!values.has(p_section) || !values[p_section].has(p_key)) {
- if (p_default.get_type() == Variant::NIL) {
- ERR_EXPLAIN("Couldn't find the given section/key and no default was given");
- ERR_FAIL_V(p_default);
- }
+ ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, p_default, "Couldn't find the given section/key and no default was given.");
return p_default;
}
return values[p_section][p_key];
@@ -204,7 +201,7 @@ Error ConfigFile::load(const String &p_path) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f)
- return ERR_CANT_OPEN;
+ return err;
return _internal_load(p_path, f);
}
@@ -271,7 +268,7 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
memdelete(f);
return OK;
} else if (err != OK) {
- ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
+ ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text + ".");
memdelete(f);
return err;
}
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index 15523a49a9..f72ad61da6 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -87,10 +87,8 @@ bool FileAccessBuffered::eof_reached() const {
}
uint8_t FileAccessBuffered::get_8() const {
- if (!file.open) {
- ERR_EXPLAIN("Can't get data, when file is not opened.");
- ERR_FAIL_V(0);
- }
+
+ ERR_FAIL_COND_V_MSG(!file.open, 0, "Can't get data, when file is not opened.");
uint8_t byte = 0;
if (cache_data_left() >= 1) {
@@ -104,10 +102,8 @@ uint8_t FileAccessBuffered::get_8() const {
}
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
- if (!file.open) {
- ERR_EXPLAIN("Can't get buffer, when file is not opened.");
- ERR_FAIL_V(-1);
- }
+
+ ERR_FAIL_COND_V_MSG(!file.open, -1, "Can't get buffer, when file is not opened.");
if (p_length > cache_size) {
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index 6e806e7b3f..c8cee04208 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -40,10 +40,7 @@ class FileAccessBufferedFA : public FileAccessBuffered {
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
- if (!f.is_open()) {
- ERR_EXPLAIN("Can't read data block, when file is not opened.");
- ERR_FAIL_V(-1);
- }
+ ERR_FAIL_COND_V_MSG(!f.is_open(), -1, "Can't read data block when file is not opened.");
((T *)&f)->seek(p_offset);
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 6c4310a572..102cd9cf6c 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -208,7 +208,8 @@ void FileAccessCompressed::seek(size_t p_position) {
if (p_position == read_total) {
at_end = true;
} else {
-
+ at_end = false;
+ read_eof = false;
int block_idx = p_position / block_size;
if (block_idx != read_block) {
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index ccee6aeb15..0eef0ee79f 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -30,7 +30,7 @@
#include "file_access_encrypted.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/os/copymem.h"
#include "core/print_string.h"
#include "core/variant.h"
@@ -94,8 +94,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
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(hash) != String::md5(md5d), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V_MSG(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT, "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.");
file = p_base;
}
@@ -177,6 +176,22 @@ bool FileAccessEncrypted::is_open() const {
return file != NULL;
}
+String FileAccessEncrypted::get_path() const {
+
+ if (file)
+ return file->get_path();
+ else
+ return "";
+}
+
+String FileAccessEncrypted::get_path_absolute() const {
+
+ if (file)
+ return file->get_path_absolute();
+ else
+ return "";
+}
+
void FileAccessEncrypted::seek(size_t p_position) {
if (p_position > (size_t)data.size())
@@ -298,7 +313,7 @@ uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
}
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
- ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet");
+ ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
return ERR_UNAVAILABLE;
}
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index d779a150ac..c3be0f7de8 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -60,6 +60,9 @@ public:
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
+ virtual String get_path() const; /// returns the path for the current open file
+ virtual String get_path_absolute() const; /// returns the absolute path for the current open file
+
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_position() const; ///< get position in the file
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index ca66b34e17..d49d36c2b9 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -90,7 +90,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
}
String filename = path.get_file();
- // Don't add as a file if the path points to a directoryy
+ // Don't add as a file if the path points to a directory
if (!filename.empty()) {
cd->files.insert(filename);
}
@@ -171,10 +171,8 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) {
uint32_t ver_minor = f->get_32();
f->get_32(); // ver_rev
- ERR_EXPLAIN("Pack version unsupported: " + itos(version));
- ERR_FAIL_COND_V(version != PACK_VERSION, false);
- ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor));
- ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false);
+ ERR_FAIL_COND_V_MSG(version != PACK_VERSION, false, "Pack version unsupported: " + itos(version) + ".");
+ ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
for (int i = 0; i < 16; i++) {
//reserved
@@ -322,10 +320,9 @@ bool FileAccessPack::file_exists(const String &p_name) {
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
pf(p_file),
f(FileAccess::open(pf.pack, FileAccess::READ)) {
- if (!f) {
- ERR_EXPLAIN("Can't open pack-referenced file: " + String(pf.pack));
- ERR_FAIL_COND(!f);
- }
+
+ ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file: " + String(pf.pack) + ".");
+
f->seek(pf.offset);
pos = 0;
eof = false;
@@ -463,11 +460,15 @@ String DirAccessPack::get_current_dir() {
bool DirAccessPack::file_exists(String p_file) {
+ p_file = fix_path(p_file);
+
return current->files.has(p_file);
}
bool DirAccessPack::dir_exists(String p_dir) {
+ p_dir = fix_path(p_dir);
+
return current->subdirs.has(p_dir);
}
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index be28c9a877..abc0bd064d 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -194,7 +194,7 @@ bool ZipArchive::try_open_pack(const String &p_path) {
packages.push_back(pkg);
int pkg_num = packages.size() - 1;
- for (unsigned int i = 0; i < gi.number_entry; i++) {
+ for (uint64_t i = 0; i < gi.number_entry; i++) {
char filename_inzip[256];
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index ae4b72a534..af6b0551a3 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -37,24 +37,8 @@
#include "core/os/file_access.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-/**
- * @class ImageScanLineLoader
- * @author Juan Linietsky <reduzio@gmail.com>
- *
-
- */
class ImageLoader;
-/**
- * @class ImageLoader
- * Base Class and singleton for loading images from disk
- * Can load images in one go, or by scanline
- */
-
class ImageFormatLoader {
friend class ImageLoader;
friend class ResourceFormatLoaderImage;
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index 9305afac5f..df4be9b9fd 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -81,8 +81,7 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
} else if (c == ':') {
break;
} else {
- ERR_EXPLAIN("Invalid character in ipv6 address: " + p_string);
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid character in IPv6 address: " + p_string + ".");
};
ret = ret << 4;
ret += n;
@@ -126,9 +125,7 @@ void IP_Address::_parse_ipv6(const String &p_string) {
++parts_count;
};
} else {
-
- ERR_EXPLAIN("Invalid character in IPv6 address: " + p_string);
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid character in IPv6 address: " + p_string + ".");
};
};
@@ -166,10 +163,7 @@ void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret
};
int slices = ip.get_slice_count(".");
- if (slices != 4) {
- ERR_EXPLAIN("Invalid IP Address String: " + ip);
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(slices != 4, "Invalid IP address string: " + ip + ".");
for (int i = 0; i < 4; i++) {
p_ret[i] = ip.get_slicec('.', i).to_int();
}
@@ -229,7 +223,7 @@ IP_Address::IP_Address(const String &p_string) {
valid = true;
} else {
- ERR_PRINT("Invalid IP address");
+ ERR_PRINT("Invalid IP address.");
}
}
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index dc5581ea01..b386feb14c 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -377,11 +377,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
} break;
- /*case Variant::RESOURCE: {
-
- ERR_EXPLAIN("Can't marshallize resources");
- ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go
- } break;*/
case Variant::_RID: {
r_variant = RID();
@@ -1066,11 +1061,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 * 4;
} break;
- /*case Variant::RESOURCE: {
-
- ERR_EXPLAIN("Can't marshallize resources");
- ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go
- } break;*/
case Variant::_RID: {
} break;
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 33dc4dbde4..ed6905c9a6 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -33,6 +33,10 @@
#include "core/io/marshalls.h"
#include "scene/main/node.h"
+#ifdef DEBUG_ENABLED
+#include "core/os/os.h"
+#endif
+
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
switch (mode) {
@@ -146,8 +150,7 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee
network_peer = p_peer;
- ERR_EXPLAIN("Supplied NetworkedNetworkPeer must be connecting or connected.");
- ERR_FAIL_COND(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED);
+ ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, "Supplied NetworkedNetworkPeer must be connecting or connected.");
if (network_peer.is_valid()) {
network_peer->connect("peer_connected", this, "_add_peer");
@@ -164,10 +167,16 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_EXPLAIN("Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it");
- ERR_FAIL_COND(root_node == NULL);
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_packet_len < 1);
+ ERR_FAIL_COND_MSG(root_node == NULL, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it.");
+ ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small.");
+
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ bandwidth_incoming_data.write[bandwidth_incoming_pointer].timestamp = OS::get_singleton()->get_ticks_msec();
+ bandwidth_incoming_data.write[bandwidth_incoming_pointer].packet_size = p_packet_len;
+ bandwidth_incoming_pointer = (bandwidth_incoming_pointer + 1) % bandwidth_incoming_data.size();
+ }
+#endif
uint8_t packet_type = p_packet[0];
@@ -186,13 +195,11 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
case NETWORK_COMMAND_REMOTE_CALL:
case NETWORK_COMMAND_REMOTE_SET: {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_packet_len < 6);
+ ERR_FAIL_COND_MSG(p_packet_len < 6, "Invalid packet received. Size too small.");
Node *node = _process_get_node(p_from, p_packet, p_packet_len);
- ERR_EXPLAIN("Invalid packet received. Requested node was not found.");
- ERR_FAIL_COND(node == NULL);
+ ERR_FAIL_COND_MSG(node == NULL, "Invalid packet received. Requested node was not found.");
// Detect cstring end.
int len_end = 5;
@@ -202,8 +209,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
}
}
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(len_end >= p_packet_len);
+ ERR_FAIL_COND_MSG(len_end >= p_packet_len, "Invalid packet received. Size too small.");
StringName name = String::utf8((const char *)&p_packet[5]);
@@ -235,8 +241,7 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
int ofs = target & 0x7FFFFFFF;
- ERR_EXPLAIN("Invalid packet received. Size smaller than declared.");
- ERR_FAIL_COND_V(ofs >= p_packet_len, NULL);
+ ERR_FAIL_COND_V_MSG(ofs >= p_packet_len, NULL, "Invalid packet received. Size smaller than declared.");
String paths;
paths.parse_utf8((const char *)&p_packet[ofs], p_packet_len - ofs);
@@ -246,33 +251,30 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
node = root_node->get_node(np);
if (!node)
- ERR_PRINTS("Failed to get path from RPC: " + String(np));
+ ERR_PRINTS("Failed to get path from RPC: " + String(np) + ".");
} else {
// Use cached path.
int id = target;
Map<int, PathGetCache>::Element *E = path_get_cache.find(p_from);
- ERR_EXPLAIN("Invalid packet received. Requests invalid peer cache.");
- ERR_FAIL_COND_V(!E, NULL);
+ ERR_FAIL_COND_V_MSG(!E, NULL, "Invalid packet received. Requests invalid peer cache.");
Map<int, PathGetCache::NodeInfo>::Element *F = E->get().nodes.find(id);
- ERR_EXPLAIN("Invalid packet received. Unabled to find requested cached node.");
- ERR_FAIL_COND_V(!F, NULL);
+ ERR_FAIL_COND_V_MSG(!F, NULL, "Invalid packet received. Unabled to find requested cached node.");
PathGetCache::NodeInfo *ni = &F->get();
// Do proper caching later.
node = root_node->get_node(ni->path);
if (!node)
- ERR_PRINTS("Failed to get cached path from RPC: " + String(ni->path));
+ ERR_PRINTS("Failed to get cached path from RPC: " + String(ni->path) + ".");
}
return node;
}
void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_offset >= p_packet_len);
+ ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RPC on this node.
RPCMode rpc_mode = RPC_MODE_DISABLED;
@@ -284,8 +286,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
}
bool can_call = _can_call_mode(p_node, rpc_mode, p_from);
- ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
- ERR_FAIL_COND(!can_call);
+ ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
int argc = p_packet[p_offset];
Vector<Variant> args;
@@ -295,15 +296,21 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
p_offset++;
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].incoming_rpc += 1;
+ }
+#endif
+
for (int i = 0; i < argc; i++) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_offset >= p_packet_len);
+ ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
int vlen;
Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen, allow_object_decoding || network_peer->is_object_decoding_allowed());
- ERR_EXPLAIN("Invalid packet received. Unable to decode RPC argument.");
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument.");
argp.write[i] = &args[i];
p_offset += vlen;
@@ -321,8 +328,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_offset >= p_packet_len);
+ ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RSET on this node.
RPCMode rset_mode = RPC_MODE_DISABLED;
@@ -334,28 +340,33 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
}
bool can_call = _can_call_mode(p_node, rset_mode, p_from);
- ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
- ERR_FAIL_COND(!can_call);
+ ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
+
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].incoming_rset += 1;
+ }
+#endif
Variant value;
Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed());
- ERR_EXPLAIN("Invalid packet received. Unable to decode RSET value.");
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RSET value.");
bool valid;
p_node->set(p_name, value, &valid);
if (!valid) {
- String error = "Error setting remote property '" + String(p_name) + "', not found in object of type " + p_node->get_class();
+ String error = "Error setting remote property '" + String(p_name) + "', not found in object of type " + p_node->get_class() + ".";
ERR_PRINTS(error);
}
}
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_packet_len < 5);
+ ERR_FAIL_COND_MSG(p_packet_len < 5, "Invalid packet received. Size too small.");
int id = decode_uint32(&p_packet[1]);
String paths;
@@ -390,8 +401,7 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_packet_len < 2);
+ ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
String paths;
paths.parse_utf8((const char *)&p_packet[1], p_packet_len - 1);
@@ -399,12 +409,10 @@ void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet,
NodePath path = paths;
PathSentCache *psc = path_send_cache.getptr(path);
- ERR_EXPLAIN("Invalid packet received. Tries to confirm a path which was not found in cache.");
- ERR_FAIL_COND(!psc);
+ ERR_FAIL_COND_MSG(!psc, "Invalid packet received. Tries to confirm a path which was not found in cache.");
Map<int, bool>::Element *E = psc->confirmed_peers.find(p_from);
- ERR_EXPLAIN("Invalid packet received. Source peer was not found in cache for the given path.");
- ERR_FAIL_COND(!E);
+ ERR_FAIL_COND_MSG(!E, "Invalid packet received. Source peer was not found in cache for the given path.");
E->get() = true;
}
@@ -460,39 +468,22 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {
- if (network_peer.is_null()) {
- ERR_EXPLAIN("Attempt to remote call/set when networking is not active in SceneTree.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
- if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING) {
- ERR_EXPLAIN("Attempt to remote call/set when networking is not connected yet in SceneTree.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
- if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
- ERR_EXPLAIN("Attempt to remote call/set when networking is disconnected.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, "Attempt to remote call/set when networking is disconnected.");
- if (p_argcount > 255) {
- ERR_EXPLAIN("Too many arguments >255.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments >255.");
if (p_to != 0 && !connected_peers.has(ABS(p_to))) {
- if (p_to == network_peer->get_unique_id()) {
- ERR_EXPLAIN("Attempt to remote call/set yourself! unique ID: " + itos(network_peer->get_unique_id()));
- } else {
- ERR_EXPLAIN("Attempt to remote call unexisting ID: " + itos(p_to));
- }
+ ERR_FAIL_COND_MSG(p_to == network_peer->get_unique_id(), "Attempt to remote call/set yourself! unique ID: " + itos(network_peer->get_unique_id()) + ".");
- ERR_FAIL();
+ ERR_FAIL_MSG("Attempt to remote call unexisting ID: " + itos(p_to) + ".");
}
NodePath from_path = (root_node->get_path()).rel_path_to(p_from->get_path());
- ERR_EXPLAIN("Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
- ERR_FAIL_COND(from_path.is_empty());
+ ERR_FAIL_COND_MSG(from_path.is_empty(), "Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
// See if the path is cached.
PathSentCache *psc = path_send_cache.getptr(from_path);
@@ -530,8 +521,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
if (p_set) {
// Set argument.
Error err = encode_variant(*p_arg[0], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
- ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
ofs += len;
@@ -543,14 +533,21 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
Error err = encode_variant(*p_arg[i], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
- ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
MAKE_ROOM(ofs + len);
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
ofs += len;
}
}
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ bandwidth_outgoing_data.write[bandwidth_outgoing_pointer].timestamp = OS::get_singleton()->get_ticks_msec();
+ bandwidth_outgoing_data.write[bandwidth_outgoing_pointer].packet_size = ofs;
+ bandwidth_outgoing_pointer = (bandwidth_outgoing_pointer + 1) % bandwidth_outgoing_data.size();
+ }
+#endif
+
// See if all peers have cached path (is so, call can be fast).
bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
@@ -626,12 +623,9 @@ void MultiplayerAPI::_server_disconnected() {
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
- ERR_EXPLAIN("Trying to call an RPC while no network peer is active.");
- ERR_FAIL_COND(!network_peer.is_valid());
- ERR_EXPLAIN("Trying to call an RPC on a node which is not inside SceneTree.");
- ERR_FAIL_COND(!p_node->is_inside_tree());
- ERR_EXPLAIN("Trying to call an RPC via a network peer which is not connected.");
- ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
+ ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to call an RPC while no network peer is active.");
+ ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree.");
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
int node_id = network_peer->get_unique_id();
bool skip_rpc = node_id == p_peer_id;
@@ -657,6 +651,15 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (!skip_rpc) {
+
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].outgoing_rpc += 1;
+ }
+#endif
+
_send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
}
@@ -668,7 +671,7 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
rpc_sender_id = temp_id;
if (ce.error != Variant::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
- error = "rpc() aborted in local call: - " + error;
+ error = "rpc() aborted in local call: - " + error + ".";
ERR_PRINTS(error);
return;
}
@@ -683,24 +686,20 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
rpc_sender_id = temp_id;
if (ce.error != Variant::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
- error = "rpc() aborted in script local call: - " + error;
+ error = "rpc() aborted in script local call: - " + error + ".";
ERR_PRINTS(error);
return;
}
}
- ERR_EXPLAIN("RPC '" + p_method + "' on yourself is not allowed by selected mode");
- ERR_FAIL_COND(skip_rpc && !(call_local_native || call_local_script));
+ ERR_FAIL_COND_MSG(skip_rpc && !(call_local_native || call_local_script), "RPC '" + p_method + "' on yourself is not allowed by selected mode.");
}
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
- ERR_EXPLAIN("Trying to RSET while no network peer is active.");
- ERR_FAIL_COND(!network_peer.is_valid());
- ERR_EXPLAIN("Trying to RSET on a node which is not inside SceneTree.");
- ERR_FAIL_COND(!p_node->is_inside_tree());
- ERR_EXPLAIN("Trying to send an RSET via a network peer which is not connected.");
- ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
+ ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to RSET while no network peer is active.");
+ ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to RSET on a node which is not inside SceneTree.");
+ ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to send an RSET via a network peer which is not connected.");
int node_id = network_peer->get_unique_id();
bool is_master = p_node->is_network_master();
@@ -724,7 +723,7 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
rpc_sender_id = temp_id;
if (!valid) {
- String error = "rset() aborted in local set, property not found: - " + String(p_property);
+ String error = "rset() aborted in local set, property not found: - " + String(p_property) + ".";
ERR_PRINTS(error);
return;
}
@@ -742,7 +741,7 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
rpc_sender_id = temp_id;
if (!valid) {
- String error = "rset() aborted in local script set, property not found: - " + String(p_property);
+ String error = "rset() aborted in local script set, property not found: - " + String(p_property) + ".";
ERR_PRINTS(error);
return;
}
@@ -751,11 +750,18 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (skip_rset) {
- ERR_EXPLAIN("RSET for '" + p_property + "' on yourself is not allowed by selected mode");
- ERR_FAIL_COND(!set_local);
+ ERR_FAIL_COND_MSG(!set_local, "RSET for '" + p_property + "' on yourself is not allowed by selected mode.");
return;
}
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].outgoing_rset += 1;
+ }
+#endif
+
const Variant *vptr = &p_value;
_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
@@ -763,12 +769,9 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
- ERR_EXPLAIN("Trying to send an empty raw packet.");
- ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
- ERR_EXPLAIN("Trying to send a raw packet while no network peer is active.");
- ERR_FAIL_COND_V(!network_peer.is_valid(), ERR_UNCONFIGURED);
- ERR_EXPLAIN("Trying to send a raw packet via a network peer which is not connected.");
- ERR_FAIL_COND_V(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet.");
+ ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active.");
+ ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
MAKE_ROOM(p_data.size() + 1);
PoolVector<uint8_t>::Read r = p_data.read();
@@ -783,8 +786,7 @@ Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, Networked
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_EXPLAIN("Invalid packet received. Size too small.");
- ERR_FAIL_COND(p_packet_len < 2);
+ ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
PoolVector<uint8_t> out;
int len = p_packet_len - 1;
@@ -798,37 +800,32 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
int MultiplayerAPI::get_network_unique_id() const {
- ERR_EXPLAIN("No network peer is assigned. Unable to get unique network ID.");
- ERR_FAIL_COND_V(!network_peer.is_valid(), 0);
+ ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), 0, "No network peer is assigned. Unable to get unique network ID.");
return network_peer->get_unique_id();
}
bool MultiplayerAPI::is_network_server() const {
// XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
- ERR_EXPLAIN("No network peer is assigned. I can't be a server.");
- ERR_FAIL_COND_V(!network_peer.is_valid(), false);
+ ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. I can't be a server.");
return network_peer->is_server();
}
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
- ERR_EXPLAIN("No network peer is assigned. Unable to set 'refuse_new_connections'.");
- ERR_FAIL_COND(!network_peer.is_valid());
+ ERR_FAIL_COND_MSG(!network_peer.is_valid(), "No network peer is assigned. Unable to set 'refuse_new_connections'.");
network_peer->set_refuse_new_connections(p_refuse);
}
bool MultiplayerAPI::is_refusing_new_network_connections() const {
- ERR_EXPLAIN("No network peer is assigned. Unable to get 'refuse_new_connections'.");
- ERR_FAIL_COND_V(!network_peer.is_valid(), false);
+ ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. Unable to get 'refuse_new_connections'.");
return network_peer->is_refusing_new_connections();
}
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
- ERR_EXPLAIN("No network peer is assigned. Assume no peers are connected.");
- ERR_FAIL_COND_V(!network_peer.is_valid(), Vector<int>());
+ ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), Vector<int>(), "No network peer is assigned. Assume no peers are connected.");
Vector<int> ret;
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
@@ -848,6 +845,96 @@ bool MultiplayerAPI::is_object_decoding_allowed() const {
return allow_object_decoding;
}
+void MultiplayerAPI::profiling_start() {
+#ifdef DEBUG_ENABLED
+ profiling = true;
+ profiler_frame_data.clear();
+
+ bandwidth_incoming_pointer = 0;
+ bandwidth_incoming_data.resize(16384); // ~128kB
+ for (int i = 0; i < bandwidth_incoming_data.size(); ++i) {
+ bandwidth_incoming_data.write[i].packet_size = -1;
+ }
+
+ bandwidth_outgoing_pointer = 0;
+ bandwidth_outgoing_data.resize(16384); // ~128kB
+ for (int i = 0; i < bandwidth_outgoing_data.size(); ++i) {
+ bandwidth_outgoing_data.write[i].packet_size = -1;
+ }
+#endif
+}
+
+void MultiplayerAPI::profiling_end() {
+#ifdef DEBUG_ENABLED
+ profiling = false;
+ bandwidth_incoming_data.clear();
+ bandwidth_outgoing_data.clear();
+#endif
+}
+
+int MultiplayerAPI::get_profiling_frame(ProfilingInfo *r_info) {
+ int i = 0;
+#ifdef DEBUG_ENABLED
+ for (Map<ObjectID, ProfilingInfo>::Element *E = profiler_frame_data.front(); E; E = E->next()) {
+ r_info[i] = E->get();
+ ++i;
+ }
+ profiler_frame_data.clear();
+#endif
+ return i;
+}
+
+int MultiplayerAPI::get_incoming_bandwidth_usage() {
+#ifdef DEBUG_ENABLED
+ return _get_bandwidth_usage(bandwidth_incoming_data, bandwidth_incoming_pointer);
+#else
+ return 0;
+#endif
+}
+
+int MultiplayerAPI::get_outgoing_bandwidth_usage() {
+#ifdef DEBUG_ENABLED
+ return _get_bandwidth_usage(bandwidth_outgoing_data, bandwidth_outgoing_pointer);
+#else
+ return 0;
+#endif
+}
+
+#ifdef DEBUG_ENABLED
+int MultiplayerAPI::_get_bandwidth_usage(const Vector<BandwidthFrame> &p_buffer, int p_pointer) {
+ int total_bandwidth = 0;
+
+ uint32_t timestamp = OS::get_singleton()->get_ticks_msec();
+ uint32_t final_timestamp = timestamp - 1000;
+
+ int i = (p_pointer + p_buffer.size() - 1) % p_buffer.size();
+
+ while (i != p_pointer && p_buffer[i].packet_size > 0) {
+ if (p_buffer[i].timestamp < final_timestamp) {
+ return total_bandwidth;
+ }
+ total_bandwidth += p_buffer[i].packet_size;
+ i = (i + p_buffer.size() - 1) % p_buffer.size();
+ }
+
+ ERR_EXPLAIN("Reached the end of the bandwidth profiler buffer, values might be inaccurate.");
+ ERR_FAIL_COND_V(i == p_pointer, total_bandwidth);
+ return total_bandwidth;
+}
+
+void MultiplayerAPI::_init_node_profile(ObjectID p_node) {
+ if (profiler_frame_data.has(p_node))
+ return;
+ profiler_frame_data.insert(p_node, ProfilingInfo());
+ profiler_frame_data[p_node].node = p_node;
+ profiler_frame_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();
+ profiler_frame_data[p_node].incoming_rpc = 0;
+ profiler_frame_data[p_node].incoming_rset = 0;
+ profiler_frame_data[p_node].outgoing_rpc = 0;
+ profiler_frame_data[p_node].outgoing_rset = 0;
+}
+#endif
+
void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
@@ -898,6 +985,9 @@ MultiplayerAPI::MultiplayerAPI() :
allow_object_decoding(false) {
rpc_sender_id = 0;
root_node = NULL;
+#ifdef DEBUG_ENABLED
+ profiling = false;
+#endif
clear();
}
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index 5258dde5d7..b824456e0f 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -38,6 +38,16 @@ class MultiplayerAPI : public Reference {
GDCLASS(MultiplayerAPI, Reference);
+public:
+ struct ProfilingInfo {
+ ObjectID node;
+ String node_path;
+ int incoming_rpc;
+ int incoming_rset;
+ int outgoing_rpc;
+ int outgoing_rset;
+ };
+
private:
//path sent caches
struct PathSentCache {
@@ -55,6 +65,23 @@ private:
Map<int, NodeInfo> nodes;
};
+#ifdef DEBUG_ENABLED
+ struct BandwidthFrame {
+ uint32_t timestamp;
+ int packet_size;
+ };
+
+ int bandwidth_incoming_pointer;
+ Vector<BandwidthFrame> bandwidth_incoming_data;
+ int bandwidth_outgoing_pointer;
+ Vector<BandwidthFrame> bandwidth_outgoing_data;
+ Map<ObjectID, ProfilingInfo> profiler_frame_data;
+ bool profiling;
+
+ void _init_node_profile(ObjectID p_node);
+ int _get_bandwidth_usage(const Vector<BandwidthFrame> &p_buffer, int p_pointer);
+#endif
+
Ref<NetworkedMultiplayerPeer> network_peer;
int rpc_sender_id;
Set<int> connected_peers;
@@ -130,6 +157,13 @@ public:
void set_allow_object_decoding(bool p_enable);
bool is_object_decoding_allowed() const;
+ void profiling_start();
+ void profiling_end();
+
+ int get_profiling_frame(ProfilingInfo *r_info);
+ int get_incoming_bandwidth_usage();
+ int get_outgoing_bandwidth_usage();
+
MultiplayerAPI();
~MultiplayerAPI();
};
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index c77c81f9e2..1c792c43d1 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -110,10 +110,11 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
Variant var;
- get_var(var, p_allow_objects);
+ Error err = get_var(var, p_allow_objects);
+ ERR_FAIL_COND_V(err != OK, Variant());
return var;
-};
+}
Error PacketPeer::_put_packet(const PoolVector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
@@ -279,8 +280,7 @@ Ref<StreamPeer> PacketPeerStream::get_stream_peer() const {
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
//warning may lose packets
- ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
- ERR_FAIL_COND(ring_buffer.data_left());
+ ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
ring_buffer.resize(nearest_shift(p_max_size + 4));
input_buffer.resize(next_power_of_2(p_max_size + 4));
}
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index c16d89d695..1c89bc6268 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -64,10 +64,7 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file = FileAccess::open(p_file, FileAccess::WRITE);
- if (!file) {
- ERR_EXPLAIN("Can't open file to write: " + String(p_file));
- ERR_FAIL_V(ERR_CANT_CREATE);
- }
+ ERR_FAIL_COND_V_MSG(!file, ERR_CANT_CREATE, "Can't open file to write: " + String(p_file) + ".");
alignment = p_alignment;
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 861e34e415..0ad2479b05 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -490,8 +490,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
#endif
} else {
- ERR_EXPLAIN("Vector2 size is NOT 8!");
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector2 size is NOT 8!");
}
w.release();
r_v = array;
@@ -518,8 +517,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
#endif
} else {
- ERR_EXPLAIN("Vector3 size is NOT 12!");
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector3 size is NOT 12!");
}
w.release();
r_v = array;
@@ -546,8 +544,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
#endif
} else {
- ERR_EXPLAIN("Color size is NOT 16!");
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Color size is NOT 16!");
}
w.release();
r_v = array;
@@ -571,7 +568,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
const uint32_t current_version = 0;
if (format_version > current_version) {
- ERR_PRINT("Format version for encoded binary image is too new");
+ ERR_PRINT("Format version for encoded binary image is too new.");
return ERR_PARSE_ERROR;
}
@@ -655,8 +652,7 @@ Error ResourceInteractiveLoaderBinary::poll() {
} else {
error = ERR_FILE_MISSING_DEPENDENCIES;
- ERR_EXPLAIN("Can't load dependency: " + path);
- ERR_FAIL_V(error);
+ ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
}
} else {
@@ -711,16 +707,15 @@ Error ResourceInteractiveLoaderBinary::poll() {
Object *obj = ClassDB::instance(t);
if (!obj) {
error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN(local_path + ":Resource of unrecognized type in file: " + t);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
}
- ERR_FAIL_COND_V(!obj, ERR_FILE_CORRUPT);
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
+ String obj_class = obj->get_class();
error = ERR_FILE_CORRUPT;
memdelete(obj); //bye
- ERR_EXPLAIN(local_path + ":Resource type in resource field not a resource, type is: " + obj->get_class());
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
}
RES res = RES(r);
@@ -850,8 +845,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
//not normal
error = ERR_FILE_UNRECOGNIZED;
- ERR_EXPLAIN("Unrecognized binary resource file: " + local_path);
- ERR_FAIL();
+ ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + ".");
}
bool big_endian = f->get_32();
@@ -877,8 +871,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
f->close();
- ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
- ERR_FAIL();
+ ERR_FAIL_MSG("File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + ".");
}
type = get_unicode_string();
@@ -926,8 +919,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
if (f->eof_reached()) {
error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN("Premature End Of File: " + local_path);
- ERR_FAIL();
+ ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + ".");
}
}
@@ -1084,8 +1076,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
//error=ERR_FILE_UNRECOGNIZED;
memdelete(f);
- ERR_EXPLAIN("Unrecognized binary resource file: " + local_path);
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file: " + local_path + ".");
} else {
fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE);
if (!fw) {
@@ -1122,7 +1113,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
memdelete(da);
//use the old approach
- WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: " + p_path).utf8().get_data());
+ WARN_PRINTS("This file is old, so it can't refactor dependencies, opening and resaving: " + p_path + ".");
Error err;
f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -1153,8 +1144,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
memdelete(f);
memdelete(fw);
- ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path);
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + ".");
}
// Since we're not actually converting the file contents, leave the version
@@ -1477,7 +1467,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
case Variant::_RID: {
f->store_32(VARIANT_RID);
- WARN_PRINT("Can't save RIDs");
+ WARN_PRINT("Can't save RIDs.");
RID val = p_property;
f->store_32(val.get_id());
} break;
@@ -1497,8 +1487,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
if (!resource_set.has(res)) {
f->store_32(OBJECT_EMPTY);
- ERR_EXPLAIN("Resource was not pre cached for the resource section, most likely due to circular refedence.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Resource was not pre cached for the resource section, most likely due to circular reference.");
}
f->store_32(OBJECT_INTERNAL_RESOURCE);
@@ -1629,8 +1618,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
default: {
- ERR_EXPLAIN("Invalid variant");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid variant.");
}
}
}
@@ -1798,6 +1786,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
f->close();
+ memdelete(f);
return ERR_CANT_CREATE;
}
@@ -1950,10 +1939,12 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if (f->get_error() != OK && f->get_error() != ERR_FILE_EOF) {
f->close();
+ memdelete(f);
return ERR_CANT_CREATE;
}
f->close();
+ memdelete(f);
return OK;
}
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index a29b9d1ddb..9e954890bc 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -275,12 +275,9 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
return res;
}
- if (found) {
- ERR_EXPLAIN("Failed loading resource: " + p_path);
- } else {
- ERR_EXPLAIN("No loader found for resource: " + p_path);
- }
- ERR_FAIL_V(RES());
+ ERR_FAIL_COND_V_MSG(found, RES(), "Failed loading resource: " + p_path + ".");
+
+ ERR_FAIL_V_MSG(RES(), "No loader found for resource: " + p_path + ".");
}
bool ResourceLoader::_add_to_loading_map(const String &p_path) {
@@ -355,10 +352,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
{
bool success = _add_to_loading_map(local_path);
- if (!success) {
- ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
- ERR_FAIL_V(RES());
- }
+ ERR_FAIL_COND_V_MSG(!success, RES(), "Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
}
//lock first if possible
@@ -395,8 +389,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
if (!p_no_cache) {
_remove_from_loading_map(local_path);
}
- ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
}
print_verbose("Loading resource: " + path);
@@ -479,10 +472,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (!p_no_cache) {
bool success = _add_to_loading_map(local_path);
- if (!success) {
- ERR_EXPLAIN("Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
- ERR_FAIL_V(RES());
- }
+ ERR_FAIL_COND_V_MSG(!success, RES(), "Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
if (ResourceCache::has(local_path)) {
@@ -503,8 +493,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (!p_no_cache) {
_remove_from_loading_map(local_path);
}
- ERR_EXPLAIN("Remapping '" + local_path + "'failed.");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
}
print_verbose("Loading resource: " + path);
@@ -534,12 +523,9 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
_remove_from_loading_map(local_path);
}
- if (found) {
- ERR_EXPLAIN("Failed loading resource: " + path);
- } else {
- ERR_EXPLAIN("No loader found for resource: " + path);
- }
- ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
+ ERR_FAIL_COND_V_MSG(found, Ref<ResourceInteractiveLoader>(), "Failed loading resource: " + path + ".");
+
+ ERR_FAIL_V_MSG(Ref<ResourceInteractiveLoader>(), "No loader found for resource: " + path + ".");
}
void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
@@ -801,7 +787,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
if (err == ERR_FILE_EOF) {
break;
} else if (err != OK) {
- ERR_PRINTS("Parse error: " + p_path + ".remap:" + itos(lines) + " error: " + error_text);
+ ERR_PRINTS("Parse error: " + p_path + ".remap:" + itos(lines) + " error: " + error_text + ".");
break;
}
@@ -932,16 +918,13 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
Ref<Script> s = res;
StringName ibt = s->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatLoader");
- ERR_EXPLAIN("Script does not inherit a CustomResourceLoader: " + script_path);
- ERR_FAIL_COND_V(!valid_type, false);
+ ERR_FAIL_COND_V_MSG(!valid_type, false, "Script does not inherit a CustomResourceLoader: " + script_path + ".");
Object *obj = ClassDB::instance(ibt);
- ERR_EXPLAIN("Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt));
- ERR_FAIL_COND_V(obj == NULL, false);
+ ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource loader, expected 'ResourceFormatLoader' inheritance, got: " + String(ibt) + ".");
- ResourceFormatLoader *crl = NULL;
- crl = Object::cast_to<ResourceFormatLoader>(obj);
+ ResourceFormatLoader *crl = Object::cast_to<ResourceFormatLoader>(obj);
crl->set_script(s.get_ref_ptr());
ResourceLoader::add_resource_format_loader(crl);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 70e7bdc224..93df8cadb0 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -33,9 +33,6 @@
#include "core/os/thread.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ResourceInteractiveLoader : public Reference {
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 0cecca904d..a9ad62afe6 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -137,7 +137,6 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
save_callback(p_resource, p_path);
return OK;
- } else {
}
}
@@ -215,16 +214,13 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
Ref<Script> s = res;
StringName ibt = s->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "ResourceFormatSaver");
- ERR_EXPLAIN("Script does not inherit a CustomResourceSaver: " + script_path);
- ERR_FAIL_COND_V(!valid_type, false);
+ ERR_FAIL_COND_V_MSG(!valid_type, false, "Script does not inherit a CustomResourceSaver: " + script_path + ".");
Object *obj = ClassDB::instance(ibt);
- ERR_EXPLAIN("Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt));
- ERR_FAIL_COND_V(obj == NULL, false);
+ ERR_FAIL_COND_V_MSG(obj == NULL, false, "Cannot instance script as custom resource saver, expected 'ResourceFormatSaver' inheritance, got: " + String(ibt) + ".");
- ResourceFormatSaver *crl = NULL;
- crl = Object::cast_to<ResourceFormatSaver>(obj);
+ ResourceFormatSaver *crl = Object::cast_to<ResourceFormatSaver>(obj);
crl->set_script(s.get_ref_ptr());
ResourceSaver::add_resource_format_saver(crl);
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 0fba47a5e8..20e05d827a 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -33,10 +33,6 @@
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ResourceFormatSaver : public Reference {
GDCLASS(ResourceFormatSaver, Reference);
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index acf72dbba5..84b8554d54 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -369,7 +369,9 @@ Variant StreamPeer::get_var(bool p_allow_objects) {
ERR_FAIL_COND_V(err != OK, Variant());
Variant ret;
- decode_variant(ret, var.ptr(), len, NULL, p_allow_objects);
+ err = decode_variant(ret, var.ptr(), len, NULL, p_allow_objects);
+ ERR_FAIL_COND_V(err != OK, Variant());
+
return ret;
}
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index ccce48ccd7..f2eaf57acc 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -30,10 +30,7 @@
#include "stream_peer_ssl.h"
-#include "core/io/certs_compressed.gen.h"
-#include "core/io/compression.h"
-#include "core/os/file_access.h"
-#include "core/project_settings.h"
+#include "core/engine.h"
StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL;
@@ -44,22 +41,8 @@ StreamPeerSSL *StreamPeerSSL::create() {
return NULL;
}
-StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
-void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
- if (load_certs_func)
- load_certs_func(p_memory);
-}
-
-void StreamPeerSSL::load_certs_from_file(String p_path) {
- if (p_path != "") {
- PoolByteArray certs = get_cert_file_as_array(p_path);
- if (certs.size() > 0)
- load_certs_func(certs);
- }
-}
-
bool StreamPeerSSL::is_available() {
return available;
}
@@ -72,56 +55,11 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake;
}
-PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
-
- PoolByteArray out;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (f) {
- int flen = f->get_len();
- out.resize(flen + 1);
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; // Make sure it ends with string terminator
- memdelete(f);
-#ifdef DEBUG_ENABLED
- print_verbose(vformat("Loaded certs from '%s'.", p_path));
-#endif
- }
-
- return out;
-}
-
-PoolByteArray StreamPeerSSL::get_project_cert_array() {
-
- PoolByteArray out;
- String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
-
- if (certs_path != "") {
- // Use certs defined in project settings.
- return get_cert_file_as_array(certs_path);
- }
-#ifdef BUILTIN_CERTS_ENABLED
- else {
- // Use builtin certs only if user did not override it in project settings.
- out.resize(_certs_uncompressed_size + 1);
- PoolByteArray::Write w = out.write();
- Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
- w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
-#ifdef DEBUG_ENABLED
- print_verbose("Loaded builtin certs");
-#endif
- }
-#endif
-
- return out;
-}
-
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream", "base"), &StreamPeerSSL::accept_stream);
- ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("accept_stream", "stream", "private_key", "certificate", "chain"), &StreamPeerSSL::accept_stream, DEFVAL(Ref<X509Certificate>()));
+ ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname", "valid_certificate"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
ClassDB::bind_method(D_METHOD("set_blocking_handshake_enabled", "enabled"), &StreamPeerSSL::set_blocking_handshake_enabled);
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 482576c4c6..dedc35b9ac 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -31,19 +31,16 @@
#ifndef STREAM_PEER_SSL_H
#define STREAM_PEER_SSL_H
+#include "core/crypto/crypto.h"
#include "core/io/stream_peer.h"
class StreamPeerSSL : public StreamPeer {
GDCLASS(StreamPeerSSL, StreamPeer);
-public:
- typedef void (*LoadCertsFromMemory)(const PoolByteArray &p_certs);
-
protected:
static StreamPeerSSL *(*_create)();
static void _bind_methods();
- static LoadCertsFromMemory load_certs_func;
static bool available;
bool blocking_handshake;
@@ -61,18 +58,14 @@ public:
bool is_blocking_handshake_enabled() const;
virtual void poll() = 0;
- virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
- virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
+ virtual Error accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
+ virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref<X509Certificate> p_valid_cert = Ref<X509Certificate>()) = 0;
virtual Status get_status() const = 0;
virtual void disconnect_from_stream() = 0;
static StreamPeerSSL *create();
- static PoolByteArray get_cert_file_as_array(String p_path);
- static PoolByteArray get_project_cert_array();
- static void load_certs_from_file(String p_path);
- static void load_certs_from_memory(const PoolByteArray &p_memory);
static bool is_available();
StreamPeerSSL();
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 67a0a905bd..e8e71c10ca 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -67,8 +67,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
if (status == STATUS_READING_ID) {
memdelete(f);
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), p_path + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
} else {
break;
}
@@ -79,8 +78,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
if (status == STATUS_READING_ID) {
memdelete(f);
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), p_path + ":" + itos(line) + " Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
}
if (msg_id != "") {
@@ -102,8 +100,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
if (status != STATUS_READING_ID) {
memdelete(f);
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), p_path + ":" + itos(line) + " Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
}
l = l.substr(6, l.length()).strip_edges();
@@ -118,11 +115,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
continue; //nothing to read or comment
}
- if (!l.begins_with("\"") || status == STATUS_NONE) {
- //not a string? failure!
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");
- ERR_FAIL_V(RES());
- }
+ ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, RES(), p_path + ":" + itos(line) + " Invalid line '" + l + "' while parsing: ");
l = l.substr(1, l.length());
//find final quote
@@ -135,10 +128,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
}
}
- if (end_pos == -1) {
- ERR_EXPLAIN(p_path + ":" + itos(line) + " Expected '\"' at end of message while parsing file: ");
- ERR_FAIL_V(RES());
- }
+ ERR_FAIL_COND_V_MSG(end_pos == -1, RES(), p_path + ":" + itos(line) + " Expected '\"' at end of message while parsing file: ");
l = l.substr(0, end_pos);
l = l.c_unescape();
@@ -163,10 +153,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
config = msg_str;
}
- if (config == "") {
- ERR_EXPLAIN("No config found in file: " + p_path);
- ERR_FAIL_V(RES());
- }
+ ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + p_path + ".");
Vector<String> configs = config.split("\n");
for (int i = 0; i < configs.size(); i++) {
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 82527d3f38..9487947365 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -443,10 +443,8 @@ String XMLParser::get_attribute_value(const String &p_name) const {
}
}
- if (idx < 0) {
- ERR_EXPLAIN("Attribute not found: " + p_name);
- }
- ERR_FAIL_COND_V(idx < 0, "");
+ ERR_FAIL_COND_V_MSG(idx < 0, "", "Attribute not found: " + p_name + ".");
+
return attributes[idx].value;
}
diff --git a/core/make_binders.py b/core/make_binders.py
index 24901c42a1..c38db5cef4 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -334,9 +334,6 @@ def make_version(template, nargs, argmax, const, ret):
elif (cmd == "noarg"):
for i in range(nargs + 1, argmax + 1):
outtext += data.replace("@", str(i))
- elif (cmd == "noarg"):
- for i in range(nargs + 1, argmax + 1):
- outtext += data.replace("@", str(i))
from_pos = end + 1
diff --git a/core/map.h b/core/map.h
index a701ba36f7..c87ee42e1b 100644
--- a/core/map.h
+++ b/core/map.h
@@ -33,12 +33,8 @@
#include "core/set.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
// based on the very nice implementation of rb-trees by:
-// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
diff --git a/core/math/SCsub b/core/math/SCsub
index 0995298a4b..be438fcfbe 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -2,37 +2,6 @@
Import('env')
-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 = env.Clone()
env_math.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index b61119d8df..60b7326c29 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -40,7 +40,17 @@ int AStar::get_available_point_id() const {
return 1;
}
- return points.back()->key() + 1;
+ // calculate our new next available point id if bigger than before or next id already contained in set of points.
+ if (points.has(last_free_id)) {
+ int cur_new_id = last_free_id;
+ while (points.has(cur_new_id)) {
+ cur_new_id++;
+ }
+ int &non_const = const_cast<int &>(last_free_id);
+ non_const = cur_new_id;
+ }
+
+ return last_free_id;
}
void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
@@ -48,7 +58,10 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
ERR_FAIL_COND(p_id < 0);
ERR_FAIL_COND(p_weight_scale < 1);
- if (!points.has(p_id)) {
+ Point *found_pt;
+ bool p_exists = points.lookup(p_id, found_pt);
+
+ if (!p_exists) {
Point *pt = memnew(Point);
pt->id = p_id;
pt->pos = p_pos;
@@ -57,84 +70,98 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
pt->open_pass = 0;
pt->closed_pass = 0;
pt->enabled = true;
- points[p_id] = pt;
+ points.set(p_id, pt);
} else {
- points[p_id]->pos = p_pos;
- points[p_id]->weight_scale = p_weight_scale;
+ found_pt->pos = p_pos;
+ found_pt->weight_scale = p_weight_scale;
}
}
Vector3 AStar::get_point_position(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), Vector3());
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, Vector3());
- return points[p_id]->pos;
+ return p->pos;
}
void AStar::set_point_position(int p_id, const Vector3 &p_pos) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- points[p_id]->pos = p_pos;
+ p->pos = p_pos;
}
real_t AStar::get_point_weight_scale(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), 0);
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, 0);
- return points[p_id]->weight_scale;
+ return p->weight_scale;
}
void AStar::set_point_weight_scale(int p_id, real_t p_weight_scale) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
ERR_FAIL_COND(p_weight_scale < 1);
- points[p_id]->weight_scale = p_weight_scale;
+ p->weight_scale = p_weight_scale;
}
void AStar::remove_point(int p_id) {
- ERR_FAIL_COND(!points.has(p_id));
-
- Point *p = points[p_id];
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
- Segment s(p_id, E->get()->id);
+ Segment s(p_id, (*it.key));
segments.erase(s);
- E->get()->neighbours.erase(p);
- E->get()->unlinked_neighbours.erase(p);
+ (*it.value)->neighbours.remove(p->id);
+ (*it.value)->unlinked_neighbours.remove(p->id);
}
- for (Set<Point *>::Element *E = p->unlinked_neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) {
- Segment s(p_id, E->get()->id);
+ Segment s(p_id, (*it.key));
segments.erase(s);
- E->get()->neighbours.erase(p);
- E->get()->unlinked_neighbours.erase(p);
+ (*it.value)->neighbours.remove(p->id);
+ (*it.value)->unlinked_neighbours.remove(p->id);
}
memdelete(p);
- points.erase(p_id);
+ points.remove(p_id);
+ last_free_id = p_id;
}
void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
- ERR_FAIL_COND(!points.has(p_id));
- ERR_FAIL_COND(!points.has(p_with_id));
ERR_FAIL_COND(p_id == p_with_id);
- Point *a = points[p_id];
- Point *b = points[p_with_id];
- a->neighbours.insert(b);
+ Point *a;
+ bool from_exists = points.lookup(p_id, a);
+ ERR_FAIL_COND(!from_exists);
+
+ Point *b;
+ bool to_exists = points.lookup(p_with_id, b);
+ ERR_FAIL_COND(!to_exists);
- if (bidirectional)
- b->neighbours.insert(a);
- else
- b->unlinked_neighbours.insert(a);
+ a->neighbours.set(b->id, b);
+
+ if (bidirectional) {
+ b->neighbours.set(a->id, a);
+ } else {
+ b->unlinked_neighbours.set(a->id, a);
+ }
Segment s(p_id, p_with_id);
if (s.from == p_id) {
@@ -147,6 +174,7 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
segments.insert(s);
}
+
void AStar::disconnect_points(int p_id, int p_with_id) {
Segment s(p_id, p_with_id);
@@ -154,12 +182,18 @@ void AStar::disconnect_points(int p_id, int p_with_id) {
segments.erase(s);
- Point *a = points[p_id];
- Point *b = points[p_with_id];
- a->neighbours.erase(b);
- a->unlinked_neighbours.erase(b);
- b->neighbours.erase(a);
- b->unlinked_neighbours.erase(a);
+ Point *a;
+ bool a_exists = points.lookup(p_id, a);
+ CRASH_COND(!a_exists);
+
+ Point *b;
+ bool b_exists = points.lookup(p_with_id, b);
+ CRASH_COND(!b_exists);
+
+ a->neighbours.remove(b->id);
+ a->unlinked_neighbours.remove(b->id);
+ b->neighbours.remove(a->id);
+ b->unlinked_neighbours.remove(a->id);
}
bool AStar::has_point(int p_id) const {
@@ -171,8 +205,8 @@ Array AStar::get_points() {
Array point_list;
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
- point_list.push_back(E->key());
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+ point_list.push_back(*(it.key));
}
return point_list;
@@ -180,14 +214,14 @@ Array AStar::get_points() {
PoolVector<int> AStar::get_point_connections(int p_id) {
- ERR_FAIL_COND_V(!points.has(p_id), PoolVector<int>());
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, PoolVector<int>());
PoolVector<int> point_list;
- Point *p = points[p_id];
-
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
- point_list.push_back(E->get()->id);
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
+ point_list.push_back((*it.key));
}
return point_list;
@@ -201,27 +235,41 @@ bool AStar::are_points_connected(int p_id, int p_with_id) const {
void AStar::clear() {
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
-
- memdelete(E->get());
+ last_free_id = 0;
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+ memdelete(*(it.value));
}
segments.clear();
points.clear();
}
+int AStar::get_point_count() const {
+ return points.get_num_elements();
+}
+
+int AStar::get_point_capacity() const {
+ return points.get_capacity();
+}
+
+void AStar::reserve_space(int p_num_nodes) {
+ ERR_FAIL_COND_MSG(p_num_nodes <= 0, "New capacity must be greater than 0, was: " + itos(p_num_nodes) + ".");
+ ERR_FAIL_COND_MSG((uint32_t)p_num_nodes < points.get_capacity(), "New capacity must be greater than current capacity: " + itos(points.get_capacity()) + ", new was: " + itos(p_num_nodes) + ".");
+ points.reserve(p_num_nodes);
+}
+
int AStar::get_closest_point(const Vector3 &p_point) const {
int closest_id = -1;
real_t closest_dist = 1e20;
- for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
+
+ if (!(*it.value)->enabled) continue; // Disabled points should not be considered.
- if (!E->get()->enabled)
- continue; //Disabled points should not be considered
- real_t d = p_point.distance_squared_to(E->get()->pos);
+ real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) {
closest_dist = d;
- closest_id = E->key();
+ closest_id = *(it.key);
}
}
@@ -230,8 +278,8 @@ int AStar::get_closest_point(const Vector3 &p_point) const {
Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
- real_t closest_dist = 1e20;
bool found = false;
+ real_t closest_dist = 1e20;
Vector3 closest_point;
for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) {
@@ -262,8 +310,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
pass++;
- if (!end_point->enabled)
- return false;
+ if (!end_point->enabled) return false;
bool found_route = false;
@@ -272,13 +319,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
begin_point->g_score = 0;
begin_point->f_score = _estimate_cost(begin_point->id, end_point->id);
-
open_list.push_back(begin_point);
- while (true) {
-
- if (open_list.size() == 0) // No path found
- break;
+ while (!open_list.empty()) {
Point *p = open_list[0]; // The currently processed point
@@ -291,24 +334,23 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
open_list.remove(open_list.size() - 1);
p->closed_pass = pass; // Mark the point as closed
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
+ for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
- Point *e = E->get(); // The neighbour point
+ Point *e = *(it.value); // The neighbour point
- if (!e->enabled || e->closed_pass == pass)
+ if (!e->enabled || e->closed_pass == pass) {
continue;
+ }
real_t tentative_g_score = p->g_score + _compute_cost(p->id, e->id) * e->weight_scale;
bool new_point = false;
- if (e->open_pass != pass) { // The point wasn't inside the open list
-
+ if (e->open_pass != pass) { // The point wasn't inside the open list.
e->open_pass = pass;
open_list.push_back(e);
new_point = true;
- } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous
-
+ } else if (tentative_g_score >= e->g_score) { // The new path is worse than the previous.
continue;
}
@@ -316,10 +358,11 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
e->g_score = tentative_g_score;
e->f_score = e->g_score + _estimate_cost(e->id, end_point->id);
- if (new_point) // The position of the new points is already known
+ if (new_point) { // The position of the new points is already known.
sorter.push_heap(0, open_list.size() - 1, 0, e, open_list.ptrw());
- else
+ } else {
sorter.push_heap(0, open_list.find(e), 0, e, open_list.ptrw());
+ }
}
}
@@ -331,7 +374,15 @@ float AStar::_estimate_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost))
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
- return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+ Point *from_point;
+ bool from_exists = points.lookup(p_from_id, from_point);
+ CRASH_COND(!from_exists);
+
+ Point *to_point;
+ bool to_exists = points.lookup(p_to_id, to_point);
+ CRASH_COND(!to_exists);
+
+ return from_point->pos.distance_to(to_point->pos);
}
float AStar::_compute_cost(int p_from_id, int p_to_id) {
@@ -339,16 +390,26 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) {
if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost))
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
- return points[p_from_id]->pos.distance_to(points[p_to_id]->pos);
+ Point *from_point;
+ bool from_exists = points.lookup(p_from_id, from_point);
+ CRASH_COND(!from_exists);
+
+ Point *to_point;
+ bool to_exists = points.lookup(p_to_id, to_point);
+ CRASH_COND(!to_exists);
+
+ return from_point->pos.distance_to(to_point->pos);
}
PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
- ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<Vector3>());
- ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<Vector3>());
+ Point *a;
+ bool from_exists = points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, PoolVector<Vector3>());
- Point *a = points[p_from_id];
- Point *b = points[p_to_id];
+ Point *b;
+ bool to_exists = points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, PoolVector<Vector3>());
if (a == b) {
PoolVector<Vector3> ret;
@@ -360,11 +421,8 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return PoolVector<Vector3>();
- if (!found_route)
- return PoolVector<Vector3>();
-
- // Midpoints
Point *p = end_point;
int pc = 1; // Begin point
while (p != begin_point) {
@@ -393,11 +451,13 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
- ERR_FAIL_COND_V(!points.has(p_from_id), PoolVector<int>());
- ERR_FAIL_COND_V(!points.has(p_to_id), PoolVector<int>());
+ Point *a;
+ bool from_exists = points.lookup(p_from_id, a);
+ ERR_FAIL_COND_V(!from_exists, PoolVector<int>());
- Point *a = points[p_from_id];
- Point *b = points[p_to_id];
+ Point *b;
+ bool to_exists = points.lookup(p_to_id, b);
+ ERR_FAIL_COND_V(!to_exists, PoolVector<int>());
if (a == b) {
PoolVector<int> ret;
@@ -409,11 +469,8 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
+ if (!found_route) return PoolVector<int>();
- if (!found_route)
- return PoolVector<int>();
-
- // Midpoints
Point *p = end_point;
int pc = 1; // Begin point
while (p != begin_point) {
@@ -442,16 +499,20 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
void AStar::set_point_disabled(int p_id, bool p_disabled) {
- ERR_FAIL_COND(!points.has(p_id));
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND(!p_exists);
- points[p_id]->enabled = !p_disabled;
+ p->enabled = !p_disabled;
}
bool AStar::is_point_disabled(int p_id) const {
- ERR_FAIL_COND_V(!points.has(p_id), false);
+ Point *p;
+ bool p_exists = points.lookup(p_id, p);
+ ERR_FAIL_COND_V(!p_exists, false);
- return !points[p_id]->enabled;
+ return !p->enabled;
}
void AStar::_bind_methods() {
@@ -474,6 +535,9 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points);
ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected);
+ ClassDB::bind_method(D_METHOD("get_point_count"), &AStar::get_point_count);
+ ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar::get_point_capacity);
+ ClassDB::bind_method(D_METHOD("reserve_space", "num_nodes"), &AStar::reserve_space);
ClassDB::bind_method(D_METHOD("clear"), &AStar::clear);
ClassDB::bind_method(D_METHOD("get_closest_point", "to_position"), &AStar::get_closest_point);
@@ -487,13 +551,11 @@ void AStar::_bind_methods() {
}
AStar::AStar() {
-
+ last_free_id = 0;
pass = 1;
}
AStar::~AStar() {
-
- pass = 1;
clear();
}
@@ -560,10 +622,22 @@ bool AStar2D::are_points_connected(int p_id, int p_with_id) const {
return astar.are_points_connected(p_id, p_with_id);
}
+int AStar2D::get_point_count() const {
+ return astar.get_point_count();
+}
+
+int AStar2D::get_point_capacity() const {
+ return astar.get_point_capacity();
+}
+
void AStar2D::clear() {
astar.clear();
}
+void AStar2D::reserve_space(int p_num_nodes) {
+ astar.reserve_space(p_num_nodes);
+}
+
int AStar2D::get_closest_point(const Vector2 &p_point) const {
return astar.get_closest_point(Vector3(p_point.x, p_point.y, 0));
}
@@ -614,6 +688,9 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar2D::disconnect_points);
ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar2D::are_points_connected);
+ ClassDB::bind_method(D_METHOD("get_point_count"), &AStar2D::get_point_count);
+ ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar2D::get_point_capacity);
+ ClassDB::bind_method(D_METHOD("reserve_space", "num_nodes"), &AStar2D::reserve_space);
ClassDB::bind_method(D_METHOD("clear"), &AStar2D::clear);
ClassDB::bind_method(D_METHOD("get_closest_point", "to_position"), &AStar2D::get_closest_point);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index ec333efc1d..ec2a06f07f 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -31,8 +31,8 @@
#ifndef ASTAR_H
#define ASTAR_H
+#include "core/oa_hash_map.h"
#include "core/reference.h"
-#include "core/self_list.h"
/**
A* pathfinding algorithm
@@ -44,19 +44,21 @@ class AStar : public Reference {
GDCLASS(AStar, Reference);
- uint64_t pass;
-
struct Point {
+ Point() :
+ neighbours(4u),
+ unlinked_neighbours(4u) {}
+
int id;
Vector3 pos;
real_t weight_scale;
bool enabled;
- Set<Point *> neighbours;
- Set<Point *> unlinked_neighbours;
+ OAHashMap<int, Point *> neighbours;
+ OAHashMap<int, Point *> unlinked_neighbours;
- // Used for pathfinding
+ // Used for pathfinding.
Point *prev_point;
real_t g_score;
real_t f_score;
@@ -64,16 +66,15 @@ class AStar : public Reference {
uint64_t closed_pass;
};
- Map<int, Point *> points;
-
struct SortPoints {
- _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B
- if (A->f_score > B->f_score)
+ _FORCE_INLINE_ bool operator()(const Point *A, const Point *B) const { // Returns true when the Point A is worse than Point B.
+ if (A->f_score > B->f_score) {
return true;
- else if (A->f_score < B->f_score)
+ } else if (A->f_score < B->f_score) {
return false;
- else
- return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start
+ } else {
+ return A->g_score < B->g_score; // If the f_costs are the same then prioritize the points that are further away from the start.
+ }
}
};
@@ -101,6 +102,10 @@ class AStar : public Reference {
}
};
+ int last_free_id;
+ uint64_t pass;
+
+ OAHashMap<int, Point *> points;
Set<Segment> segments;
bool _solve(Point *begin_point, Point *end_point);
@@ -131,6 +136,9 @@ public:
void disconnect_points(int p_id, int p_with_id);
bool are_points_connected(int p_id, int p_with_id) const;
+ int get_point_count() const;
+ int get_point_capacity() const;
+ void reserve_space(int p_num_nodes);
void clear();
int get_closest_point(const Vector3 &p_point) const;
@@ -170,6 +178,9 @@ public:
void disconnect_points(int p_id, int p_with_id);
bool are_points_connected(int p_id, int p_with_id) const;
+ int get_point_count() const;
+ int get_point_capacity() const;
+ void reserve_space(int p_num_nodes);
void clear();
int get_closest_point(const Vector2 &p_point) const;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 400f342018..2985959113 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -618,10 +618,7 @@ Basis::operator String() const {
Quat Basis::get_quat() const {
#ifdef MATH_CHECKS
- if (!is_rotation()) {
- ERR_EXPLAIN("Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead.");
- ERR_FAIL_V(Quat());
- }
+ ERR_FAIL_COND_V_MSG(!is_rotation(), Quat(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead.");
#endif
/* Allow getting a quaternion from an unnormalized transform */
Basis m = *this;
diff --git a/core/math/basis.h b/core/math/basis.h
index d3adad3d90..053effda69 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -36,10 +36,6 @@
#include "core/math/quat.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Basis {
public:
Vector3 elements[3];
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index a12f9fee2e..cfa698282e 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -192,7 +192,7 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
#ifdef DEBUG_ENABLED
int plane_count = planes.size();
uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_INDEX_V(plane, plane_count, false);
+ ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
#endif
idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under;
@@ -258,7 +258,7 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
#ifdef DEBUG_ENABLED
int plane_count = planes.size();
uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_INDEX_V(plane, plane_count, false);
+ ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
#endif
bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point);
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
index a7a3697990..90b5e8322a 100644
--- a/core/math/bsp_tree.h
+++ b/core/math/bsp_tree.h
@@ -38,9 +38,7 @@
#include "core/pool_vector.h"
#include "core/variant.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class BSP_Tree {
public:
enum {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 8b3b6c82f3..30c0cab909 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -302,8 +302,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform)
/** Fast Plane Extraction from combined modelview/projection matrices.
* References:
- * http://www.markmorley.com/opengl/frustumculling.html
- * http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
+ * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html
+ * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/
Vector<Plane> planes;
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 3bcf48f5da..63cc88553d 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -34,10 +34,6 @@
#include "core/math/rect2.h"
#include "core/math/transform.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
struct CameraMatrix {
enum Planes {
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index ed52c506db..3f8013a3e6 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -80,11 +80,11 @@ public:
}
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) {
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) {
return true;
}
- if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) {
+ if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) {
return true;
}
diff --git a/core/math/disjoint_set.cpp b/core/math/disjoint_set.cpp
new file mode 100644
index 0000000000..838939e1ba
--- /dev/null
+++ b/core/math/disjoint_set.cpp
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* disjoint_set.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. */
+/*************************************************************************/
+
+#include "disjoint_set.h"
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
new file mode 100644
index 0000000000..c9b3d0b65d
--- /dev/null
+++ b/core/math/disjoint_set.h
@@ -0,0 +1,155 @@
+/*************************************************************************/
+/* disjoint_set.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 DISJOINT_SET_H
+#define DISJOINT_SET_H
+
+#include "core/map.h"
+#include "core/vector.h"
+
+/**
+ @author Marios Staikopoulos <marios@staik.net>
+*/
+
+/* This DisjointSet class uses Find with path compression and Union by rank */
+template <typename T, class C = Comparator<T>, class AL = DefaultAllocator>
+class DisjointSet {
+
+ struct Element {
+ T object;
+ Element *parent = nullptr;
+ int rank = 0;
+ };
+
+ typedef Map<T, Element *, C, AL> MapT;
+
+ MapT elements;
+
+ Element *get_parent(Element *element);
+
+ _FORCE_INLINE_ Element *insert_or_get(T object);
+
+public:
+ ~DisjointSet();
+
+ _FORCE_INLINE_ void insert(T object) { (void)insert_or_get(object); }
+
+ void create_union(T a, T b);
+
+ void get_representatives(Vector<T> &out_roots);
+
+ void get_members(Vector<T> &out_members, T representative);
+};
+
+/* FUNCTIONS */
+
+template <typename T, class C, class AL>
+DisjointSet<T, C, AL>::~DisjointSet() {
+ for (typename MapT::Element *itr = elements.front(); itr != nullptr; itr = itr->next()) {
+ memdelete_allocator<Element, AL>(itr->value());
+ }
+}
+
+template <typename T, class C, class AL>
+typename DisjointSet<T, C, AL>::Element *DisjointSet<T, C, AL>::get_parent(Element *element) {
+ if (element->parent != element) {
+ element->parent = get_parent(element->parent);
+ }
+
+ return element->parent;
+}
+
+template <typename T, class C, class AL>
+typename DisjointSet<T, C, AL>::Element *DisjointSet<T, C, AL>::insert_or_get(T object) {
+ typename MapT::Element *itr = elements.find(object);
+ if (itr != nullptr) {
+ return itr->value();
+ }
+
+ Element *new_element = memnew_allocator(Element, AL);
+ new_element->object = object;
+ new_element->parent = new_element;
+ elements.insert(object, new_element);
+
+ return new_element;
+}
+
+template <typename T, class C, class AL>
+void DisjointSet<T, C, AL>::create_union(T a, T b) {
+
+ Element *x = insert_or_get(a);
+ Element *y = insert_or_get(b);
+
+ Element *x_root = get_parent(x);
+ Element *y_root = get_parent(y);
+
+ // Already in the same set
+ if (x_root == y_root)
+ return;
+
+ // Not in the same set, merge
+ if (x_root->rank < y_root->rank) {
+ SWAP(x_root, y_root);
+ }
+
+ // Merge y_root into x_root
+ y_root->parent = x_root;
+ if (x_root->rank == y_root->rank) {
+ ++x_root->rank;
+ }
+}
+
+template <typename T, class C, class AL>
+void DisjointSet<T, C, AL>::get_representatives(Vector<T> &out_representatives) {
+ for (typename MapT::Element *itr = elements.front(); itr != nullptr; itr = itr->next()) {
+ Element *element = itr->value();
+ if (element->parent == element) {
+ out_representatives.push_back(element->object);
+ }
+ }
+}
+
+template <typename T, class C, class AL>
+void DisjointSet<T, C, AL>::get_members(Vector<T> &out_members, T representative) {
+ typename MapT::Element *rep_itr = elements.find(representative);
+ ERR_FAIL_COND(rep_itr == nullptr);
+
+ Element *rep_element = rep_itr->value();
+ ERR_FAIL_COND(rep_element->parent != rep_element);
+
+ for (typename MapT::Element *itr = elements.front(); itr != nullptr; itr = itr->next()) {
+ Element *parent = get_parent(itr->value());
+ if (parent == rep_element) {
+ out_members.push_back(itr->key());
+ }
+ }
+}
+
+#endif
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index b52658e2cf..46f81ce5c3 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -52,6 +52,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = {
"sqrt",
"fmod",
"fposmod",
+ "posmod",
"floor",
"ceil",
"round",
@@ -67,6 +68,7 @@ const char *Expression::func_name[Expression::FUNC_MAX] = {
"step_decimals",
"stepify",
"lerp",
+ "lerp_angle",
"inverse_lerp",
"range_lerp",
"smoothstep",
@@ -175,6 +177,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
case MATH_ATAN2:
case MATH_FMOD:
case MATH_FPOSMOD:
+ case MATH_POSMOD:
case MATH_POW:
case MATH_EASE:
case MATH_STEPIFY:
@@ -188,6 +191,7 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
case COLORN:
return 2;
case MATH_LERP:
+ case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
case MATH_SMOOTHSTEP:
case MATH_MOVE_TOWARD:
@@ -283,6 +287,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
VALIDATE_ARG_NUM(1);
*r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
+ case MATH_POSMOD: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]);
+ } break;
case MATH_FLOOR: {
VALIDATE_ARG_NUM(0);
@@ -387,6 +397,13 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
+ case MATH_LERP_ANGLE: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
case MATH_INVERSE_LERP: {
VALIDATE_ARG_NUM(0);
@@ -793,17 +810,13 @@ Error Expression::_get_token(Token &r_token) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
CharType cchar = GET_CHAR();
- if (cchar == 0) {
- r_token.type = TK_EOF;
- return OK;
- }
switch (cchar) {
case 0: {
r_token.type = TK_EOF;
return OK;
- } break;
+ };
case '{': {
r_token.type = TK_CURLY_BRACKET_OPEN;
@@ -2148,10 +2161,8 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
}
Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) {
- if (error_set) {
- ERR_EXPLAIN("There was previously a parse error: " + error_str);
- ERR_FAIL_V(Variant());
- }
+
+ ERR_FAIL_COND_V_MSG(error_set, Variant(), "There was previously a parse error: " + error_str + ".");
execution_error = false;
Variant output;
@@ -2160,10 +2171,7 @@ Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) {
if (err) {
execution_error = true;
error_str = error_txt;
- if (p_show_error) {
- ERR_EXPLAIN(error_str);
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(p_show_error, Variant(), error_str);
}
return output;
diff --git a/core/math/expression.h b/core/math/expression.h
index 1113bb6587..833220592c 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -51,6 +51,7 @@ public:
MATH_SQRT,
MATH_FMOD,
MATH_FPOSMOD,
+ MATH_POSMOD,
MATH_FLOOR,
MATH_CEIL,
MATH_ROUND,
@@ -66,6 +67,7 @@ public:
MATH_STEP_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
+ MATH_LERP_ANGLE,
MATH_INVERSE_LERP,
MATH_RANGE_LERP,
MATH_SMOOTHSTEP,
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 8314cb827c..77383e2839 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -34,9 +34,10 @@
#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/triangulator.h"
-#define SCALE_FACTOR 100000.0 // based on CMP_EPSILON
+#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.
-/* this implementation is very inefficient, commenting unless bugs happen. See the other one.
+// This implementation is very inefficient, commenting unless bugs happen. See the other one.
+/*
bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
Vector<int> indices = Geometry::triangulate_polygon(p_polygon);
@@ -124,8 +125,8 @@ struct _FaceClassify {
};
static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
- /* connect faces, error will occur if an edge is shared between more than 2 faces */
- /* clear connections */
+ // Connect faces, error will occur if an edge is shared between more than 2 faces.
+ // Clear connections.
bool error = false;
@@ -195,13 +196,6 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
if (p_faces[i].links[j].face == -1)
p_faces[i].valid = false;
}
- /*printf("face %i is valid: %i, group %i. connected to %i:%i,%i:%i,%i:%i\n",i,p_faces[i].valid,p_faces[i].group,
- p_faces[i].links[0].face,
- p_faces[i].links[0].edge,
- p_faces[i].links[1].face,
- p_faces[i].links[1].edge,
- p_faces[i].links[2].face,
- p_faces[i].links[2].edge);*/
}
return error;
}
@@ -249,10 +243,10 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
if (error) {
- ERR_FAIL_COND_V(error, PoolVector<PoolVector<Face3> >()); // invalid geometry
+ ERR_FAIL_COND_V(error, PoolVector<PoolVector<Face3> >()); // Invalid geometry.
}
- /* group connected faces in separate objects */
+ // Group connected faces in separate objects.
int group = 0;
for (int i = 0; i < len; i++) {
@@ -264,7 +258,7 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
}
}
- /* group connected faces in separate objects */
+ // Group connected faces in separate objects.
for (int i = 0; i < len; i++) {
@@ -376,7 +370,7 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int
static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z) {
if (p_cell_status[x][y][z] & 3)
- return; // nothing to do, already used and/or visited
+ return; // Nothing to do, already used and/or visited.
p_cell_status[x][y][z] = _CELL_PREV_FIRST;
@@ -384,29 +378,20 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
uint8_t &c = p_cell_status[x][y][z];
- //printf("at %i,%i,%i\n",x,y,z);
-
if ((c & _CELL_STEP_MASK) == _CELL_STEP_NONE) {
- /* Haven't been in here, mark as outside */
+ // Haven't been in here, mark as outside.
p_cell_status[x][y][z] |= _CELL_EXTERIOR;
- //printf("not marked as anything, marking exterior\n");
}
- //printf("cell step is %i\n",(c&_CELL_STEP_MASK));
-
if ((c & _CELL_STEP_MASK) != _CELL_STEP_DONE) {
- /* if not done, increase step */
+ // If not done, increase step.
c += 1 << 2;
- //printf("incrementing cell step\n");
}
if ((c & _CELL_STEP_MASK) == _CELL_STEP_DONE) {
- /* Go back */
- //printf("done, going back a cell\n");
-
+ // Go back.
switch (c & _CELL_PREV_MASK) {
case _CELL_PREV_FIRST: {
- //printf("at end, finished marking\n");
return;
} break;
case _CELL_PREV_Y_POS: {
@@ -440,8 +425,6 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
continue;
}
- //printf("attempting new cell!\n");
-
int next_x = x, next_y = y, next_z = z;
uint8_t prev = 0;
@@ -475,8 +458,6 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
default: ERR_FAIL();
}
- //printf("testing if new cell will be ok...!\n");
-
if (next_x < 0 || next_x >= len_x)
continue;
if (next_y < 0 || next_y >= len_y)
@@ -484,13 +465,9 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
if (next_z < 0 || next_z >= len_z)
continue;
- //printf("testing if new cell is traversable\n");
-
if (p_cell_status[next_x][next_y][next_z] & 3)
continue;
- //printf("move to it\n");
-
x = next_x;
y = next_y;
z = next_z;
@@ -507,17 +484,6 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
if (p_cell_status[x][y][z] & _CELL_EXTERIOR)
return;
-/* static const Vector3 vertices[8]={
- Vector3(0,0,0),
- Vector3(0,0,1),
- Vector3(0,1,0),
- Vector3(0,1,1),
- Vector3(1,0,0),
- Vector3(1,0,1),
- Vector3(1,1,0),
- Vector3(1,1,1),
- };
-*/
#define vert(m_idx) Vector3(((m_idx)&4) >> 2, ((m_idx)&2) >> 1, (m_idx)&1)
static const uint8_t indices[6][4] = {
@@ -529,22 +495,6 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
{ 0, 4, 6, 2 },
};
- /*
-
- {0,1,2,3},
- {0,1,4,5},
- {0,2,4,6},
- {4,5,6,7},
- {2,3,7,6},
- {1,3,5,7},
-
- {0,2,3,1},
- {0,1,5,4},
- {0,4,6,2},
- {7,6,4,5},
- {7,3,2,6},
- {7,5,1,3},
-*/
for (int i = 0; i < 6; i++) {
@@ -607,9 +557,9 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
}
}
- global_aabb.grow_by(0.01); // avoid numerical error
+ global_aabb.grow_by(0.01); // Avoid numerical error.
- // determine amount of cells in grid axis
+ // Determine amount of cells in grid axis.
int div_x, div_y, div_z;
if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH)
@@ -632,7 +582,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
voxelsize.y /= div_y;
voxelsize.z /= div_z;
- // create and initialize cells to zero
+ // Create and initialize cells to zero.
uint8_t ***cell_status = memnew_arr(uint8_t **, div_x);
for (int i = 0; i < div_x; i++) {
@@ -650,7 +600,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
}
}
- // plot faces into cells
+ // Plot faces into cells.
for (int i = 0; i < face_count; i++) {
@@ -662,7 +612,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
_plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f);
}
- // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking
+ // Determine which cells connect to the outside by traversing the outside and recursively flood-fill marking.
for (int i = 0; i < div_x; i++) {
@@ -691,7 +641,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
}
}
- // build faces for the inside-outside cell divisors
+ // Build faces for the inside-outside cell divisors.
PoolVector<Face3> wrapped_faces;
@@ -706,7 +656,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
}
}
- // transform face vertices to global coords
+ // Transform face vertices to global coords.
int wrapped_faces_count = wrapped_faces.size();
PoolVector<Face3>::Write wrapped_facesw = wrapped_faces.write();
@@ -753,7 +703,7 @@ Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> po
inp.SetOrientation(TRIANGULATOR_CCW);
in_poly.push_back(inp);
TriangulatorPartition tpart;
- if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
+ if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed.
ERR_PRINT("Convex decomposing failed!");
return decomp;
}
@@ -765,7 +715,7 @@ Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> po
decomp.write[idx].resize(tp.GetNumPoints());
- for (int i = 0; i < tp.GetNumPoints(); i++) {
+ for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
decomp.write[idx].write[i] = tp.GetPoint(i);
}
@@ -781,7 +731,7 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
#define SUBPLANE_SIZE 1024.0
- real_t subplane_size = 1024.0; // should compute this from the actual plane
+ real_t subplane_size = 1024.0; // Should compute this from the actual plane.
for (int i = 0; i < p_planes.size(); i++) {
Plane p = p_planes[i];
@@ -789,7 +739,7 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
Vector3 ref = Vector3(0.0, 1.0, 0.0);
if (ABS(p.normal.dot(ref)) > 0.95)
- ref = Vector3(0.0, 0.0, 1.0); // change axis
+ ref = Vector3(0.0, 0.0, 1.0); // Change axis.
Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross(right).normalized();
@@ -827,20 +777,20 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
real_t dist0 = clip.distance_to(edge0_A);
real_t dist1 = clip.distance_to(edge1_A);
- if (dist0 <= 0) { // behind plane
+ if (dist0 <= 0) { // Behind plane.
new_vertices.push_back(vertices[k]);
}
- // check for different sides and non coplanar
+ // Check for different sides and non coplanar.
if ((dist0 * dist1) < 0) {
- // calculate intersection
+ // Calculate intersection.
Vector3 rel = edge1_A - edge0_A;
real_t den = clip.normal.dot(rel);
if (Math::is_zero_approx(den))
- continue; // point too short
+ continue; // Point too short.
real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den;
Vector3 inters = edge0_A + rel * dist;
@@ -854,11 +804,11 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
if (vertices.size() < 3)
continue;
- //result is a clockwise face
+ // Result is a clockwise face.
MeshData::Face face;
- // add face indices
+ // Add face indices.
for (int j = 0; j < vertices.size(); j++) {
int idx = -1;
@@ -882,7 +832,7 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
face.plane = p;
mesh.faces.push_back(face);
- //add edge
+ // Add edge.
for (int j = 0; j < face.indices.size(); j++) {
@@ -972,7 +922,7 @@ PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int
for (int j = 1; j <= p_lats; j++) {
- //todo this is stupid, fix
+ // FIXME: This is stupid.
Vector3 angle = normal.linear_interpolate(axis, j / (real_t)p_lats).normalized();
Vector3 pos = angle * p_radius;
planes.push_back(Plane(pos, angle));
@@ -1032,12 +982,12 @@ struct _AtlasWorkRectResult {
void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size) {
- //super simple, almost brute force scanline stacking fitter
- //it's pretty basic for now, but it tries to make sure that the aspect ratio of the
- //resulting atlas is somehow square. This is necessary because video cards have limits
- //on texture size (usually 2048 or 4096), so the more square a texture, the more chances
- //it will work in every hardware.
- // for example, it will prioritize a 1024x1024 atlas (works everywhere) instead of a
+ // Super simple, almost brute force scanline stacking fitter.
+ // It's pretty basic for now, but it tries to make sure that the aspect ratio of the
+ // resulting atlas is somehow square. This is necessary because video cards have limits.
+ // On texture size (usually 2048 or 4096), so the more square a texture, the more chances.
+ // It will work in every hardware.
+ // For example, it will prioritize a 1024x1024 atlas (works everywhere) instead of a
// 256x8192 atlas (won't work anywhere).
ERR_FAIL_COND(p_rects.size() == 0);
@@ -1066,7 +1016,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
for (int j = 0; j < w; j++)
hmax.write[j] = 0;
- //place them
+ // Place them.
int ofs = 0;
int limit_h = 0;
for (int j = 0; j < wrects.size(); j++) {
@@ -1101,7 +1051,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
if (end_w > max_w)
max_w = end_w;
- if (ofs == 0 || end_h > limit_h) //while h limit not reached, keep stacking
+ if (ofs == 0 || end_h > limit_h) // While h limit not reached, keep stacking.
ofs += wrects[j].s.width;
}
@@ -1112,7 +1062,7 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
results.push_back(result);
}
- //find the result with the best aspect ratio
+ // Find the result with the best aspect ratio.
int best = -1;
real_t best_aspect = 1e20;
@@ -1152,7 +1102,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p
}
Path path_a, path_b;
- // Need to scale points (Clipper's requirement for robust computation)
+ // Need to scale points (Clipper's requirement for robust computation).
for (int i = 0; i != p_polypath_a.size(); ++i) {
path_a << IntPoint(p_polypath_a[i].x * SCALE_FACTOR, p_polypath_a[i].y * SCALE_FACTOR);
}
@@ -1160,19 +1110,19 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p
path_b << IntPoint(p_polypath_b[i].x * SCALE_FACTOR, p_polypath_b[i].y * SCALE_FACTOR);
}
Clipper clp;
- clp.AddPath(path_a, ptSubject, !is_a_open); // forward compatible with Clipper 10.0.0
- clp.AddPath(path_b, ptClip, true); // polylines cannot be set as clip
+ clp.AddPath(path_a, ptSubject, !is_a_open); // Forward compatible with Clipper 10.0.0.
+ clp.AddPath(path_b, ptClip, true); // Polylines cannot be set as clip.
Paths paths;
if (is_a_open) {
- PolyTree tree; // needed to populate polylines
+ PolyTree tree; // Needed to populate polylines.
clp.Execute(op, tree);
OpenPathsFromPolyTree(tree, paths);
} else {
- clp.Execute(op, paths); // works on closed polygons only
+ clp.Execute(op, paths); // Works on closed polygons only.
}
- // Have to scale points down now
+ // Have to scale points down now.
Vector<Vector<Point2> > polypaths;
for (Paths::size_type i = 0; i < paths.size(); ++i) {
@@ -1214,16 +1164,16 @@ Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polyp
ClipperOffset co;
Path path;
- // Need to scale points (Clipper's requirement for robust computation)
+ // Need to scale points (Clipper's requirement for robust computation).
for (int i = 0; i != p_polypath.size(); ++i) {
path << IntPoint(p_polypath[i].x * SCALE_FACTOR, p_polypath[i].y * SCALE_FACTOR);
}
co.AddPath(path, jt, et);
Paths paths;
- co.Execute(paths, p_delta * SCALE_FACTOR); // inflate/deflate
+ co.Execute(paths, p_delta * SCALE_FACTOR); // Inflate/deflate.
- // Have to scale points down now
+ // Have to scale points down now.
Vector<Vector<Point2> > polypaths;
for (Paths::size_type i = 0; i < paths.size(); ++i) {
diff --git a/core/math/geometry.h b/core/math/geometry.h
index e4f3ff799e..8b0a51c651 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -41,47 +41,43 @@
#include "core/print_string.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Geometry {
Geometry();
public:
static real_t get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2, Vector2 &c1, Vector2 &c2) {
- Vector2 d1 = q1 - p1; // Direction vector of segment S1
- Vector2 d2 = q2 - p2; // Direction vector of segment S2
+ Vector2 d1 = q1 - p1; // Direction vector of segment S1.
+ Vector2 d2 = q2 - p2; // Direction vector of segment S2.
Vector2 r = p1 - p2;
- real_t a = d1.dot(d1); // Squared length of segment S1, always nonnegative
- real_t e = d2.dot(d2); // Squared length of segment S2, always nonnegative
+ real_t a = d1.dot(d1); // Squared length of segment S1, always nonnegative.
+ real_t e = d2.dot(d2); // Squared length of segment S2, always nonnegative.
real_t f = d2.dot(r);
real_t s, t;
- // Check if either or both segments degenerate into points
+ // Check if either or both segments degenerate into points.
if (a <= CMP_EPSILON && e <= CMP_EPSILON) {
- // Both segments degenerate into points
+ // Both segments degenerate into points.
c1 = p1;
c2 = p2;
return Math::sqrt((c1 - c2).dot(c1 - c2));
}
if (a <= CMP_EPSILON) {
- // First segment degenerates into a point
+ // First segment degenerates into a point.
s = 0.0;
t = f / e; // s = 0 => t = (b*s + f) / e = f / e
t = CLAMP(t, 0.0, 1.0);
} else {
real_t c = d1.dot(r);
if (e <= CMP_EPSILON) {
- // Second segment degenerates into a point
+ // Second segment degenerates into a point.
t = 0.0;
s = CLAMP(-c / a, 0.0, 1.0); // t = 0 => s = (b*t - c) / a = -c / a
} else {
- // The general nondegenerate case starts here
+ // The general nondegenerate case starts here.
real_t b = d1.dot(d2);
- real_t denom = a * e - b * b; // Always nonnegative
+ real_t denom = a * e - b * b; // Always nonnegative.
// If segments not parallel, compute closest point on L1 to L2 and
- // clamp to segment S1. Else pick arbitrary s (here 0)
+ // clamp to segment S1. Else pick arbitrary s (here 0).
if (denom != 0.0) {
s = CLAMP((b * f - c * e) / denom, 0.0, 1.0);
} else
@@ -92,7 +88,7 @@ public:
//If t in [0,1] done. Else clamp t, recompute s for the new value
// of t using s = Dot((P2 + D2*t) - P1,D1) / Dot(D1,D1)= (t*b - c) / a
- // and clamp s to [0, 1]
+ // and clamp s to [0, 1].
if (t < 0.0) {
t = 0.0;
s = CLAMP(-c / a, 0.0, 1.0);
@@ -109,14 +105,14 @@ public:
static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) {
-//do the function 'd' as defined by pb. I think is is dot product of some sort
+// Do the function 'd' as defined by pb. I think is is dot product of some sort.
#define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z))
- //calculate the parametric position on the 2 curves, mua and mub
+ // Calculate the parametric position on the 2 curves, mua and mub.
real_t mua = (d_of(p1, q1, q2, q1) * d_of(q2, q1, p2, p1) - d_of(p1, q1, p2, p1) * d_of(q2, q1, q2, q1)) / (d_of(p2, p1, p2, p1) * d_of(q2, q1, q2, q1) - d_of(q2, q1, p2, p1) * d_of(q2, q1, p2, p1));
real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1);
- //clip the value between [0..1] constraining the solution to lie on the original curves
+ // Clip the value between [0..1] constraining the solution to lie on the original curves.
if (mua < 0) mua = 0;
if (mub < 0) mub = 0;
if (mua > 1) mua = 1;
@@ -129,38 +125,38 @@ public:
Vector3 u = p_to_a - p_from_a;
Vector3 v = p_to_b - p_from_b;
Vector3 w = p_from_a - p_to_a;
- real_t a = u.dot(u); // always >= 0
+ real_t a = u.dot(u); // Always >= 0
real_t b = u.dot(v);
- real_t c = v.dot(v); // always >= 0
+ real_t c = v.dot(v); // Always >= 0
real_t d = u.dot(w);
real_t e = v.dot(w);
- real_t D = a * c - b * b; // always >= 0
+ real_t D = a * c - b * b; // Always >= 0
real_t sc, sN, sD = D; // sc = sN / sD, default sD = D >= 0
real_t tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0
- // compute the line parameters of the two closest points
- if (D < CMP_EPSILON) { // the lines are almost parallel
- sN = 0.0; // force using point P0 on segment S1
- sD = 1.0; // to prevent possible division by 0.0 later
+ // Compute the line parameters of the two closest points.
+ if (D < CMP_EPSILON) { // The lines are almost parallel.
+ sN = 0.0; // Force using point P0 on segment S1
+ sD = 1.0; // to prevent possible division by 0.0 later.
tN = e;
tD = c;
- } else { // get the closest points on the infinite lines
+ } else { // Get the closest points on the infinite lines
sN = (b * e - c * d);
tN = (a * e - b * d);
- if (sN < 0.0) { // sc < 0 => the s=0 edge is visible
+ if (sN < 0.0) { // sc < 0 => the s=0 edge is visible.
sN = 0.0;
tN = e;
tD = c;
- } else if (sN > sD) { // sc > 1 => the s=1 edge is visible
+ } else if (sN > sD) { // sc > 1 => the s=1 edge is visible.
sN = sD;
tN = e + b;
tD = c;
}
}
- if (tN < 0.0) { // tc < 0 => the t=0 edge is visible
+ if (tN < 0.0) { // tc < 0 => the t=0 edge is visible.
tN = 0.0;
- // recompute sc for this edge
+ // Recompute sc for this edge.
if (-d < 0.0)
sN = 0.0;
else if (-d > a)
@@ -169,9 +165,9 @@ public:
sN = -d;
sD = a;
}
- } else if (tN > tD) { // tc > 1 => the t=1 edge is visible
+ } else if (tN > tD) { // tc > 1 => the t=1 edge is visible.
tN = tD;
- // recompute sc for this edge
+ // Recompute sc for this edge.
if ((-d + b) < 0.0)
sN = 0;
else if ((-d + b) > a)
@@ -181,14 +177,14 @@ public:
sD = a;
}
}
- // finally do the division to get sc and tc
+ // Finally do the division to get sc and tc.
sc = (Math::is_zero_approx(sN) ? 0.0 : sN / sD);
tc = (Math::is_zero_approx(tN) ? 0.0 : tN / tD);
- // get the difference of the two closest points
+ // Get the difference of the two closest points.
Vector3 dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc)
- return dP.length(); // return the closest distance
+ return dP.length(); // Return the closest distance.
}
static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = 0) {
@@ -196,7 +192,7 @@ public:
Vector3 e2 = p_v2 - p_v0;
Vector3 h = p_dir.cross(e2);
real_t a = e1.dot(h);
- if (Math::is_zero_approx(a)) // parallel test
+ if (Math::is_zero_approx(a)) // Parallel test.
return false;
real_t f = 1.0 / a;
@@ -214,16 +210,15 @@ public:
if (v < 0.0 || u + v > 1.0)
return false;
- // at this stage we can compute t to find out where
- // the intersection point is on the line
+ // At this stage we can compute t to find out where
+ // the intersection point is on the line.
real_t t = f * e2.dot(q);
if (t > 0.00001) { // ray intersection
if (r_res)
*r_res = p_from + p_dir * t;
return true;
- } else // this means that there is a line intersection
- // but not a ray intersection
+ } else // This means that there is a line intersection but not a ray intersection.
return false;
}
@@ -234,7 +229,7 @@ public:
Vector3 e2 = p_v2 - p_v0;
Vector3 h = rel.cross(e2);
real_t a = e1.dot(h);
- if (Math::is_zero_approx(a)) // parallel test
+ if (Math::is_zero_approx(a)) // Parallel test.
return false;
real_t f = 1.0 / a;
@@ -252,16 +247,15 @@ public:
if (v < 0.0 || u + v > 1.0)
return false;
- // at this stage we can compute t to find out where
- // the intersection point is on the line
+ // At this stage we can compute t to find out where
+ // the intersection point is on the line.
real_t t = f * e2.dot(q);
- if (t > CMP_EPSILON && t <= 1.0) { // ray intersection
+ if (t > CMP_EPSILON && t <= 1.0) { // Ray intersection.
if (r_res)
*r_res = p_from + rel * t;
return true;
- } else // this means that there is a line intersection
- // but not a ray intersection
+ } else // This means that there is a line intersection but not a ray intersection.
return false;
}
@@ -271,13 +265,11 @@ public:
Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON)
- return false; // both points are the same
+ return false; // Both points are the same.
Vector3 normal = rel / rel_l;
real_t sphere_d = normal.dot(sphere_pos);
- //Vector3 ray_closest=normal*sphere_d;
-
real_t ray_distance = sphere_pos.distance_to(normal * sphere_d);
if (ray_distance >= p_sphere_radius)
@@ -289,7 +281,7 @@ public:
if (inters_d2 >= CMP_EPSILON)
inters_d -= Math::sqrt(inters_d2);
- // check in segment
+ // Check in segment.
if (inters_d < 0 || inters_d > rel_l)
return false;
@@ -308,9 +300,9 @@ public:
Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON)
- return false; // both points are the same
+ return false; // Both points are the same.
- // first check if they are parallel
+ // First check if they are parallel.
Vector3 normal = (rel / rel_l);
Vector3 crs = normal.cross(Vector3(0, 0, 1));
real_t crs_l = crs.length();
@@ -318,8 +310,7 @@ public:
Vector3 z_dir;
if (crs_l < CMP_EPSILON) {
- //blahblah parallel
- z_dir = Vector3(1, 0, 0); //any x/y vector ok
+ z_dir = Vector3(1, 0, 0); // Any x/y vector OK.
} else {
z_dir = crs / crs_l;
}
@@ -327,12 +318,12 @@ public:
real_t dist = z_dir.dot(p_from);
if (dist >= p_radius)
- return false; // too far away
+ return false; // Too far away.
- // convert to 2D
+ // Convert to 2D.
real_t w2 = p_radius * p_radius - dist * dist;
if (w2 < CMP_EPSILON)
- return false; //avoid numerical error
+ return false; // Avoid numerical error.
Size2 size(Math::sqrt(w2), p_height * 0.5);
Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized();
@@ -379,7 +370,7 @@ public:
return false;
}
- // convert to 3D again
+ // Convert to 3D again.
Vector3 result = p_from + (rel * min);
Vector3 res_normal = result;
@@ -420,19 +411,18 @@ public:
real_t den = p.normal.dot(dir);
- //printf("den is %i\n",den);
if (Math::abs(den) <= CMP_EPSILON)
- continue; // ignore parallel plane
+ continue; // Ignore parallel plane.
real_t dist = -p.distance_to(p_from) / den;
if (den > 0) {
- //backwards facing plane
+ // Backwards facing plane.
if (dist < max)
max = dist;
} else {
- //front facing plane
+ // Front facing plane.
if (dist > min) {
min = dist;
min_index = i;
@@ -440,8 +430,8 @@ public:
}
}
- if (max <= min || min < 0 || min > rel_l || min_index == -1) // exit conditions
- return false; // no intersection
+ if (max <= min || min < 0 || min > rel_l || min_index == -1) // Exit conditions.
+ return false; // No intersection.
if (p_res)
*p_res = p_from + dir * min;
@@ -457,16 +447,16 @@ public:
Vector3 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
if (l2 < 1e-20)
- return p_segment[0]; // both points are the same, just give any
+ return p_segment[0]; // Both points are the same, just give any.
real_t d = n.dot(p) / l2;
if (d <= 0.0)
- return p_segment[0]; // before first point
+ return p_segment[0]; // Before first point.
else if (d >= 1.0)
- return p_segment[1]; // after first point
+ return p_segment[1]; // After first point.
else
- return p_segment[0] + n * d; // inside
+ return p_segment[0] + n * d; // Inside.
}
static Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 *p_segment) {
@@ -475,11 +465,11 @@ public:
Vector3 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
if (l2 < 1e-20)
- return p_segment[0]; // both points are the same, just give any
+ return p_segment[0]; // Both points are the same, just give any.
real_t d = n.dot(p) / l2;
- return p_segment[0] + n * d; // inside
+ return p_segment[0] + n * d; // Inside.
}
static Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 *p_segment) {
@@ -488,16 +478,16 @@ public:
Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
if (l2 < 1e-20)
- return p_segment[0]; // both points are the same, just give any
+ return p_segment[0]; // Both points are the same, just give any.
real_t d = n.dot(p) / l2;
if (d <= 0.0)
- return p_segment[0]; // before first point
+ return p_segment[0]; // Before first point.
else if (d >= 1.0)
- return p_segment[1]; // after first point
+ return p_segment[1]; // After first point.
else
- return p_segment[0] + n * d; // inside
+ return p_segment[0] + n * d; // Inside.
}
static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
@@ -512,27 +502,25 @@ public:
return (cn.cross(an) > 0) == orientation;
}
- //static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon);
-
static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 *p_segment) {
Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
if (l2 < 1e-20)
- return p_segment[0]; // both points are the same, just give any
+ return p_segment[0]; // Both points are the same, just give any.
real_t d = n.dot(p) / l2;
- return p_segment[0] + n * d; // inside
+ return p_segment[0] + n * d; // Inside.
}
static bool line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) {
- // see http://paulbourke.net/geometry/pointlineplane/
+ // See http://paulbourke.net/geometry/pointlineplane/
const real_t denom = p_dir_b.y * p_dir_a.x - p_dir_b.x * p_dir_a.y;
- if (Math::is_zero_approx(denom)) { // parallel?
+ if (Math::is_zero_approx(denom)) { // Parallel?
return false;
}
@@ -560,11 +548,11 @@ public:
real_t ABpos = D.x + (C.x - D.x) * D.y / (D.y - C.y);
- // Fail if segment C-D crosses line A-B outside of segment A-B.
+ // Fail if segment C-D crosses line A-B outside of segment A-B.
if (ABpos < 0 || ABpos > 1.0)
return false;
- // (4) Apply the discovered position to line A-B in the original coordinate system.
+ // (4) Apply the discovered position to line A-B in the original coordinate system.
if (r_result)
*r_result = p_from_a + B * ABpos;
@@ -597,7 +585,7 @@ public:
real_t d = p_normal.dot(p_sphere_pos) - p_normal.dot(p_triangle[0]);
- if (d > p_sphere_radius || d < -p_sphere_radius) // not touching the plane of the face, return
+ if (d > p_sphere_radius || d < -p_sphere_radius) // Not touching the plane of the face, return.
return false;
Vector3 contact = p_sphere_pos - (p_normal * d);
@@ -617,25 +605,25 @@ public:
for (int i = 0; i < 3; i++) {
- // check edge cylinder
+ // Check edge cylinder.
Vector3 n1 = verts[i] - verts[i + 1];
Vector3 n2 = p_sphere_pos - verts[i + 1];
- ///@TODO i could discard by range here to make the algorithm quicker? dunno..
+ ///@TODO Maybe discard by range here to make the algorithm quicker.
- // check point within cylinder radius
+ // Check point within cylinder radius.
Vector3 axis = n1.cross(n2).cross(n1);
- axis.normalize(); // ugh
+ axis.normalize();
real_t ad = axis.dot(n2);
if (ABS(ad) > p_sphere_radius) {
- // no chance with this edge, too far away
+ // No chance with this edge, too far away.
continue;
}
- // check point within edge capsule cylinder
+ // Check point within edge capsule cylinder.
/** 4th TEST INSIDE EDGE POINTS **/
real_t sphere_at = n1.dot(n2);
@@ -644,8 +632,7 @@ public:
r_triangle_contact = p_sphere_pos - axis * (axis.dot(n2));
r_sphere_contact = p_sphere_pos - axis * p_sphere_radius;
- // point inside here
- //printf("solved inside edge\n");
+ // Point inside here.
return true;
}
@@ -655,48 +642,51 @@ public:
Vector3 n = (p_sphere_pos - verts[i + 1]).normalized();
- //r_triangle_contact=verts[i+1]+n*p_sphere_radius;p_sphere_pos+axis*(p_sphere_radius-axis.dot(n2));
r_triangle_contact = verts[i + 1];
r_sphere_contact = p_sphere_pos - n * p_sphere_radius;
- //printf("solved inside point segment 1\n");
return true;
}
if (n2.distance_squared_to(n1) < r2) {
Vector3 n = (p_sphere_pos - verts[i]).normalized();
- //r_triangle_contact=verts[i]+n*p_sphere_radius;p_sphere_pos+axis*(p_sphere_radius-axis.dot(n2));
r_triangle_contact = verts[i];
r_sphere_contact = p_sphere_pos - n * p_sphere_radius;
- //printf("solved inside point segment 1\n");
return true;
}
- break; // It's pointless to continue at this point, so save some cpu cycles
+ break; // It's pointless to continue at this point, so save some CPU cycles.
}
return false;
}
+ static inline bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) {
+
+ return p_point.distance_squared_to(p_circle_pos) <= p_circle_radius * p_circle_radius;
+ }
+
static real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) {
Vector2 line_vec = p_to - p_from;
Vector2 vec_to_line = p_from - p_circle_pos;
- /* create a quadratic formula of the form ax^2 + bx + c = 0 */
+ // Create a quadratic formula of the form ax^2 + bx + c = 0
real_t a, b, c;
a = line_vec.dot(line_vec);
b = 2 * vec_to_line.dot(line_vec);
c = vec_to_line.dot(vec_to_line) - p_circle_radius * p_circle_radius;
- /* solve for t */
+ // Solve for t.
real_t sqrtterm = b * b - 4 * a * c;
- /* if the term we intend to square root is less than 0 then the answer won't be real, so it definitely won't be t in the range 0 to 1 */
+ // If the term we intend to square root is less than 0 then the answer won't be real,
+ // so it definitely won't be t in the range 0 to 1.
if (sqrtterm < 0) return -1;
- /* if we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection) then the following can be skipped and we can just return the equivalent of res1 */
+ // If we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection)
+ // then the following can be skipped and we can just return the equivalent of res1.
sqrtterm = Math::sqrt(sqrtterm);
real_t res1 = (-b - sqrtterm) / (2 * a);
real_t res2 = (-b + sqrtterm) / (2 * a);
@@ -722,7 +712,6 @@ public:
int outside_count = 0;
for (int a = 0; a < polygon.size(); a++) {
- //real_t p_plane.d = (*this) * polygon[a];
real_t dist = p_plane.distance_to(polygon[a]);
if (dist < -CMP_POINT_IN_PLANE_EPSILON) {
location_cache[a] = LOC_INSIDE;
@@ -739,11 +728,11 @@ public:
if (outside_count == 0) {
- return polygon; // no changes
+ return polygon; // No changes.
} else if (inside_count == 0) {
- return Vector<Vector3>(); //empty
+ return Vector<Vector3>(); // Empty.
}
long previous = polygon.size() - 1;
@@ -838,22 +827,11 @@ public:
static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
- ERR_EXPLAIN("Attempt to offset a polyline like a polygon (use offset_polygon_2d instead).");
- ERR_FAIL_COND_V(p_end_type == END_POLYGON, Vector<Vector<Point2> >());
+ ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2> >(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead).");
return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type);
}
- static Vector<Point2> transform_points_2d(const Vector<Point2> &p_points, const Transform2D &p_mat) {
-
- Vector<Point2> points;
-
- for (int i = 0; i < p_points.size(); ++i) {
- points.push_back(p_mat.xform(p_points[i]));
- }
- return points;
- }
-
static Vector<int> triangulate_delaunay_2d(const Vector<Vector2> &p_points) {
Vector<Delaunay2D::Triangle> tr = Delaunay2D::triangulate(p_points);
@@ -899,7 +877,7 @@ public:
return sum > 0.0f;
}
- /* alternate implementation that should be faster */
+ // Alternate implementation that should be faster.
static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
int c = p_polygon.size();
if (c < 3)
@@ -915,7 +893,8 @@ public:
further_away_opposite.y = MIN(p[i].y, further_away_opposite.y);
}
- further_away += (further_away - further_away_opposite) * Vector2(1.221313, 1.512312); // make point outside that won't intersect with points in segment from p_point
+ // Make point outside that won't intersect with points in segment from p_point.
+ further_away += (further_away - further_away_opposite) * Vector2(1.221313, 1.512312);
int intersections = 0;
for (int i = 0; i < c; i++) {
@@ -931,7 +910,8 @@ public:
static PoolVector<PoolVector<Face3> > separate_objects(PoolVector<Face3> p_array);
- static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL); ///< create a "wrap" that encloses the given geometry
+ // Create a "wrap" that encloses the given geometry.
+ static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL);
struct MeshData {
@@ -1013,17 +993,17 @@ public:
Vector<Point2> H;
H.resize(2 * n);
- // Sort points lexicographically
+ // Sort points lexicographically.
P.sort();
- // Build lower hull
+ // Build lower hull.
for (int i = 0; i < n; ++i) {
while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
k--;
H.write[k++] = P[i];
}
- // Build upper hull
+ // Build upper hull.
for (int i = n - 2, t = k + 1; i >= 0; i--) {
while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
k--;
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 7a2e74a413..f04e40cb6c 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -79,6 +79,15 @@ int Math::step_decimals(double p_step) {
return 0;
}
+// Only meant for editor usage in float ranges, where a step of 0
+// means that decimal digits should not be limited in String::num.
+int Math::range_step_decimals(double p_step) {
+ if (p_step < 0.0000000000001) {
+ return 16; // Max value hardcoded in String::num
+ }
+ return step_decimals(p_step);
+}
+
double Math::dectime(double p_value, double p_amount, double p_step) {
double sgn = p_value < 0 ? -1.0 : 1.0;
double val = Math::abs(p_value);
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 0e3bd8a318..9078abea68 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -198,6 +198,13 @@ public:
value += 0.0;
return value;
}
+ static _ALWAYS_INLINE_ int posmod(int p_x, int p_y) {
+ int value = p_x % p_y;
+ if ((value < 0 && p_y > 0) || (value > 0 && p_y < 0)) {
+ value += p_y;
+ }
+ return value;
+ }
static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; }
static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; }
@@ -208,6 +215,17 @@ public:
static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; }
static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; }
+ static _ALWAYS_INLINE_ double lerp_angle(double p_from, double p_to, double p_weight) {
+ double difference = fmod(p_to - p_from, Math_TAU);
+ double distance = fmod(2.0 * difference, Math_TAU) - difference;
+ return p_from + distance * p_weight;
+ }
+ static _ALWAYS_INLINE_ float lerp_angle(float p_from, float p_to, float p_weight) {
+ float difference = fmod(p_to - p_from, (float)Math_TAU);
+ float distance = fmod(2.0f * difference, (float)Math_TAU) - difference;
+ return p_from + distance * p_weight;
+ }
+
static _ALWAYS_INLINE_ double inverse_lerp(double p_from, double p_to, double p_value) { return (p_value - p_from) / (p_to - p_from); }
static _ALWAYS_INLINE_ float inverse_lerp(float p_from, float p_to, float p_value) { return (p_value - p_from) / (p_to - p_from); }
@@ -237,21 +255,22 @@ public:
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
- int64_t rng = max - min;
- return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min;
+ int64_t range = max - min;
+ return range == 0 ? min : min + ((((value - min) % range) + range) % range);
}
static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) {
- double rng = max - min;
- return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ double range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) {
- float rng = max - min;
- return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ float range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
// double only, as these functions are mainly used by the editor and not performance-critical,
static double ease(double p_x, double p_c);
static int step_decimals(double p_step);
+ static int range_step_decimals(double p_step);
static double stepify(double p_value, double p_step);
static double dectime(double p_value, double p_amount, double p_step);
@@ -281,6 +300,11 @@ public:
}
static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) {
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b) {
+ return true;
+ }
+ // Then check for approximate equality.
real_t tolerance = CMP_EPSILON * abs(a);
if (tolerance < CMP_EPSILON) {
tolerance = CMP_EPSILON;
@@ -289,6 +313,11 @@ public:
}
static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t tolerance) {
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b) {
+ return true;
+ }
+ // Then check for approximate equality.
return abs(a - b) < tolerance;
}
diff --git a/core/math/octree.h b/core/math/octree.h
index d6fc9776bc..db15c8a1f8 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -38,10 +38,6 @@
#include "core/print_string.h"
#include "core/variant.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef uint32_t OctreeElementID;
#define OCTREE_ELEMENT_INVALID_ID 0
@@ -568,10 +564,7 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
while (!base.encloses(p_aabb)) {
- if (base.size.x > OCTREE_SIZE_LIMIT) {
- ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(base.size.x > OCTREE_SIZE_LIMIT, "Octree upper size limit reached, does the AABB supplied contain NAN?");
Octant *gp = memnew_allocator(Octant, AL);
octant_count++;
diff --git a/core/math/quat.h b/core/math/quat.h
index 8ed2fa7cc2..3d6602e466 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -38,10 +38,6 @@
#include "core/math/math_funcs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Quat {
public:
real_t x, y, z, w;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 7ff7cac914..4056975da8 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -213,3 +213,8 @@ Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) :
basis(p_basis),
origin(p_origin) {
}
+
+Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz) {
+ basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz);
+ origin = Vector3(ox, oy, oz);
+}
diff --git a/core/math/transform.h b/core/math/transform.h
index 2f43f6b035..90e2b07583 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -34,10 +34,7 @@
#include "core/math/aabb.h"
#include "core/math/basis.h"
#include "core/math/plane.h"
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+#include "core/pool_vector.h"
class Transform {
public:
@@ -86,6 +83,9 @@ public:
_FORCE_INLINE_ AABB xform(const AABB &p_aabb) const;
_FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const;
+ _FORCE_INLINE_ PoolVector<Vector3> xform(const PoolVector<Vector3> &p_array) const;
+ _FORCE_INLINE_ PoolVector<Vector3> xform_inv(const PoolVector<Vector3> &p_array) const;
+
void operator*=(const Transform &p_transform);
Transform operator*(const Transform &p_transform) const;
@@ -108,6 +108,7 @@ public:
operator String() const;
+ Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform() {}
};
@@ -157,22 +158,29 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
}
_FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const {
- /* define vertices */
- Vector3 x = basis.get_axis(0) * p_aabb.size.x;
- Vector3 y = basis.get_axis(1) * p_aabb.size.y;
- Vector3 z = basis.get_axis(2) * p_aabb.size.z;
- Vector3 pos = xform(p_aabb.position);
- //could be even further optimized
- AABB new_aabb;
- new_aabb.position = pos;
- new_aabb.expand_to(pos + x);
- new_aabb.expand_to(pos + y);
- new_aabb.expand_to(pos + z);
- new_aabb.expand_to(pos + x + y);
- new_aabb.expand_to(pos + x + z);
- new_aabb.expand_to(pos + y + z);
- new_aabb.expand_to(pos + x + y + z);
- return new_aabb;
+
+ /* http://dev.theomader.com/transform-bounding-boxes/ */
+ Vector3 min = p_aabb.position;
+ Vector3 max = p_aabb.position + p_aabb.size;
+ Vector3 tmin, tmax;
+ for (int i = 0; i < 3; i++) {
+ tmin[i] = tmax[i] = origin[i];
+ for (int j = 0; j < 3; j++) {
+ real_t e = basis[i][j] * min[j];
+ real_t f = basis[i][j] * max[j];
+ if (e < f) {
+ tmin[i] += e;
+ tmax[i] += f;
+ } else {
+ tmin[i] += f;
+ tmax[i] += e;
+ }
+ }
+ }
+ AABB r_aabb;
+ r_aabb.position = tmin;
+ r_aabb.size = tmax - tmin;
+ return r_aabb;
}
_FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
@@ -201,4 +209,32 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
return ret;
}
+PoolVector<Vector3> Transform::xform(const PoolVector<Vector3> &p_array) const {
+
+ PoolVector<Vector3> array;
+ array.resize(p_array.size());
+
+ PoolVector<Vector3>::Read r = p_array.read();
+ PoolVector<Vector3>::Write w = array.write();
+
+ for (int i = 0; i < p_array.size(); ++i) {
+ w[i] = xform(r[i]);
+ }
+ return array;
+}
+
+PoolVector<Vector3> Transform::xform_inv(const PoolVector<Vector3> &p_array) const {
+
+ PoolVector<Vector3> array;
+ array.resize(p_array.size());
+
+ PoolVector<Vector3>::Read r = p_array.read();
+ PoolVector<Vector3>::Write w = array.write();
+
+ for (int i = 0; i < p_array.size(); ++i) {
+ w[i] = xform_inv(r[i]);
+ }
+ return array;
+}
+
#endif // TRANSFORM_H
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index c44678674a..e8b44ab197 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -32,6 +32,7 @@
#define TRANSFORM_2D_H
#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring
+#include "core/pool_vector.h"
struct Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper":
@@ -110,6 +111,8 @@ struct Transform2D {
_FORCE_INLINE_ Vector2 xform_inv(const Vector2 &p_vec) const;
_FORCE_INLINE_ Rect2 xform(const Rect2 &p_rect) const;
_FORCE_INLINE_ Rect2 xform_inv(const Rect2 &p_rect) const;
+ _FORCE_INLINE_ PoolVector<Vector2> xform(const PoolVector<Vector2> &p_array) const;
+ _FORCE_INLINE_ PoolVector<Vector2> xform_inv(const PoolVector<Vector2> &p_array) const;
operator String() const;
@@ -199,4 +202,32 @@ Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
return new_rect;
}
+PoolVector<Vector2> Transform2D::xform(const PoolVector<Vector2> &p_array) const {
+
+ PoolVector<Vector2> array;
+ array.resize(p_array.size());
+
+ PoolVector<Vector2>::Read r = p_array.read();
+ PoolVector<Vector2>::Write w = array.write();
+
+ for (int i = 0; i < p_array.size(); ++i) {
+ w[i] = xform(r[i]);
+ }
+ return array;
+}
+
+PoolVector<Vector2> Transform2D::xform_inv(const PoolVector<Vector2> &p_array) const {
+
+ PoolVector<Vector2> array;
+ array.resize(p_array.size());
+
+ PoolVector<Vector2>::Read r = p_array.read();
+ PoolVector<Vector2>::Write w = array.write();
+
+ for (int i = 0; i < p_array.size(); ++i) {
+ w[i] = xform_inv(r[i]);
+ }
+ return array;
+}
+
#endif // TRANSFORM_2D_H
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 779a28be66..972bccc0ac 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -98,6 +98,11 @@ real_t Vector2::cross(const Vector2 &p_other) const {
return x * p_other.y - y * p_other.x;
}
+Vector2 Vector2::sign() const {
+
+ return Vector2(SGN(x), SGN(y));
+}
+
Vector2 Vector2::floor() const {
return Vector2(Math::floor(x), Math::floor(y));
@@ -121,6 +126,14 @@ Vector2 Vector2::rotated(real_t p_by) const {
return v;
}
+Vector2 Vector2::posmod(const real_t p_mod) const {
+ return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod));
+}
+
+Vector2 Vector2::posmodv(const Vector2 &p_modv) const {
+ return Vector2(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y));
+}
+
Vector2 Vector2::project(const Vector2 &p_b) const {
return p_b * (dot(p_b) / p_b.length_squared());
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 78a1641c1e..1a73831891 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -38,6 +38,11 @@ struct Vector2i;
struct Vector2 {
+ enum Axis {
+ AXIS_X,
+ AXIS_Y,
+ };
+
union {
real_t x;
real_t width;
@@ -69,6 +74,8 @@ struct Vector2 {
real_t dot(const Vector2 &p_other) const;
real_t cross(const Vector2 &p_other) const;
+ Vector2 posmod(const real_t p_mod) const;
+ Vector2 posmodv(const Vector2 &p_modv) const;
Vector2 project(const Vector2 &p_b) const;
Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const;
@@ -107,8 +114,10 @@ struct Vector2 {
bool operator==(const Vector2 &p_vec2) const;
bool operator!=(const Vector2 &p_vec2) const;
- bool operator<(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y < p_vec2.y) : (x < p_vec2.x); }
- bool operator<=(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
+ bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
+ bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); }
real_t angle() const;
@@ -129,6 +138,7 @@ struct Vector2 {
return Vector2(y, -x);
}
+ Vector2 sign() const;
Vector2 floor() const;
Vector2 ceil() const;
Vector2 round() const;
@@ -141,10 +151,7 @@ struct Vector2 {
x = p_x;
y = p_y;
}
- _FORCE_INLINE_ Vector2() {
- x = 0;
- y = 0;
- }
+ _FORCE_INLINE_ Vector2() { x = y = 0; }
};
_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const {
@@ -262,6 +269,11 @@ typedef Vector2 Point2;
struct Vector2i {
+ enum Axis {
+ AXIS_X,
+ AXIS_Y,
+ };
+
union {
int x;
int width;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 811a207138..c68b075613 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -31,9 +31,7 @@
#ifndef VECTOR3_H
#define VECTOR3_H
-#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
-#include "core/typedefs.h"
#include "core/ustring.h"
class Basis;
@@ -110,6 +108,8 @@ struct Vector3 {
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const;
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_b) const;
+ _FORCE_INLINE_ Vector3 posmod(const real_t p_mod) const;
+ _FORCE_INLINE_ Vector3 posmodv(const Vector3 &p_modv) const;
_FORCE_INLINE_ Vector3 project(const Vector3 &p_b) const;
_FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const;
@@ -141,15 +141,17 @@ struct Vector3 {
_FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<(const Vector3 &p_v) const;
_FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const;
+ _FORCE_INLINE_ bool operator>(const Vector3 &p_v) const;
+ _FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const;
operator String() const;
- _FORCE_INLINE_ Vector3() { x = y = z = 0; }
_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
y = p_y;
z = p_z;
}
+ _FORCE_INLINE_ Vector3() { x = y = z = 0; }
};
// Should be included after class definition, otherwise we get circular refs
@@ -219,10 +221,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);
}
@@ -237,6 +235,14 @@ real_t Vector3::distance_squared_to(const Vector3 &p_b) const {
return (p_b - *this).length_squared();
}
+Vector3 Vector3::posmod(const real_t p_mod) const {
+ return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod));
+}
+
+Vector3 Vector3::posmodv(const Vector3 &p_modv) const {
+ return Vector3(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z));
+}
+
Vector3 Vector3::project(const Vector3 &p_b) const {
return p_b * (dot(p_b) / p_b.length_squared());
}
@@ -361,6 +367,18 @@ bool Vector3::operator<(const Vector3 &p_v) const {
}
}
+bool Vector3::operator>(const Vector3 &p_v) const {
+
+ if (Math::is_equal_approx(x, p_v.x)) {
+ if (Math::is_equal_approx(y, p_v.y))
+ return z > p_v.z;
+ else
+ return y > p_v.y;
+ } else {
+ return x > p_v.x;
+ }
+}
+
bool Vector3::operator<=(const Vector3 &p_v) const {
if (Math::is_equal_approx(x, p_v.x)) {
@@ -373,6 +391,18 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
}
}
+bool Vector3::operator>=(const Vector3 &p_v) const {
+
+ if (Math::is_equal_approx(x, p_v.x)) {
+ if (Math::is_equal_approx(y, p_v.y))
+ return z >= p_v.z;
+ else
+ return y > p_v.y;
+ } else {
+ return x > p_v.x;
+ }
+}
+
_FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
return p_a.cross(p_b);
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 32d2b805f6..390989ac91 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -52,8 +52,7 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V
type = ObjectDB::get_instance(p_id)->get_class();
print_line("Failed method: " + type + ":" + p_method + " target ID: " + itos(p_id));
statistics();
- ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
+ ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
@@ -103,8 +102,7 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
type = ObjectDB::get_instance(p_id)->get_class();
print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id));
statistics();
- ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
+ ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
@@ -136,8 +134,7 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
type = ObjectDB::get_instance(p_id)->get_class();
print_line("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id));
statistics();
- ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
+ ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings.");
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
@@ -256,7 +253,7 @@ void MessageQueue::_call_function(Object *p_target, const StringName &p_func, co
p_target->call(p_func, argptrs, p_argcount, ce);
if (p_show_error && ce.error != Variant::CallError::CALL_OK) {
- ERR_PRINTS("Error calling deferred method: " + Variant::get_call_error_text(p_target, p_func, argptrs, p_argcount, ce));
+ ERR_PRINTS("Error calling deferred method: " + Variant::get_call_error_text(p_target, p_func, argptrs, p_argcount, ce) + ".");
}
}
diff --git a/core/method_bind.h b/core/method_bind.h
index 1b0c3b27c0..7bb75e778f 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -38,10 +38,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifdef DEBUG_ENABLED
#define DEBUG_METHODS_ENABLED
#endif
diff --git a/core/node_path.cpp b/core/node_path.cpp
index a4b7cbe2eb..8244785d84 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -375,8 +375,7 @@ NodePath::NodePath(const String &p_path) {
if (str == "") {
if (path[i] == 0) continue; // Allow end-of-path :
- ERR_EXPLAIN("Invalid NodePath: " + p_path);
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid NodePath: " + p_path + ".");
}
subpath.push_back(str);
diff --git a/core/node_path.h b/core/node_path.h
index 24725123d6..1b21c4ef1c 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -34,10 +34,6 @@
#include "core/string_name.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class NodePath {
struct Data {
diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h
index e52d36a859..5ea6d8b0d4 100644
--- a/core/oa_hash_map.h
+++ b/core/oa_hash_map.h
@@ -62,7 +62,7 @@ private:
static const uint32_t EMPTY_HASH = 0;
static const uint32_t DELETED_HASH_BIT = 1 << 31;
- _FORCE_INLINE_ uint32_t _hash(const TKey &p_key) {
+ _FORCE_INLINE_ uint32_t _hash(const TKey &p_key) const {
uint32_t hash = Hasher::hash(p_key);
if (hash == EMPTY_HASH) {
@@ -74,12 +74,11 @@ private:
return hash;
}
- _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash) {
+ _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash) const {
p_hash = p_hash & ~DELETED_HASH_BIT; // we don't care if it was deleted or not
uint32_t original_pos = p_hash % capacity;
-
- return p_pos - original_pos;
+ return (p_pos - original_pos) % capacity;
}
_FORCE_INLINE_ void _construct(uint32_t p_pos, uint32_t p_hash, const TKey &p_key, const TValue &p_value) {
@@ -90,7 +89,7 @@ private:
num_elements++;
}
- bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) {
+ bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const {
uint32_t hash = _hash(p_key);
uint32_t pos = hash % capacity;
uint32_t distance = 0;
@@ -151,17 +150,17 @@ private:
distance++;
}
}
- void _resize_and_rehash() {
+
+ void _resize_and_rehash(uint32_t p_new_capacity) {
+
+ uint32_t old_capacity = capacity;
+ capacity = p_new_capacity;
TKey *old_keys = keys;
TValue *old_values = values;
uint32_t *old_hashes = hashes;
- uint32_t old_capacity = capacity;
-
- capacity = old_capacity * 2;
num_elements = 0;
-
keys = memnew_arr(TKey, capacity);
values = memnew_arr(TValue, capacity);
hashes = memnew_arr(uint32_t, capacity);
@@ -186,10 +185,38 @@ private:
memdelete_arr(old_hashes);
}
+ void _resize_and_rehash() {
+ _resize_and_rehash(capacity * 2);
+ }
+
public:
_FORCE_INLINE_ uint32_t get_capacity() const { return capacity; }
_FORCE_INLINE_ uint32_t get_num_elements() const { return num_elements; }
+ bool empty() const {
+ return num_elements == 0;
+ }
+
+ void clear() {
+
+ for (uint32_t i = 0; i < capacity; i++) {
+
+ if (hashes[i] == EMPTY_HASH) {
+ continue;
+ }
+
+ if (hashes[i] & DELETED_HASH_BIT) {
+ continue;
+ }
+
+ hashes[i] = EMPTY_HASH;
+ values[i].~TValue();
+ keys[i].~TKey();
+ }
+
+ num_elements = 0;
+ }
+
void insert(const TKey &p_key, const TValue &p_value) {
if ((float)num_elements / (float)capacity > 0.9) {
@@ -219,7 +246,7 @@ public:
* if r_data is not NULL then the value will be written to the object
* it points to.
*/
- bool lookup(const TKey &p_key, TValue &r_data) {
+ bool lookup(const TKey &p_key, TValue &r_data) const {
uint32_t pos = 0;
bool exists = _lookup_pos(p_key, pos);
@@ -232,7 +259,7 @@ public:
return false;
}
- _FORCE_INLINE_ bool has(const TKey &p_key) {
+ _FORCE_INLINE_ bool has(const TKey &p_key) const {
uint32_t _pos = 0;
return _lookup_pos(p_key, _pos);
}
@@ -251,6 +278,16 @@ public:
num_elements--;
}
+ /**
+ * reserves space for a number of elements, useful to avoid many resizes and rehashes
+ * if adding a known (possibly large) number of elements at once, must be larger than old
+ * capacity.
+ **/
+ void reserve(uint32_t p_new_capacity) {
+ ERR_FAIL_COND(p_new_capacity < capacity);
+ _resize_and_rehash(p_new_capacity);
+ }
+
struct Iterator {
bool valid;
@@ -302,6 +339,9 @@ public:
return it;
}
+ OAHashMap(const OAHashMap &) = delete; // Delete the copy constructor so we don't get unexpected copies and dangling pointers.
+ OAHashMap &operator=(const OAHashMap &) = delete; // Same for assignment operator.
+
OAHashMap(uint32_t p_initial_capacity = 64) {
capacity = p_initial_capacity;
@@ -312,7 +352,7 @@ public:
hashes = memnew_arr(uint32_t, p_initial_capacity);
for (uint32_t i = 0; i < p_initial_capacity; i++) {
- hashes[i] = 0;
+ hashes[i] = EMPTY_HASH;
}
}
diff --git a/core/object.cpp b/core/object.cpp
index 3367d6b6c3..62bfa31480 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -709,20 +709,17 @@ static void _test_call_error(const StringName &p_func, const Variant::CallError
break;
case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected));
- ERR_FAIL();
+ ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected) + ".");
break;
}
case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
- ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument));
- ERR_FAIL();
+ ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument) + ".");
break;
}
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
- ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument));
- ERR_FAIL();
+ ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument) + ".");
break;
}
case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
@@ -739,15 +736,9 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
if (p_method == CoreStringNames::get_singleton()->_free) {
#ifdef DEBUG_ENABLED
- if (Object::cast_to<Reference>(this)) {
- ERR_EXPLAIN("Can't 'free' a reference.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(Object::cast_to<Reference>(this), "Can't 'free' a reference.");
- if (_lock_index.get() > 1) {
- ERR_EXPLAIN("Object is locked and can't be freed.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(_lock_index.get() > 1, "Object is locked and can't be freed.");
#endif
//must be here, must be before everything,
@@ -835,8 +826,7 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
Variant::CallError ce;
Variant ret = call(p_method, argptrs, p_args.size(), ce);
if (ce.error != Variant::CallError::CALL_OK) {
- ERR_EXPLAIN("Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce));
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + ".");
}
return ret;
}
@@ -888,15 +878,13 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
if (Object::cast_to<Reference>(this)) {
r_error.argument = 0;
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- ERR_EXPLAIN("Can't 'free' a reference.");
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "Can't 'free' a reference.");
}
if (_lock_index.get() > 1) {
r_error.argument = 0;
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- ERR_EXPLAIN("Object is locked and can't be freed.");
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "Object is locked and can't be freed.");
}
#endif
@@ -1172,10 +1160,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
#ifdef DEBUG_ENABLED
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name);
//check in script
- if (!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name)) {
- ERR_EXPLAIN("Can't emit non-existing signal " + String("\"") + p_name + "\".");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name), ERR_UNAVAILABLE, "Can't emit non-existing signal " + String("\"") + p_name + "\".");
#endif
//not connected? just return
return ERR_UNAVAILABLE;
@@ -1240,7 +1225,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
//most likely object is not initialized yet, do not throw error.
} else {
- ERR_PRINTS("Error calling method from signal '" + String(p_name) + "': " + Variant::get_call_error_text(target, c.method, args, argc, ce));
+ ERR_PRINTS("Error calling method from signal '" + String(p_name) + "': " + Variant::get_call_error_text(target, c.method, args, argc, ce) + ".");
err = ERR_METHOD_NOT_FOUND;
}
}
@@ -1415,8 +1400,9 @@ void Object::get_signal_connection_list(const StringName &p_signal, List<Connect
p_connections->push_back(s->slot_map.getv(i).conn);
}
-bool Object::has_persistent_signal_connections() const {
+int Object::get_persistent_signal_connection_count() const {
+ int count = 0;
const StringName *S = NULL;
while ((S = signal_map.next(S))) {
@@ -1424,13 +1410,13 @@ bool Object::has_persistent_signal_connections() const {
const Signal *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
-
- if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST)
- return true;
+ if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
+ count += 1;
+ }
}
}
- return false;
+ return count;
}
void Object::get_signals_connected_to_this(List<Connection> *p_connections) const {
@@ -1463,10 +1449,8 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
#endif
}
- if (!signal_is_valid) {
- ERR_EXPLAIN("In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'.");
+
signal_map[p_signal] = Signal();
s = &signal_map[p_signal];
}
@@ -1477,8 +1461,7 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
s->slot_map[target].reference_count++;
return OK;
} else {
- ERR_EXPLAIN("Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object.");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object.");
}
}
@@ -1514,8 +1497,7 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const
if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal))
return false;
- ERR_EXPLAIN("Nonexistent signal: " + p_signal);
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
}
Signal::Target target(p_to_object->get_instance_id(), p_to_method);
@@ -1533,21 +1515,13 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
ERR_FAIL_NULL(p_to_object);
Signal *s = signal_map.getptr(p_signal);
- if (!s) {
- ERR_EXPLAIN("Nonexistent signal: " + p_signal);
- ERR_FAIL();
- }
- if (s->lock > 0) {
- ERR_EXPLAIN("Attempt to disconnect signal '" + p_signal + "' while emitting (locks: " + itos(s->lock) + ")");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!s, "Nonexistent signal: " + p_signal + ".");
+
+ ERR_FAIL_COND_MSG(s->lock > 0, "Attempt to disconnect signal '" + p_signal + "' while emitting (locks: " + itos(s->lock) + ").");
Signal::Target target(p_to_object->get_instance_id(), p_to_method);
- if (!s->slot_map.has(target)) {
- ERR_EXPLAIN("Disconnecting nonexistent signal '" + p_signal + "', slot: " + itos(target._id) + ":" + target.method);
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!s->slot_map.has(target), "Disconnecting nonexistent signal '" + p_signal + "', slot: " + itos(target._id) + ":" + target.method + ".");
Signal::Slot *slot = &s->slot_map[target];
@@ -1974,10 +1948,7 @@ Object::~Object() {
Signal *s = &signal_map[*S];
- if (s->lock) {
- ERR_EXPLAIN("Attempt to delete an object in the middle of a signal emission from it");
- ERR_CONTINUE(s->lock > 0);
- }
+ ERR_CONTINUE_MSG(s->lock > 0, "Attempt to delete an object in the middle of a signal emission from it.");
//brute force disconnect for performance
int slot_count = s->slot_map.size();
diff --git a/core/object.h b/core/object.h
index 1e0b22c086..ac8620757c 100644
--- a/core/object.h
+++ b/core/object.h
@@ -58,7 +58,7 @@ enum PropertyHint {
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- PROPERTY_HINT_SPRITE_FRAME,
+ PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat. Keeping now for GDNative compat.
PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -104,7 +104,8 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
PROPERTY_USAGE_CATEGORY = 256,
- //those below are deprecated thanks to ClassDB's now class value cache
+ // FIXME: Drop in 4.0, possibly reorder other flags?
+ // Those below are deprecated thanks to ClassDB's now class value cache
//PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
//PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
@@ -121,6 +122,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
+ PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
@@ -179,6 +181,15 @@ struct PropertyInfo {
usage(PROPERTY_USAGE_DEFAULT) {
}
+ bool operator==(const PropertyInfo &p_info) const {
+ return ((type == p_info.type) &&
+ (name == p_info.name) &&
+ (class_name == p_info.class_name) &&
+ (hint == p_info.hint) &&
+ (hint_string == p_info.hint_string) &&
+ (usage == p_info.usage));
+ }
+
bool operator<(const PropertyInfo &p_info) const {
return name < p_info.name;
}
@@ -696,7 +707,7 @@ public:
void get_signal_list(List<MethodInfo> *p_signals) const;
void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
void get_all_signal_connections(List<Connection> *p_connections) const;
- bool has_persistent_signal_connections() const;
+ int get_persistent_signal_connection_count() const;
void get_signals_connected_to_this(List<Connection> *p_connections) const;
Error connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
@@ -783,8 +794,13 @@ public:
static int get_object_count();
_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
+ rw_lock->read_lock();
+
+ bool exists = instance_checks.has(p_ptr);
+
+ rw_lock->read_unlock();
- return instance_checks.has(p_ptr);
+ return exists;
}
};
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 0cdb5b41b7..b444f0ae1e 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -179,14 +179,6 @@ Error DirAccess::make_dir_recursive(String p_dir) {
return OK;
}
-String DirAccess::get_next(bool *p_is_dir) {
-
- String next = get_next();
- if (p_is_dir)
- *p_is_dir = current_is_dir();
- return next;
-}
-
String DirAccess::fix_path(String p_path) const {
switch (_access_type) {
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index bde19bd5ae..d3eb1e13f6 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -34,10 +34,6 @@
#include "core/typedefs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
//@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies
class DirAccess {
public:
@@ -71,7 +67,6 @@ protected:
public:
virtual Error list_dir_begin() = 0; ///< This starts dir listing
- virtual String get_next(bool *p_is_dir); // compatibility
virtual String get_next() = 0;
virtual bool current_is_dir() const = 0;
virtual bool current_is_hidden() const = 0;
@@ -98,6 +93,18 @@ public:
virtual Error rename(String p_from, String p_to) = 0;
virtual Error remove(String p_name) = 0;
+ // Meant for editor code when we want to quickly remove a file without custom
+ // handling (e.g. removing a cache file).
+ static void remove_file_or_error(String p_path) {
+ DirAccess *da = create(ACCESS_FILESYSTEM);
+ if (da->file_exists(p_path)) {
+ if (da->remove(p_path) != OK) {
+ ERR_FAIL_MSG("Cannot remove file or directory: " + p_path);
+ }
+ }
+ memdelete(da);
+ }
+
virtual String get_filesystem_type() const = 0;
static String get_full_path(const String &p_path, AccessType p_access);
static DirAccess *create_for_path(const String &p_path);
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 7509050b2b..9a8315a3bb 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -30,9 +30,9 @@
#include "file_access.h"
+#include "core/crypto/crypto_core.h"
#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"
@@ -599,8 +599,7 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err
if (r_error) { // if error requested, do not throw error
return Vector<uint8_t>();
}
- ERR_EXPLAIN("Can't open file from path: " + String(p_path));
- ERR_FAIL_V(Vector<uint8_t>());
+ ERR_FAIL_V_MSG(Vector<uint8_t>(), "Can't open file from path: " + String(p_path) + ".");
}
Vector<uint8_t> data;
data.resize(f->get_len());
@@ -620,8 +619,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
if (r_error) {
return String();
}
- ERR_EXPLAIN("Can't get file as string from path: " + String(p_path));
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Can't get file as string from path: " + String(p_path) + ".");
}
String ret;
diff --git a/core/os/input.cpp b/core/os/input.cpp
index f04d4a1b3e..51cb41b184 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -80,6 +80,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
+ ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
diff --git a/core/os/input.h b/core/os/input.h
index de04f239e6..a12ded176b 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -100,6 +100,7 @@ public:
virtual uint64_t get_joy_vibration_timestamp(int p_device) = 0;
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0) = 0;
virtual void stop_joy_vibration(int p_device) = 0;
+ virtual void vibrate_handheld(int p_duration_ms = 500) = 0;
virtual Point2 get_mouse_position() const = 0;
virtual Point2 get_last_mouse_speed() const = 0;
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index a40a50cfce..30fca0c155 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -450,7 +450,7 @@ bool InputEventMouseButton::is_doubleclick() const {
Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
- Vector2 g = p_xform.xform(get_global_position());
+ Vector2 g = get_global_position();
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
Ref<InputEventMouseButton> mb;
@@ -577,7 +577,7 @@ Vector2 InputEventMouseMotion::get_speed() const {
Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
- Vector2 g = p_xform.xform(get_global_position());
+ Vector2 g = get_global_position();
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
Vector2 r = p_xform.basis_xform(get_relative());
Vector2 s = p_xform.basis_xform(get_speed());
diff --git a/core/os/input_event.h b/core/os/input_event.h
index 4f5762e756..28658e3865 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -38,10 +38,6 @@
#include "core/ustring.h"
/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
-/**
* Input Event classes. These are used in the main loop.
* The events are pretty obvious.
*/
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 58a0807579..5c8a2e90e9 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -33,10 +33,6 @@
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/*
Special Key:
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 9946ced2f3..eca3b2a7f4 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -49,6 +49,8 @@ void MainLoop::_bind_methods() {
BIND_VMETHOD(MethodInfo("_drop_files", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "from_screen")));
BIND_VMETHOD(MethodInfo("_finalize"));
+ BIND_VMETHOD(MethodInfo("_global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta")));
+
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
@@ -115,6 +117,12 @@ void MainLoop::drop_files(const Vector<String> &p_files, int p_from_screen) {
get_script_instance()->call("_drop_files", p_files, p_from_screen);
}
+void MainLoop::global_menu_action(const Variant &p_id, const Variant &p_meta) {
+
+ if (get_script_instance())
+ get_script_instance()->call("_global_menu_action", p_id, p_meta);
+}
+
void MainLoop::finish() {
if (get_script_instance()) {
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index ad734d3fc8..aca920efcb 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -35,10 +35,6 @@
#include "core/reference.h"
#include "core/script_language.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MainLoop : public Object {
GDCLASS(MainLoop, Object);
@@ -64,6 +60,8 @@ public:
NOTIFICATION_WM_ABOUT = 1011,
NOTIFICATION_CRASH = 1012,
NOTIFICATION_OS_IME_UPDATE = 1013,
+ NOTIFICATION_APP_RESUMED = 1014,
+ NOTIFICATION_APP_PAUSED = 1015,
};
virtual void input_event(const Ref<InputEvent> &p_event);
@@ -75,6 +73,7 @@ public:
virtual void finish();
virtual void drop_files(const Vector<String> &p_files, int p_from_screen = 0);
+ virtual void global_menu_action(const Variant &p_id, const Variant &p_meta);
void set_init_script(const Ref<Script> &p_init_script);
diff --git a/core/os/memory.h b/core/os/memory.h
index e073b11e76..8778cb63ad 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -35,10 +35,6 @@
#include <stddef.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifndef PAD_ALIGN
#define PAD_ALIGN 16 //must always be greater than this at much
#endif
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 925154af7d..7531900480 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -186,6 +186,11 @@ int OS::get_process_id() const {
return -1;
};
+void OS::vibrate_handheld(int p_duration_ms) {
+
+ WARN_PRINTS("vibrate_handheld() only works with Android and iOS");
+}
+
bool OS::is_stdout_verbose() const {
return _verbose_stdout;
@@ -268,8 +273,7 @@ void OS::print_all_resources(String p_to_file) {
_OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err);
if (err != OK) {
_OSPRF = NULL;
- ERR_EXPLAIN("Can't print all resources to file: " + String(p_to_file));
- ERR_FAIL();
+ ERR_FAIL_MSG("Can't print all resources to file: " + String(p_to_file) + ".");
}
}
@@ -487,10 +491,7 @@ void OS::_ensure_user_data_dir() {
da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = da->make_dir_recursive(dd);
- if (err != OK) {
- ERR_EXPLAIN("Error attempting to create data dir: " + dd);
- }
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Error attempting to create data dir: " + dd + ".");
memdelete(da);
}
diff --git a/core/os/os.h b/core/os/os.h
index 2224d3b006..9b46b43081 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -41,10 +41,6 @@
#include <stdarg.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Mutex;
class OS {
@@ -147,6 +143,11 @@ public:
static OS *get_singleton();
+ virtual void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta){};
+ virtual void global_menu_add_separator(const String &p_menu){};
+ virtual void global_menu_remove_item(const String &p_menu, int p_idx){};
+ virtual void global_menu_clear(const String &p_menu){};
+
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR);
void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
@@ -269,6 +270,7 @@ public:
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL) = 0;
virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
+ virtual void vibrate_handheld(int p_duration_ms = 500);
virtual Error shell_open(String p_uri);
virtual Error set_cwd(const String &p_cwd);
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index ccbba0dacd..a0862dce84 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -33,10 +33,6 @@
#include "core/error_list.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Semaphore {
protected:
static Semaphore *(*create_func)();
diff --git a/core/os/thread.h b/core/os/thread.h
index e7a6e8cb1f..169280a208 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -34,10 +34,6 @@
#include "core/typedefs.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*ThreadCreateCallback)(void *p_userdata);
class Thread {
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index 094352b5cc..6c1f2756f2 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -204,10 +204,8 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
/* Then search again */
if (!find_hole(&new_entry_indices_pos, size_to_alloc)) {
-
mt_unlock();
- ERR_EXPLAIN("Memory can't be compacted further");
- ERR_FAIL_V(POOL_ALLOCATOR_INVALID_ID);
+ ERR_FAIL_V_MSG(POOL_ALLOCATOR_INVALID_ID, "Memory can't be compacted further.");
}
}
@@ -217,8 +215,7 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
if (!found_free_entry) {
mt_unlock();
- ERR_EXPLAIN("No free entry found in PoolAllocator");
- ERR_FAIL_V(POOL_ALLOCATOR_INVALID_ID);
+ ERR_FAIL_V_MSG(POOL_ALLOCATOR_INVALID_ID, "No free entry found in PoolAllocator.");
}
/* move all entry indices up, make room for this one */
@@ -539,6 +536,10 @@ void PoolAllocator::unlock(ID p_mem) {
return;
mt_lock();
Entry *e = get_entry(p_mem);
+ if (!e) {
+ mt_unlock();
+ ERR_FAIL_COND(!e);
+ }
if (e->lock == 0) {
mt_unlock();
ERR_PRINT("e->lock == 0");
@@ -611,7 +612,7 @@ PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_
PoolAllocator::PoolAllocator(int p_align, int p_size, bool p_needs_locking, int p_max_entries) {
ERR_FAIL_COND(p_align < 1);
- mem_ptr = Memory::alloc_static(p_size + p_align, "PoolAllocator()");
+ mem_ptr = Memory::alloc_static(p_size + p_align, true);
uint8_t *mem8 = (uint8_t *)mem_ptr;
uint64_t ofs = (uint64_t)mem8;
if (ofs % p_align)
diff --git a/core/pool_vector.cpp b/core/pool_vector.cpp
index b9d2316315..50ea898bef 100644
--- a/core/pool_vector.cpp
+++ b/core/pool_vector.cpp
@@ -66,6 +66,5 @@ void MemoryPool::cleanup() {
memdelete_arr(allocs);
memdelete(alloc_mutex);
- ERR_EXPLAINC("There are still MemoryPool allocs in use at exit!");
- ERR_FAIL_COND(allocs_used > 0);
+ ERR_FAIL_COND_MSG(allocs_used > 0, "There are still MemoryPool allocs in use at exit!");
}
diff --git a/core/pool_vector.h b/core/pool_vector.h
index 98a52c6938..957a72483c 100644
--- a/core/pool_vector.h
+++ b/core/pool_vector.h
@@ -77,10 +77,6 @@ struct MemoryPool {
static void cleanup();
};
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
template <class T>
class PoolVector {
@@ -102,8 +98,7 @@ class PoolVector {
MemoryPool::alloc_mutex->lock();
if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
MemoryPool::alloc_mutex->unlock();
- ERR_EXPLAINC("All memory pool allocations are in use, can't COW.");
- ERR_FAIL();
+ ERR_FAIL_MSG("All memory pool allocations are in use, can't COW.");
}
MemoryPool::Alloc *old_alloc = alloc;
@@ -458,7 +453,7 @@ public:
bool is_locked() const { return alloc && alloc->lock > 0; }
- inline const T operator[](int p_index) const;
+ inline T operator[](int p_index) const;
Error resize(int p_size);
@@ -502,7 +497,7 @@ void PoolVector<T>::push_back(const T &p_val) {
}
template <class T>
-const T PoolVector<T>::operator[](int p_index) const {
+T PoolVector<T>::operator[](int p_index) const {
CRASH_BAD_INDEX(p_index, size());
@@ -524,8 +519,7 @@ Error PoolVector<T>::resize(int p_size) {
MemoryPool::alloc_mutex->lock();
if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
MemoryPool::alloc_mutex->unlock();
- ERR_EXPLAINC("All memory pool allocations are in use.");
- ERR_FAIL_V(ERR_OUT_OF_MEMORY);
+ ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "All memory pool allocations are in use.");
}
//take one from the free list
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index c1d4967f55..ec2c5ecbb3 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -500,8 +500,7 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
if (hdr[0] != 'E' || hdr[1] != 'C' || hdr[2] != 'F' || hdr[3] != 'G') {
memdelete(f);
- ERR_EXPLAIN("Corrupted header in binary project.binary (not ECFG)");
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Corrupted header in binary project.binary (not ECFG).");
}
uint32_t count = f->get_32();
@@ -522,8 +521,7 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
f->get_buffer(d.ptrw(), vlen);
Variant value;
err = decode_variant(value, d.ptr(), d.size(), NULL, true);
- ERR_EXPLAIN("Error decoding property: " + key);
- ERR_CONTINUE(err != OK);
+ ERR_CONTINUE_MSG(err != OK, "Error decoding property: " + key + ".");
set(key, value);
}
@@ -577,8 +575,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
config_version = value;
if (config_version > CONFIG_VERSION) {
memdelete(f);
- ERR_EXPLAIN(vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
- ERR_FAIL_V(ERR_FILE_CANT_OPEN);
+ ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
}
} else {
if (section == String()) {
@@ -645,11 +642,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
Error err;
FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
- if (err != OK) {
-
- ERR_EXPLAIN("Couldn't save project.binary at " + p_file);
- ERR_FAIL_COND_V(err, err);
- }
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.binary at " + p_file + ".");
uint8_t hdr[4] = { 'E', 'C', 'F', 'G' };
file->store_buffer(hdr, 4);
@@ -738,10 +731,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
Error err;
FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
- if (err) {
- ERR_EXPLAIN("Couldn't save project.godot - " + p_file);
- ERR_FAIL_COND_V(err, err);
- }
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.godot - " + p_file + ".");
file->store_line("; Engine configuration file.");
file->store_line("; It's best edited using the editor UI and not directly,");
@@ -872,8 +862,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
return _save_settings_binary(p_path, props, p_custom, custom_features);
else {
- ERR_EXPLAIN("Unknown config file format: " + p_path);
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown config file format: " + p_path + ".");
}
}
@@ -1011,6 +1000,8 @@ ProjectSettings::ProjectSettings() {
Ref<InputEventJoypadButton> joyb;
GLOBAL_DEF("application/config/name", "");
+ GLOBAL_DEF("application/config/description", "");
+ custom_prop_info["application/config/description"] = PropertyInfo(Variant::STRING, "application/config/description", PROPERTY_HINT_MULTILINE_TEXT);
GLOBAL_DEF("application/run/main_scene", "");
custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res");
GLOBAL_DEF("application/run/disable_stdout", false);
@@ -1030,6 +1021,9 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("editor/search_in_file_extensions", extensions);
custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::POOL_STRING_ARRAY, "editor/search_in_file_extensions");
+ GLOBAL_DEF("editor/script_templates_search_path", "res://script_templates");
+ custom_prop_info["editor/script_templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script_templates_search_path", PROPERTY_HINT_DIR);
+
action = Dictionary();
action["deadzone"] = Variant(0.5f);
events = Array();
diff --git a/core/project_settings.h b/core/project_settings.h
index d7651417d5..a8deab028c 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -35,10 +35,6 @@
#include "core/os/thread_safe.h"
#include "core/set.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ProjectSettings : public Object {
GDCLASS(ProjectSettings, Object);
diff --git a/core/reference.h b/core/reference.h
index 8a19f846c7..20ee22ddfc 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -36,9 +36,6 @@
#include "core/ref_ptr.h"
#include "core/safe_refcount.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Reference : public Object {
GDCLASS(Reference, Object);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e442546124..efc77bde48 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -34,6 +34,8 @@
#include "core/class_db.h"
#include "core/compressed_translation.h"
#include "core/core_string_names.h"
+#include "core/crypto/crypto.h"
+#include "core/crypto/hashing_context.h"
#include "core/engine.h"
#include "core/func_ref.h"
#include "core/input_map.h"
@@ -70,6 +72,8 @@ static Ref<ResourceFormatLoaderBinary> resource_loader_binary;
static Ref<ResourceFormatImporter> resource_format_importer;
static Ref<ResourceFormatLoaderImage> resource_format_image;
static Ref<TranslationLoaderPO> resource_format_po;
+static Ref<ResourceFormatSaverCrypto> resource_format_saver_crypto;
+static Ref<ResourceFormatLoaderCrypto> resource_format_loader_crypto;
static _ResourceLoader *_resource_loader = NULL;
static _ResourceSaver *_resource_saver = NULL;
@@ -151,7 +155,19 @@ void register_core_types() {
ClassDB::register_class<StreamPeerTCP>();
ClassDB::register_class<TCP_Server>();
ClassDB::register_class<PacketPeerUDP>();
+
+ // Crypto
+ ClassDB::register_class<HashingContext>();
+ ClassDB::register_custom_instance_class<X509Certificate>();
+ ClassDB::register_custom_instance_class<CryptoKey>();
+ ClassDB::register_custom_instance_class<Crypto>();
ClassDB::register_custom_instance_class<StreamPeerSSL>();
+
+ resource_format_saver_crypto.instance();
+ ResourceSaver::add_resource_format_saver(resource_format_saver_crypto);
+ resource_format_loader_crypto.instance();
+ ResourceLoader::add_resource_format_loader(resource_format_loader_crypto);
+
ClassDB::register_virtual_class<IP>();
ClassDB::register_virtual_class<PacketPeer>();
ClassDB::register_class<PacketPeerStream>();
@@ -211,6 +227,9 @@ void register_core_settings() {
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"));
+
+ GLOBAL_DEF("network/ssl/certificates", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
}
void register_core_singletons() {
@@ -272,6 +291,11 @@ void unregister_core_types() {
ResourceLoader::remove_resource_format_loader(resource_format_po);
resource_format_po.unref();
+ ResourceSaver::remove_resource_format_saver(resource_format_saver_crypto);
+ resource_format_saver_crypto.unref();
+ ResourceLoader::remove_resource_format_loader(resource_format_loader_crypto);
+ resource_format_loader_crypto.unref();
+
if (ip)
memdelete(ip);
diff --git a/core/register_core_types.h b/core/register_core_types.h
index b5a6aa985b..2d397b55f9 100644
--- a/core/register_core_types.h
+++ b/core/register_core_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_CORE_TYPES_H
#define REGISTER_CORE_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_core_types();
void register_core_settings();
void register_core_singletons();
diff --git a/core/resource.cpp b/core/resource.cpp
index 74e2c1ed6b..5a5efa4644 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -75,8 +75,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
bool exists = ResourceCache::resources.has(p_path);
ResourceCache::lock->read_unlock();
- ERR_EXPLAIN("Another resource is loaded from path: " + p_path + " (possible cyclic resource inclusion)");
- ERR_FAIL_COND(exists);
+ ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path: " + p_path + " (possible cyclic resource inclusion).");
}
}
path_cache = p_path;
@@ -277,8 +276,7 @@ void Resource::notify_change_to_owners() {
for (Set<ObjectID>::Element *E = owners.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
- ERR_EXPLAIN("Object was deleted, while still owning a resource");
- ERR_CONTINUE(!obj); //wtf
+ ERR_CONTINUE_MSG(!obj, "Object was deleted, while still owning a resource."); //wtf
//TODO store string
obj->call("resource_changed", RES(this));
}
@@ -427,7 +425,7 @@ Resource::~Resource() {
ResourceCache::lock->write_unlock();
}
if (owners.size()) {
- WARN_PRINT("Resource is still owned");
+ WARN_PRINT("Resource is still owned.");
}
}
diff --git a/core/resource.h b/core/resource.h
index 853b2859c7..038b4f6278 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -38,10 +38,6 @@
#include "core/safe_refcount.h"
#include "core/self_list.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#define RES_BASE_EXTENSION(m_ext) \
public: \
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
diff --git a/core/rid.h b/core/rid.h
index c7a71a03a0..381eee645b 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -37,10 +37,6 @@
#include "core/set.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class RID_OwnerBase;
class RID_Data {
diff --git a/core/script_debugger_local.cpp b/core/script_debugger_local.cpp
index ac4dafcf59..e61f9f7158 100644
--- a/core/script_debugger_local.cpp
+++ b/core/script_debugger_local.cpp
@@ -33,7 +33,7 @@
#include "core/os/os.h"
#include "scene/main/scene_tree.h"
-void ScriptDebuggerLocal::debug(ScriptLanguage *p_script, bool p_can_continue) {
+void ScriptDebuggerLocal::debug(ScriptLanguage *p_script, bool p_can_continue, bool p_is_error_breakpoint) {
if (!target_function.empty()) {
String current_function = p_script->debug_get_stack_level_function(0);
diff --git a/core/script_debugger_local.h b/core/script_debugger_local.h
index 19151d4cb0..b3aed5e358 100644
--- a/core/script_debugger_local.h
+++ b/core/script_debugger_local.h
@@ -48,7 +48,7 @@ class ScriptDebuggerLocal : public ScriptDebugger {
void print_variables(const List<String> &names, const List<Variant> &values, const String &variable_prefix);
public:
- void debug(ScriptLanguage *p_script, bool p_can_continue);
+ void debug(ScriptLanguage *p_script, bool p_can_continue, bool p_is_error_breakpoint);
virtual void send_message(const String &p_message, const Array &p_args);
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info);
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index e7ff7a3aef..65ef2a0978 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -89,7 +89,7 @@ Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_por
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
- ERR_PRINTS("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()));
+ ERR_PRINTS("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
return FAILED;
};
@@ -110,7 +110,7 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_
int len = 0;
Error err = encode_variant(var, NULL, len, true);
if (err != OK)
- ERR_PRINT("Failed to encode variant");
+ ERR_PRINT("Failed to encode variant.");
if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
packet_peer_stream->put_var(Variant());
@@ -129,15 +129,15 @@ void ScriptDebuggerRemote::_save_node(ObjectID id, const String &p_path) {
ResourceSaver::save(p_path, ps);
}
-void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) {
+void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue, bool p_is_error_breakpoint) {
//this function is called when there is a debugger break (bug on script)
//or when execution is paused from editor
- if (!tcp_client->is_connected_to_host()) {
- ERR_EXPLAIN("Script Debugger failed to connect, but being used anyway.");
- ERR_FAIL();
- }
+ if (skip_breakpoints && !p_is_error_breakpoint)
+ return;
+
+ ERR_FAIL_COND_MSG(!tcp_client->is_connected_to_host(), "Script Debugger failed to connect, but being used anyway.");
packet_peer_stream->put_var("debug_enter");
packet_peer_stream->put_var(2);
@@ -158,6 +158,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
Variant var;
Error err = packet_peer_stream->get_var(var);
+
ERR_CONTINUE(err != OK);
ERR_CONTINUE(var.get_type() != Variant::ARRAY);
@@ -269,7 +270,6 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
break;
} else if (command == "continue") {
-
set_depth(-1);
set_lines_left(-1);
OS::get_singleton()->move_window_to_foreground();
@@ -305,6 +305,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
} else if (command == "save_node") {
_save_node(cmd[1], cmd[2]);
+ } else if (command == "set_skip_breakpoints") {
+ skip_breakpoints = cmd[1];
} else {
_parse_live_edit(cmd);
}
@@ -357,10 +359,11 @@ void ScriptDebuggerRemote::_get_output() {
locking = false;
}
- if (n_errors_dropped > 0) {
+ if (n_errors_dropped == 1) {
+ // Only print one message about dropping per second
OutputError oe;
oe.error = "TOO_MANY_ERRORS";
- oe.error_descr = "Too many errors! " + String::num_int64(n_errors_dropped) + " errors were dropped.";
+ oe.error_descr = "Too many errors! Ignoring errors for up to 1 second.";
oe.warning = false;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr = time / 3600000;
@@ -368,7 +371,20 @@ void ScriptDebuggerRemote::_get_output() {
oe.sec = (time / 1000) % 60;
oe.msec = time % 1000;
errors.push_back(oe);
- n_errors_dropped = 0;
+ }
+
+ if (n_warnings_dropped == 1) {
+ // Only print one message about dropping per second
+ OutputError oe;
+ oe.error = "TOO_MANY_WARNINGS";
+ oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second.";
+ oe.warning = true;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ errors.push_back(oe);
}
while (errors.size()) {
@@ -587,9 +603,19 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
}
}
}
+
if (Node *node = Object::cast_to<Node>(obj)) {
- PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
- properties.push_front(PropertyDesc(pi, node->get_path()));
+ // in some cases node will not be in tree here
+ // for instance where it created as variable and not yet added to tree
+ // in such cases we can't ask for it's path
+ if (node->is_inside_tree()) {
+ PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
+ properties.push_front(PropertyDesc(pi, node->get_path()));
+ } else {
+ PropertyInfo pi(Variant::STRING, String("Node/path"));
+ properties.push_front(PropertyDesc(pi, "[Orphan]"));
+ }
+
} else if (Resource *res = Object::cast_to<Resource>(obj)) {
if (Script *s = Object::cast_to<Script>(res)) {
Map<StringName, Variant> constants;
@@ -743,6 +769,14 @@ void ScriptDebuggerRemote::_poll_events() {
profiling = false;
_send_profiling_data(false);
print_line("PROFILING END!");
+ } else if (command == "start_network_profiling") {
+
+ multiplayer->profiling_start();
+ profiling_network = true;
+ } else if (command == "stop_network_profiling") {
+
+ multiplayer->profiling_end();
+ profiling_network = false;
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -752,6 +786,8 @@ void ScriptDebuggerRemote::_poll_events() {
insert_breakpoint(cmd[2], cmd[1]);
else
remove_breakpoint(cmd[2], cmd[1]);
+ } else if (command == "set_skip_breakpoints") {
+ skip_breakpoints = cmd[1];
} else {
_parse_live_edit(cmd);
}
@@ -890,6 +926,18 @@ void ScriptDebuggerRemote::idle_poll() {
}
}
+ if (profiling_network) {
+ uint64_t pt = OS::get_singleton()->get_ticks_msec();
+ if (pt - last_net_bandwidth_time > 200) {
+ last_net_bandwidth_time = pt;
+ _send_network_bandwidth_usage();
+ }
+ if (pt - last_net_prof_time > 100) {
+ last_net_prof_time = pt;
+ _send_network_profiling_data();
+ }
+ }
+
if (reload_all_scripts) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -901,6 +949,35 @@ void ScriptDebuggerRemote::idle_poll() {
_poll_events();
}
+void ScriptDebuggerRemote::_send_network_profiling_data() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int n_nodes = multiplayer->get_profiling_frame(&network_profile_info.write[0]);
+
+ packet_peer_stream->put_var("network_profile");
+ packet_peer_stream->put_var(n_nodes * 6);
+ for (int i = 0; i < n_nodes; ++i) {
+ packet_peer_stream->put_var(network_profile_info[i].node);
+ packet_peer_stream->put_var(network_profile_info[i].node_path);
+ packet_peer_stream->put_var(network_profile_info[i].incoming_rpc);
+ packet_peer_stream->put_var(network_profile_info[i].incoming_rset);
+ packet_peer_stream->put_var(network_profile_info[i].outgoing_rpc);
+ packet_peer_stream->put_var(network_profile_info[i].outgoing_rset);
+ }
+}
+
+void ScriptDebuggerRemote::_send_network_bandwidth_usage() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int incoming_bandwidth = multiplayer->get_incoming_bandwidth_usage();
+ int outgoing_bandwidth = multiplayer->get_outgoing_bandwidth_usage();
+
+ packet_peer_stream->put_var("network_bandwidth");
+ packet_peer_stream->put_var(2);
+ packet_peer_stream->put_var(incoming_bandwidth);
+ packet_peer_stream->put_var(outgoing_bandwidth);
+}
+
void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) {
mutex->lock();
@@ -934,6 +1011,19 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
oe.msec = time % 1000;
Array cstack;
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
+ msec_count += ticks - last_msec;
+ last_msec = ticks;
+
+ if (msec_count > 1000) {
+ msec_count = 0;
+
+ err_count = 0;
+ n_errors_dropped = 0;
+ warn_count = 0;
+ n_warnings_dropped = 0;
+ }
+
cstack.resize(p_stack_info.size() * 3);
for (int i = 0; i < p_stack_info.size(); i++) {
cstack[i * 3 + 0] = p_stack_info[i].file;
@@ -942,15 +1032,28 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
}
oe.callstack = cstack;
+ if (oe.warning) {
+ warn_count++;
+ } else {
+ err_count++;
+ }
mutex->lock();
if (!locking && tcp_client->is_connected_to_host()) {
- if (errors.size() >= max_errors_per_frame) {
- n_errors_dropped++;
+ if (oe.warning) {
+ if (warn_count > max_warnings_per_second) {
+ n_warnings_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
} else {
- errors.push_back(oe);
+ if (err_count > max_errors_per_second) {
+ n_errors_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
}
}
@@ -1014,6 +1117,10 @@ void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
live_edit_funcs = p_funcs;
}
+void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
+ multiplayer = p_multiplayer;
+}
+
bool ScriptDebuggerRemote::is_profiling() const {
return profiling;
@@ -1055,25 +1162,35 @@ void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p
physics_frame_time = p_physics_frame_time;
}
+void ScriptDebuggerRemote::set_skip_breakpoints(bool p_skip_breakpoints) {
+ skip_breakpoints = p_skip_breakpoints;
+}
+
ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL;
ScriptDebuggerRemote::ScriptDebuggerRemote() :
profiling(false),
+ profiling_network(false),
max_frame_functions(16),
skip_profile_frame(false),
reload_all_scripts(false),
tcp_client(Ref<StreamPeerTCP>(memnew(StreamPeerTCP))),
packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))),
last_perf_time(0),
+ last_net_prof_time(0),
+ last_net_bandwidth_time(0),
performance(Engine::get_singleton()->get_singleton_object("Performance")),
requested_quit(false),
mutex(Mutex::create()),
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
n_messages_dropped(0),
- max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")),
+ max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
+ max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")),
n_errors_dropped(0),
max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
char_count(0),
+ err_count(0),
+ warn_count(0),
last_msec(0),
msec_count(0),
locking(false),
@@ -1093,6 +1210,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
add_error_handler(&eh);
profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
+ network_profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
profile_info_ptrs.resize(profile_info.size());
}
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
index 1fc9d7c7f1..b6dd925181 100644
--- a/core/script_debugger_remote.h
+++ b/core/script_debugger_remote.h
@@ -54,11 +54,13 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Vector<ScriptLanguage::ProfilingInfo> profile_info;
Vector<ScriptLanguage::ProfilingInfo *> profile_info_ptrs;
+ Vector<MultiplayerAPI::ProfilingInfo> network_profile_info;
Map<StringName, int> profiler_function_signature_map;
float frame_time, idle_time, physics_time, physics_frame_time;
bool profiling;
+ bool profiling_network;
int max_frame_functions;
bool skip_profile_frame;
bool reload_all_scripts;
@@ -67,6 +69,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Ref<PacketPeerStream> packet_peer_stream;
uint64_t last_perf_time;
+ uint64_t last_net_prof_time;
+ uint64_t last_net_bandwidth_time;
Object *performance;
bool requested_quit;
Mutex *mutex;
@@ -91,11 +95,15 @@ class ScriptDebuggerRemote : public ScriptDebugger {
int max_messages_per_frame;
int n_messages_dropped;
List<OutputError> errors;
- int max_errors_per_frame;
+ int max_errors_per_second;
+ int max_warnings_per_second;
int n_errors_dropped;
+ int n_warnings_dropped;
int max_cps;
int char_count;
+ int err_count;
+ int warn_count;
uint64_t last_msec;
uint64_t msec_count;
@@ -119,10 +127,14 @@ class ScriptDebuggerRemote : public ScriptDebugger {
void _send_video_memory();
LiveEditFuncs *live_edit_funcs;
+ Ref<MultiplayerAPI> multiplayer;
+
ErrorHandlerList eh;
static void _err_handler(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _send_profiling_data(bool p_for_frame);
+ void _send_network_profiling_data();
+ void _send_network_bandwidth_usage();
struct FrameData {
@@ -136,6 +148,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
void _save_node(ObjectID id, const String &p_path);
+ bool skip_breakpoints;
+
public:
struct ResourceUsage {
@@ -152,7 +166,7 @@ public:
static ResourceUsageFunc resource_usage_func;
Error connect_to_host(const String &p_host, uint16_t p_port);
- virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true);
+ virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true, bool p_is_error_breakpoint = false);
virtual void idle_poll();
virtual void line_poll();
@@ -164,6 +178,7 @@ public:
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
+ virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
virtual bool is_profiling() const;
virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data);
@@ -172,6 +187,8 @@ public:
virtual void profiling_end();
virtual void profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
+ virtual void set_skip_breakpoints(bool p_skip_breakpoints);
+
ScriptDebuggerRemote();
~ScriptDebuggerRemote();
};
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 97758ced66..ee8589d76a 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -50,6 +50,52 @@ void Script::_notification(int p_what) {
}
}
+Variant Script::_get_property_default_value(const StringName &p_property) {
+ Variant ret;
+ get_property_default_value(p_property, ret);
+ return ret;
+}
+
+Array Script::_get_script_property_list() {
+ Array ret;
+ List<PropertyInfo> list;
+ get_script_property_list(&list);
+ for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) {
+ ret.append(E->get().operator Dictionary());
+ }
+ return ret;
+}
+
+Array Script::_get_script_method_list() {
+ Array ret;
+ List<MethodInfo> list;
+ get_script_method_list(&list);
+ for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) {
+ ret.append(E->get().operator Dictionary());
+ }
+ return ret;
+}
+
+Array Script::_get_script_signal_list() {
+ Array ret;
+ List<MethodInfo> list;
+ get_script_signal_list(&list);
+ for (List<MethodInfo>::Element *E = list.front(); E; E = E->next()) {
+ ret.append(E->get().operator Dictionary());
+ }
+ return ret;
+}
+
+Dictionary Script::_get_script_constant_map() {
+ Dictionary ret;
+ Map<StringName, Variant> map;
+ get_constants(&map);
+ for (Map<StringName, Variant>::Element *E = map.front(); E; E = E->next()) {
+ ret[E->key()] = E->value();
+ }
+ return ret;
+}
+
void Script::_bind_methods() {
ClassDB::bind_method(D_METHOD("can_instance"), &Script::can_instance);
@@ -64,6 +110,12 @@ void Script::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_script_signal", "signal_name"), &Script::has_script_signal);
+ ClassDB::bind_method(D_METHOD("get_script_property_list"), &Script::_get_script_property_list);
+ ClassDB::bind_method(D_METHOD("get_script_method_list"), &Script::_get_script_method_list);
+ ClassDB::bind_method(D_METHOD("get_script_signal_list"), &Script::_get_script_signal_list);
+ ClassDB::bind_method(D_METHOD("get_script_constant_map"), &Script::_get_script_constant_map);
+ ClassDB::bind_method(D_METHOD("get_property_default_value"), &Script::_get_property_default_value);
+
ClassDB::bind_method(D_METHOD("is_tool"), &Script::is_tool);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_code", PROPERTY_HINT_NONE, "", 0), "set_source_code", "get_source_code");
diff --git a/core/script_language.h b/core/script_language.h
index 87f103bb33..116918fdc0 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -36,10 +36,6 @@
#include "core/pair.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ScriptLanguage;
typedef void (*ScriptEditRequestFunction)(const String &p_path);
@@ -113,6 +109,12 @@ protected:
friend class PlaceHolderScriptInstance;
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {}
+ Variant _get_property_default_value(const StringName &p_property);
+ Array _get_script_property_list();
+ Array _get_script_method_list();
+ Array _get_script_signal_list();
+ Dictionary _get_script_constant_map();
+
public:
virtual bool can_instance() const = 0;
@@ -465,7 +467,7 @@ public:
void clear_breakpoints();
const Map<int, Set<StringName> > &get_breakpoints() const { return breakpoints; }
- virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true) = 0;
+ virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true, bool p_is_error_breakpoint = false) = 0;
virtual void idle_poll();
virtual void line_poll();
@@ -480,6 +482,7 @@ public:
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
+ virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {}
virtual bool is_profiling() const = 0;
virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data) = 0;
diff --git a/core/set.h b/core/set.h
index 81250068af..68431c294a 100644
--- a/core/set.h
+++ b/core/set.h
@@ -34,12 +34,8 @@
#include "core/os/memory.h"
#include "core/typedefs.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
// based on the very nice implementation of rb-trees by:
-// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class T, class C = Comparator<T>, class A = DefaultAllocator>
class Set {
diff --git a/core/string_name.cpp b/core/string_name.cpp
index 10b71ad3ac..b1a8bfb849 100644
--- a/core/string_name.cpp
+++ b/core/string_name.cpp
@@ -205,7 +205,6 @@ StringName::StringName(const char *p_name) {
// exists
lock->unlock();
return;
- } else {
}
}
@@ -253,7 +252,6 @@ StringName::StringName(const StaticCString &p_static_string) {
// exists
lock->unlock();
return;
- } else {
}
}
@@ -301,7 +299,6 @@ StringName::StringName(const String &p_name) {
// exists
lock->unlock();
return;
- } else {
}
}
diff --git a/core/string_name.h b/core/string_name.h
index 0984b0181f..6dd960abd5 100644
--- a/core/string_name.h
+++ b/core/string_name.h
@@ -34,9 +34,6 @@
#include "core/os/mutex.h"
#include "core/safe_refcount.h"
#include "core/ustring.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
struct StaticCString {
diff --git a/core/translation.cpp b/core/translation.cpp
index 0b55badc61..a0902d71fc 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -848,8 +848,7 @@ void Translation::set_locale(const String &p_locale) {
if (!TranslationServer::is_locale_valid(univ_locale)) {
String trimmed_locale = get_trimmed_locale(univ_locale);
- ERR_EXPLAIN("Invalid locale: " + trimmed_locale);
- ERR_FAIL_COND(!TranslationServer::is_locale_valid(trimmed_locale));
+ ERR_FAIL_COND_MSG(!TranslationServer::is_locale_valid(trimmed_locale), "Invalid locale: " + trimmed_locale + ".");
locale = trimmed_locale;
} else {
@@ -1044,6 +1043,13 @@ StringName TranslationServer::translate(const StringName &p_message) const {
if (!enabled)
return p_message;
+ // Locale can be of the form 'll_CC', i.e. language code and regional code,
+ // e.g. 'en_US', 'en_GB', etc. It might also be simply 'll', e.g. 'en'.
+ // To find the relevant translation, we look for those with locale starting
+ // with the language code, and then if any is an exact match for the long
+ // form. If not found, we fall back to a near match (another locale with
+ // same language code).
+
StringName res;
bool near_match = false;
const CharType *lptr = &locale[0];
@@ -1053,13 +1059,11 @@ StringName TranslationServer::translate(const StringName &p_message) const {
const Ref<Translation> &t = E->get();
String l = t->get_locale();
if (lptr[0] != l[0] || lptr[1] != l[1])
- continue; // locale not match
-
- //near match
- bool match = (l != locale);
+ continue; // Language code does not match.
- if (near_match && !match)
- continue; //only near-match once
+ bool exact_match = (l == locale);
+ if (!exact_match && near_match)
+ continue; // Only near-match once, but keep looking for exact matches.
StringName r = t->get_message(p_message);
@@ -1068,43 +1072,38 @@ StringName TranslationServer::translate(const StringName &p_message) const {
res = r;
- if (match)
+ if (exact_match)
break;
else
near_match = true;
}
- if (!res) {
- //try again with fallback
- if (fallback.length() >= 2) {
-
- const CharType *fptr = &fallback[0];
- near_match = false;
- for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
+ if (!res && fallback.length() >= 2) {
+ // Try again with the fallback locale.
+ const CharType *fptr = &fallback[0];
+ near_match = false;
+ for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
- const Ref<Translation> &t = E->get();
- String l = t->get_locale();
- if (fptr[0] != l[0] || fptr[1] != l[1])
- continue; // locale not match
+ const Ref<Translation> &t = E->get();
+ String l = t->get_locale();
+ if (fptr[0] != l[0] || fptr[1] != l[1])
+ continue; // Language code does not match.
- //near match
- bool match = (l != fallback);
+ bool exact_match = (l == fallback);
+ if (!exact_match && near_match)
+ continue; // Only near-match once, but keep looking for exact matches.
- if (near_match && !match)
- continue; //only near-match once
+ StringName r = t->get_message(p_message);
- StringName r = t->get_message(p_message);
+ if (!r)
+ continue;
- if (!r)
- continue;
+ res = r;
- res = r;
-
- if (match)
- break;
- else
- near_match = true;
- }
+ if (exact_match)
+ break;
+ else
+ near_match = true;
}
}
diff --git a/core/type_info.h b/core/type_info.h
index d85a63ee42..61ec7b2f20 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -83,15 +83,13 @@ enum Metadata {
};
}
+// If the compiler fails because it's trying to instantiate the primary 'GetTypeInfo' template
+// instead of one of the specializations, it's most likely because the type 'T' is not supported.
+// If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration
+// instead of a forward declaration. You can always forward declare 'T' in a header file, and then
+// include the actual declaration of 'T' in the source file where 'GetTypeInfo<T>' is instantiated.
template <class T, typename = void>
-struct GetTypeInfo {
- static const Variant::Type VARIANT_TYPE = Variant::NIL;
- static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
- static inline PropertyInfo get_class_info() {
- ERR_PRINT("GetTypeInfo fallback. Bug!");
- return PropertyInfo(); // Not "Nil", this is an error
- }
-};
+struct GetTypeInfo;
#define MAKE_TYPE_INFO(m_type, m_var_type) \
template <> \
@@ -283,10 +281,7 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
-#define CLASS_INFO(m_type) \
- (GetTypeInfo<m_type *>::VARIANT_TYPE != Variant::NIL ? \
- GetTypeInfo<m_type *>::get_class_info() : \
- GetTypeInfo<m_type>::get_class_info())
+#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
#else
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 75e3b6f22e..dee554716f 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -31,7 +31,7 @@
#include "ustring.h"
#include "core/color.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/print_string.h"
@@ -40,6 +40,7 @@
#include "core/variant.h"
#include <wchar.h>
+#include <cstdint>
#ifndef NO_USE_STDLIB
#include <stdio.h>
@@ -1668,6 +1669,7 @@ int String::hex_to_int(bool p_with_prefix) const {
return 0;
}
+ ERR_FAIL_COND_V_MSG(hex > INT32_MAX / 16, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
hex *= 16;
hex += n;
s++;
@@ -1709,6 +1711,7 @@ int64_t String::hex_to_int64(bool p_with_prefix) const {
return 0;
}
+ ERR_FAIL_COND_V_MSG(hex > INT64_MAX / 16, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
hex *= 16;
hex += n;
s++;
@@ -1748,6 +1751,7 @@ int64_t String::bin_to_int64(bool p_with_prefix) const {
return 0;
}
+ ERR_FAIL_COND_V_MSG(binary > INT64_MAX / 2, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
binary *= 2;
binary += n;
s++;
@@ -1771,6 +1775,7 @@ int String::to_int() const {
CharType c = operator[](i);
if (c >= '0' && c <= '9') {
+ ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
@@ -1798,6 +1803,7 @@ int64_t String::to_int64() const {
CharType c = operator[](i);
if (c >= '0' && c <= '9') {
+ ERR_FAIL_COND_V_MSG(integer > INT64_MAX / 10, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
@@ -1828,6 +1834,7 @@ int String::to_int(const char *p_str, int p_len) {
char c = p_str[i];
if (c >= '0' && c <= '9') {
+ ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
@@ -2140,6 +2147,14 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
if (c >= '0' && c <= '9') {
+ if (integer > INT64_MAX / 10) {
+ String number("");
+ str = p_str;
+ while (*str && str != limit) {
+ number += *(str++);
+ }
+ ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+ }
integer *= 10;
integer += c - '0';
} else {
@@ -2729,6 +2744,51 @@ bool String::is_quoted() const {
return is_enclosed_in("\"") || is_enclosed_in("'");
}
+int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const {
+ if (p_string.empty()) {
+ return 0;
+ }
+ int len = length();
+ int slen = p_string.length();
+ if (len < slen) {
+ return 0;
+ }
+ String str;
+ if (p_from >= 0 && p_to >= 0) {
+ if (p_to == 0) {
+ p_to = len;
+ } else if (p_from >= p_to) {
+ return 0;
+ }
+ if (p_from == 0 && p_to == len) {
+ str = String();
+ str.copy_from_unchecked(&c_str()[0], len);
+ } else {
+ str = substr(p_from, p_to - p_from);
+ }
+ } else {
+ return 0;
+ }
+ int c = 0;
+ int idx = -1;
+ do {
+ idx = p_case_insensitive ? str.findn(p_string) : str.find(p_string);
+ if (idx != -1) {
+ str = str.substr(idx + slen, str.length() - slen);
+ ++c;
+ }
+ } while (idx != -1);
+ return c;
+}
+
+int String::count(const String &p_string, int p_from, int p_to) const {
+ return _count(p_string, p_from, p_to, false);
+}
+
+int String::countn(const String &p_string, int p_from, int p_to) const {
+ return _count(p_string, p_from, p_to, true);
+}
+
bool String::_base_is_subsequence_of(const String &p_string, bool case_insensitive) const {
int len = length();
@@ -3225,18 +3285,26 @@ static int _humanize_digits(int p_num) {
String String::humanize_size(size_t p_size) {
uint64_t _div = 1;
- static const char *prefix[] = { " Bytes", " KB", " MB", " GB", " TB", " PB", " EB", "" };
+ Vector<String> prefixes;
+ prefixes.push_back(RTR("B"));
+ prefixes.push_back(RTR("KiB"));
+ prefixes.push_back(RTR("MiB"));
+ prefixes.push_back(RTR("GiB"));
+ prefixes.push_back(RTR("TiB"));
+ prefixes.push_back(RTR("PiB"));
+ prefixes.push_back(RTR("EiB"));
+
int prefix_idx = 0;
- while (p_size > (_div * 1024) && prefix[prefix_idx][0]) {
+ while (prefix_idx < prefixes.size() && p_size > (_div * 1024)) {
_div *= 1024;
prefix_idx++;
}
- int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
- double divisor = prefix_idx > 0 ? _div : 1;
+ const int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
+ const double divisor = prefix_idx > 0 ? _div : 1;
- return String::num(p_size / divisor).pad_decimals(digits) + prefix[prefix_idx];
+ return String::num(p_size / divisor).pad_decimals(digits) + " " + prefixes[prefix_idx];
}
bool String::is_abs_path() const {
diff --git a/core/ustring.h b/core/ustring.h
index 8a52c53238..bbd0bcceb5 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -36,10 +36,6 @@
#include "core/typedefs.h"
#include "core/vector.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
template <class T>
class CharProxy {
friend class CharString;
@@ -137,6 +133,7 @@ class String {
void copy_from(const CharType &p_char);
void copy_from_unchecked(const CharType *p_char, const int p_length);
bool _base_is_subsequence_of(const String &p_string, bool case_insensitive) const;
+ int _count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const;
public:
enum {
@@ -279,6 +276,9 @@ public:
String to_upper() const;
String to_lower() const;
+ int count(const String &p_string, int p_from = 0, int p_to = 0) const;
+ int countn(const String &p_string, int p_from = 0, int p_to = 0) const;
+
String left(int p_pos) const;
String right(int p_pos) const;
String dedent() const;
diff --git a/core/variant.cpp b/core/variant.cpp
index fe9623d068..16bbf94c54 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -910,7 +910,15 @@ bool Variant::is_one() const {
void Variant::reference(const Variant &p_variant) {
- clear();
+ switch (type) {
+ case NIL:
+ case BOOL:
+ case INT:
+ case REAL:
+ break;
+ default:
+ clear();
+ }
type = p_variant.type;
@@ -1740,10 +1748,7 @@ Variant::operator RID() const {
} else if (type == OBJECT && _get_obj().obj) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
- if (!ObjectDB::instance_validate(_get_obj().obj)) {
- ERR_EXPLAIN("Invalid pointer (object was deleted)");
- ERR_FAIL_V(RID());
- };
+ ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(_get_obj().obj), RID(), "Invalid pointer (object was deleted).");
};
#endif
Variant::CallError ce;
@@ -1834,8 +1839,6 @@ inline DA _convert_array_from_variant(const Variant &p_variant) {
return DA();
}
}
-
- return DA();
}
Variant::operator Array() const {
@@ -2299,7 +2302,7 @@ Variant::Variant(const Object *p_object) {
Variant::Variant(const Dictionary &p_dictionary) {
type = DICTIONARY;
- memnew_placement(_data._mem, (Dictionary)(p_dictionary));
+ memnew_placement(_data._mem, Dictionary(p_dictionary));
}
Variant::Variant(const Array &p_array) {
diff --git a/core/variant.h b/core/variant.h
index a8e99c13f1..c4f69c3e8d 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -31,10 +31,6 @@
#ifndef VARIANT_H
#define VARIANT_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/array.h"
#include "core/color.h"
#include "core/dictionary.h"
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 3fdd18a630..c288c50abf 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -32,8 +32,8 @@
#include "core/color_names.inc"
#include "core/core_string_names.h"
+#include "core/crypto/crypto_core.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"
@@ -70,7 +70,7 @@ struct _VariantCall {
for (int i = 0; i < arg_count; i++) {
- if (!tptr[i] || tptr[i] == p_args[i]->type)
+ if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type)
continue; // all good
if (!Variant::can_convert(p_args[i]->type, tptr[i])) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
@@ -237,6 +237,8 @@ struct _VariantCall {
VCALL_LOCALMEM1R(String, casecmp_to);
VCALL_LOCALMEM1R(String, nocasecmp_to);
VCALL_LOCALMEM0R(String, length);
+ VCALL_LOCALMEM3R(String, count);
+ VCALL_LOCALMEM3R(String, countn);
VCALL_LOCALMEM2R(String, substr);
VCALL_LOCALMEM2R(String, find);
VCALL_LOCALMEM1R(String, find_last);
@@ -345,6 +347,8 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector2, is_normalized);
VCALL_LOCALMEM1R(Vector2, distance_to);
VCALL_LOCALMEM1R(Vector2, distance_squared_to);
+ VCALL_LOCALMEM1R(Vector2, posmod);
+ VCALL_LOCALMEM1R(Vector2, posmodv);
VCALL_LOCALMEM1R(Vector2, project);
VCALL_LOCALMEM1R(Vector2, angle_to);
VCALL_LOCALMEM1R(Vector2, angle_to_point);
@@ -368,6 +372,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector2, cross);
VCALL_LOCALMEM0R(Vector2, abs);
VCALL_LOCALMEM1R(Vector2, clamped);
+ VCALL_LOCALMEM0R(Vector2, sign);
VCALL_LOCALMEM0R(Rect2, get_area);
VCALL_LOCALMEM1R(Rect2, intersects);
@@ -405,12 +410,15 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector3, round);
VCALL_LOCALMEM1R(Vector3, distance_to);
VCALL_LOCALMEM1R(Vector3, distance_squared_to);
+ VCALL_LOCALMEM1R(Vector3, posmod);
+ VCALL_LOCALMEM1R(Vector3, posmodv);
VCALL_LOCALMEM1R(Vector3, project);
VCALL_LOCALMEM1R(Vector3, angle_to);
VCALL_LOCALMEM1R(Vector3, direction_to);
VCALL_LOCALMEM1R(Vector3, slide);
VCALL_LOCALMEM1R(Vector3, bounce);
VCALL_LOCALMEM1R(Vector3, reflect);
+ VCALL_LOCALMEM0R(Vector3, sign);
VCALL_LOCALMEM0R(Plane, normalized);
VCALL_LOCALMEM0R(Plane, center);
@@ -526,6 +534,7 @@ struct _VariantCall {
VCALL_LOCALMEM2R(Array, bsearch);
VCALL_LOCALMEM4R(Array, bsearch_custom);
VCALL_LOCALMEM1R(Array, duplicate);
+ VCALL_LOCALMEM4R(Array, slice);
VCALL_LOCALMEM0(Array, invert);
VCALL_LOCALMEM0R(Array, max);
VCALL_LOCALMEM0R(Array, min);
@@ -582,8 +591,7 @@ struct _VariantCall {
if (buffer_size < 0) {
r_ret = decompressed;
- ERR_EXPLAIN("Decompression buffer size is less than zero");
- ERR_FAIL();
+ ERR_FAIL_MSG("Decompression buffer size is less than zero.");
}
decompressed.resize(buffer_size);
@@ -595,13 +603,10 @@ struct _VariantCall {
r_ret = decompressed;
}
- static void _call_PoolByteArray_sha256_string(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
PoolByteArray::Read r = ba->read();
- String s;
- unsigned char hash[32];
- CryptoCore::sha256((unsigned char *)r.ptr(), ba->size(), hash);
- s = String::hex_encode_buffer(hash, 32);
+ String s = String::hex_encode_buffer(&r[0], ba->size());
r_ret = s;
}
@@ -747,6 +752,7 @@ struct _VariantCall {
case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2()); return;
case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2()); return;
+ case Variant::POOL_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PoolVector2Array()); return;
default: r_ret = Variant();
}
}
@@ -757,6 +763,7 @@ struct _VariantCall {
case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2()); return;
case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2()); return;
+ case Variant::POOL_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PoolVector2Array()); return;
default: r_ret = Variant();
}
}
@@ -813,6 +820,7 @@ struct _VariantCall {
case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return;
case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return;
case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return;
+ case Variant::POOL_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PoolVector3Array()); return;
default: r_ret = Variant();
}
}
@@ -824,6 +832,7 @@ struct _VariantCall {
case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return;
case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return;
case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return;
+ case Variant::POOL_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PoolVector3Array()); return;
default: r_ret = Variant();
}
}
@@ -912,7 +921,7 @@ struct _VariantCall {
static void Quat_init2(Variant &r_ret, const Variant **p_args) {
- r_ret = Quat(((Vector3)(*p_args[0])), ((float)(*p_args[1])));
+ r_ret = Quat(((Vector3)(*p_args[0])), ((real_t)(*p_args[1])));
}
static void Quat_init3(Variant &r_ret, const Variant **p_args) {
@@ -1502,6 +1511,9 @@ void register_variant_methods() {
ADDFUNC2R(STRING, INT, String, find, STRING, "what", INT, "from", varray(0));
+ ADDFUNC3R(STRING, INT, String, count, STRING, "what", INT, "from", INT, "to", varray(0, 0));
+ ADDFUNC3R(STRING, INT, String, countn, STRING, "what", INT, "from", INT, "to", varray(0, 0));
+
ADDFUNC1R(STRING, INT, String, find_last, STRING, "what", varray());
ADDFUNC2R(STRING, INT, String, findn, STRING, "what", INT, "from", varray(0));
ADDFUNC2R(STRING, INT, String, rfind, STRING, "what", INT, "from", varray(-1));
@@ -1586,6 +1598,8 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, direction_to, VECTOR2, "b", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_squared_to, VECTOR2, "to", varray());
+ ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, REAL, "mod", varray());
+ ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
@@ -1607,6 +1621,7 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray());
+ ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray());
ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
ADDFUNC1R(RECT2, BOOL, Rect2, intersects, RECT2, "b", varray());
@@ -1645,11 +1660,14 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, round, varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
+ ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, REAL, "mod", varray());
+ ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmodv, VECTOR3, "modv", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, project, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
+ ADDFUNC0R(VECTOR3, VECTOR3, Vector3, sign, varray());
ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, center, varray());
@@ -1742,6 +1760,7 @@ void register_variant_methods() {
ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());
ADDFUNC1R(ARRAY, ARRAY, Array, duplicate, BOOL, "deep", varray(false));
+ ADDFUNC4R(ARRAY, ARRAY, Array, slice, INT, "begin", INT, "end", INT, "step", BOOL, "deep", varray(1, false));
ADDFUNC0R(ARRAY, NIL, Array, max, varray());
ADDFUNC0R(ARRAY, NIL, Array, min, varray());
@@ -1758,7 +1777,7 @@ void register_variant_methods() {
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, sha256_string, varray());
+ ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, hex_encode, varray());
ADDFUNC1R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
@@ -1942,6 +1961,9 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
+ _VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X);
+ _VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y);
+
_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));
@@ -1950,19 +1972,27 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "DOWN", Vector2(0, 1));
- _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D(1, 0, 0, 1, 0, 0));
+ _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D());
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0));
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0));
- Transform identity_transform, transform_x, transform_y, transform_z;
- identity_transform.set(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ Transform identity_transform = Transform();
+ Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
+ Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
_VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform);
- transform_x.set(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", transform_x);
- transform_y.set(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", transform_y);
- transform_z.set(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", transform_z);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform);
+
+ Basis identity_basis = Basis();
+ Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1);
+ Basis flip_y_basis = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1);
+ Basis flip_z_basis = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1);
+ _VariantCall::add_variant_constant(Variant::BASIS, "IDENTITY", identity_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_X", flip_x_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Y", flip_y_basis);
+ _VariantCall::add_variant_constant(Variant::BASIS, "FLIP_Z", flip_z_basis);
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_YZ", Plane(Vector3(1, 0, 0), 0));
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0));
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index d677c7776a..ea9e29e744 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -2613,7 +2613,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
if (r_valid) {
*r_valid = false;
}
- return "Attempted get on stray pointer.";
+ return true; // Attempted get on stray pointer.
}
}
#endif
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index d5513bc2d7..fe2c981c3c 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -1522,7 +1522,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
return err;
if (tk.type != TK_STRING) {
r_err_str = "Error reading quoted string";
- return err;
+ return ERR_INVALID_DATA;
}
what = tk.value;
@@ -1537,8 +1537,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
Token token;
get_token(p_stream, token, line, r_err_str);
Error err = parse_value(token, r_value, p_stream, line, r_err_str, p_res_parser);
- if (err) {
- }
return err;
}
} else if (c == '\n') {
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 0428140908..b25de3cf99 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -1317,10 +1317,10 @@
No hint for the edited property.
</constant>
<constant name="PROPERTY_HINT_RANGE" value="1" enum="PropertyHint">
- Hints that an integer or float property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"allow_greater"[/code] and/or [code]"allow_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"-360,360,1,allow_greater,allow_lesser"[/code].
+ Hints that an integer or float property should be within a range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"-360,360,1,or_greater,or_lesser"[/code].
</constant>
<constant name="PROPERTY_HINT_EXP_RANGE" value="2" enum="PropertyHint">
- Hints that an integer or float property should be within an exponential range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"allow_greater"[/code] and/or [code]"allow_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"0.01,100,0.01,allow_greater"[/code].
+ Hints that an integer or float property should be within an exponential range specified via the hint string [code]"min,max"[/code] or [code]"min,max,step"[/code]. The hint string can optionally include [code]"or_greater"[/code] and/or [code]"or_lesser"[/code] to allow manual input going respectively above the max or below the min values. Example: [code]"0.01,100,0.01,or_greater"[/code].
</constant>
<constant name="PROPERTY_HINT_ENUM" value="3" enum="PropertyHint">
Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
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/AStar.xml b/doc/classes/AStar.xml
index 99e2db6d83..9ca09371dd 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -44,8 +44,8 @@
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
[codeblock]
- var as = AStar.new()
- as.add_point(1, Vector3(1, 0, 0), 4) # Adds the point (1, 0, 0) with weight_scale 4 and id 1
+ var astar = AStar.new()
+ astar.add_point(1, Vector3(1, 0, 0), 4) # Adds the point (1, 0, 0) with weight_scale 4 and id 1
[/codeblock]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
@@ -80,10 +80,10 @@
<description>
Creates a segment between the given points. If [code]bidirectional[/code] is [code]false[/code], only movement from [code]id[/code] to [code]to_id[/code] is allowed, not the reverse direction.
[codeblock]
- var as = AStar.new()
- as.add_point(1, Vector3(1, 1, 0))
- as.add_point(2, Vector3(0, 5, 0))
- as.connect_points(1, 2, false)
+ var astar = AStar.new()
+ astar.add_point(1, Vector3(1, 1, 0))
+ astar.add_point(2, Vector3(0, 5, 0))
+ astar.connect_points(1, 2, false)
[/codeblock]
</description>
</method>
@@ -122,11 +122,11 @@
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
[codeblock]
- var as = AStar.new()
- as.add_point(1, Vector3(0, 0, 0))
- as.add_point(2, Vector3(0, 5, 0))
- as.connect_points(1, 2)
- var res = as.get_closest_position_in_segment(Vector3(3, 3, 0)) # Returns (0, 3, 0)
+ var astar = AStar.new()
+ astar.add_point(1, Vector3(0, 0, 0))
+ astar.add_point(2, Vector3(0, 5, 0))
+ astar.connect_points(1, 2)
+ var res = astar.get_closest_position_in_segment(Vector3(3, 3, 0)) # Returns (0, 3, 0)
[/codeblock]
The result is in the segment that goes from [code]y = 0[/code] to [code]y = 5[/code]. It's the closest position in the segment to the given point.
</description>
@@ -141,23 +141,29 @@
<description>
Returns an array with the IDs of the points that form the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path.
[codeblock]
- var as = AStar.new()
- as.add_point(1, Vector3(0, 0, 0))
- as.add_point(2, Vector3(0, 1, 0), 1) # Default weight is 1
- as.add_point(3, Vector3(1, 1, 0))
- as.add_point(4, Vector3(2, 0, 0))
+ var astar = AStar.new()
+ astar.add_point(1, Vector3(0, 0, 0))
+ astar.add_point(2, Vector3(0, 1, 0), 1) # Default weight is 1
+ astar.add_point(3, Vector3(1, 1, 0))
+ astar.add_point(4, Vector3(2, 0, 0))
- as.connect_points(1, 2, false)
- as.connect_points(2, 3, false)
- as.connect_points(4, 3, false)
- as.connect_points(1, 4, false)
- as.connect_points(5, 4, false)
+ astar.connect_points(1, 2, false)
+ astar.connect_points(2, 3, false)
+ astar.connect_points(4, 3, false)
+ astar.connect_points(1, 4, false)
- var res = as.get_id_path(1, 3) # Returns [1, 2, 3]
+ var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
[/codeblock]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
</description>
</method>
+ <method name="get_point_capacity" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the capacity of the structure backing the points, useful in conjunction with [code]reserve_space[/code].
+ </description>
+ </method>
<method name="get_point_connections">
<return type="PoolIntArray">
</return>
@@ -166,19 +172,26 @@
<description>
Returns an array with the IDs of the points that form the connection with the given point.
[codeblock]
- var as = AStar.new()
- as.add_point(1, Vector3(0, 0, 0))
- as.add_point(2, Vector3(0, 1, 0))
- as.add_point(3, Vector3(1, 1, 0))
- as.add_point(4, Vector3(2, 0, 0))
+ var astar = AStar.new()
+ astar.add_point(1, Vector3(0, 0, 0))
+ astar.add_point(2, Vector3(0, 1, 0))
+ astar.add_point(3, Vector3(1, 1, 0))
+ astar.add_point(4, Vector3(2, 0, 0))
- as.connect_points(1, 2, true)
- as.connect_points(1, 3, true)
+ astar.connect_points(1, 2, true)
+ astar.connect_points(1, 3, true)
- var neighbors = as.get_point_connections(1) # Returns [2, 3]
+ var neighbors = astar.get_point_connections(1) # Returns [2, 3]
[/codeblock]
</description>
</method>
+ <method name="get_point_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of points currently in the points pool.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PoolVector3Array">
</return>
@@ -242,6 +255,15 @@
Removes the point associated with the given [code]id[/code] from the points pool.
</description>
</method>
+ <method name="reserve_space">
+ <return type="void">
+ </return>
+ <argument index="0" name="num_nodes" type="int">
+ </argument>
+ <description>
+ Reserves space internally for [code]num_nodes[/code] points, useful if you're adding a known large number of points at once, for a grid for instance. New capacity must be greater or equals to old capacity.
+ </description>
+ </method>
<method name="set_point_disabled">
<return type="void">
</return>
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 526d1c16da..0eff2bd560 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -21,8 +21,8 @@
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
[codeblock]
- var as = AStar2D.new()
- as.add_point(1, Vector2(1, 0), 4) # Adds the point (1, 0) with weight_scale 4 and id 1
+ var astar = AStar2D.new()
+ astar.add_point(1, Vector2(1, 0), 4) # Adds the point (1, 0) with weight_scale 4 and id 1
[/codeblock]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
@@ -57,10 +57,10 @@
<description>
Creates a segment between the given points. If [code]bidirectional[/code] is [code]false[/code], only movement from [code]id[/code] to [code]to_id[/code] is allowed, not the reverse direction.
[codeblock]
- var as = AStar2D.new()
- as.add_point(1, Vector2(1, 1))
- as.add_point(2, Vector2(0, 5))
- as.connect_points(1, 2, false)
+ var astar = AStar2D.new()
+ astar.add_point(1, Vector2(1, 1))
+ astar.add_point(2, Vector2(0, 5))
+ astar.connect_points(1, 2, false)
[/codeblock]
</description>
</method>
@@ -99,11 +99,11 @@
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
[codeblock]
- var as = AStar2D.new()
- as.add_point(1, Vector2(0, 0))
- as.add_point(2, Vector2(0, 5))
- as.connect_points(1, 2)
- var res = as.get_closest_position_in_segment(Vector2(3, 3)) # Returns (0, 3)
+ var astar = AStar2D.new()
+ astar.add_point(1, Vector2(0, 0))
+ astar.add_point(2, Vector2(0, 5))
+ astar.connect_points(1, 2)
+ var res = astar.get_closest_position_in_segment(Vector2(3, 3)) # Returns (0, 3)
[/codeblock]
The result is in the segment that goes from [code]y = 0[/code] to [code]y = 5[/code]. It's the closest position in the segment to the given point.
</description>
@@ -118,23 +118,29 @@
<description>
Returns an array with the IDs of the points that form the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path.
[codeblock]
- var as = AStar2D.new()
- as.add_point(1, Vector2(0, 0))
- as.add_point(2, Vector2(0, 1), 1) # Default weight is 1
- as.add_point(3, Vector2(1, 1))
- as.add_point(4, Vector2(2, 0))
+ var astar = AStar2D.new()
+ astar.add_point(1, Vector2(0, 0))
+ astar.add_point(2, Vector2(0, 1), 1) # Default weight is 1
+ astar.add_point(3, Vector2(1, 1))
+ astar.add_point(4, Vector2(2, 0))
- as.connect_points(1, 2, false)
- as.connect_points(2, 3, false)
- as.connect_points(4, 3, false)
- as.connect_points(1, 4, false)
- as.connect_points(5, 4, false)
+ astar.connect_points(1, 2, false)
+ astar.connect_points(2, 3, false)
+ astar.connect_points(4, 3, false)
+ astar.connect_points(1, 4, false)
- var res = as.get_id_path(1, 3) # Returns [1, 2, 3]
+ var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
[/codeblock]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
</description>
</method>
+ <method name="get_point_capacity" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the capacity of the structure backing the points, useful in conjunction with [code]reserve_space[/code].
+ </description>
+ </method>
<method name="get_point_connections">
<return type="PoolIntArray">
</return>
@@ -143,19 +149,26 @@
<description>
Returns an array with the IDs of the points that form the connection with the given point.
[codeblock]
- var as = AStar2D.new()
- as.add_point(1, Vector2(0, 0))
- as.add_point(2, Vector2(0, 1))
- as.add_point(3, Vector2(1, 1))
- as.add_point(4, Vector2(2, 0))
+ var astar = AStar2D.new()
+ astar.add_point(1, Vector2(0, 0))
+ astar.add_point(2, Vector2(0, 1))
+ astar.add_point(3, Vector2(1, 1))
+ astar.add_point(4, Vector2(2, 0))
- as.connect_points(1, 2, true)
- as.connect_points(1, 3, true)
+ astar.connect_points(1, 2, true)
+ astar.connect_points(1, 3, true)
- var neighbors = as.get_point_connections(1) # Returns [2, 3]
+ var neighbors = astar.get_point_connections(1) # Returns [2, 3]
[/codeblock]
</description>
</method>
+ <method name="get_point_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of points currently in the points pool.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PoolVector2Array">
</return>
@@ -219,6 +232,15 @@
Removes the point associated with the given [code]id[/code] from the points pool.
</description>
</method>
+ <method name="reserve_space">
+ <return type="void">
+ </return>
+ <argument index="0" name="num_nodes" type="int">
+ </argument>
+ <description>
+ Reserves space internally for [code]num_nodes[/code] points, useful if you're adding a known large number of points at once, for a grid for instance. New capacity must be greater or equals to old capacity.
+ </description>
+ </method>
<method name="set_point_disabled">
<return type="void">
</return>
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/AnimatedTexture.xml b/doc/classes/AnimatedTexture.xml
index 7e32db1bb8..2d3ebac78c 100644
--- a/doc/classes/AnimatedTexture.xml
+++ b/doc/classes/AnimatedTexture.xml
@@ -6,7 +6,7 @@
<description>
[AnimatedTexture] is a resource format for frame-based animations, where multiple textures can be chained automatically with a predefined delay for each frame. Unlike [AnimationPlayer] or [AnimatedSprite], it isn't a [Node], but has the advantage of being usable anywhere a [Texture] resource can be used, e.g. in a [TileSet].
The playback of the animation is controlled by the [member fps] property as well as each frame's optional delay (see [method set_frame_delay]). The animation loops, i.e. it will restart at frame 0 automatically after playing the last frame.
- [AnimatedTexture] currently requires all frame textures to have the same size, otherwise the bigger ones will be cropped to match the smallest one.
+ [AnimatedTexture] currently requires all frame textures to have the same size, otherwise the bigger ones will be cropped to match the smallest one. Also, it doesn't support [AtlasTexture]. Each frame needs to be separate image.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml
index 7d5d8a2db1..b4288bbfaa 100644
--- a/doc/classes/AnimationNode.xml
+++ b/doc/classes/AnimationNode.xml
@@ -73,7 +73,7 @@
<argument index="6" name="optimize" type="bool" default="true">
</argument>
<description>
- Blend another animaiton node (in case this node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your node for addition.
+ Blend another animation node (in case this node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your node for addition.
</description>
</method>
<method name="get_caption" qualifiers="virtual">
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index b4c44fe8eb..5bb4a6e3c7 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -71,7 +71,7 @@
<argument index="0" name="animation" type="Animation">
</argument>
<description>
- Returns the name of [code]animation[/code] or empty string if not found.
+ Returns the name of [code]animation[/code] or an empty string if not found.
</description>
</method>
<method name="get_animation" qualifiers="const">
@@ -112,6 +112,7 @@
<return type="PoolStringArray">
</return>
<description>
+ Returns a list of the animation names that are currently queued to play.
</description>
</method>
<method name="has_animation" qualifiers="const">
@@ -165,6 +166,7 @@
</argument>
<description>
Queues an animation for playback once the current one is done.
+ [b]Note:[/b] If a looped animation is currently playing, the queued animation will never play unless the looped animation is stopped somehow.
</description>
</method>
<method name="remove_animation">
@@ -283,6 +285,7 @@
</signal>
<signal name="caches_cleared">
<description>
+ Notifies when the caches have been cleared, either automatically, or manually via [method clear_caches].
</description>
</signal>
</signals>
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(&quot;&quot;)">
</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/Array.xml b/doc/classes/Array.xml
index 130908b842..45d40cccea 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -124,6 +124,21 @@
[b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
</description>
</method>
+ <method name="slice">
+ <return type="Array">
+ </return>
+ <argument index="0" name="begin" type="int">
+ </argument>
+ <argument index="1" name="end" type="int">
+ </argument>
+ <argument index="2" name="step" type="int" default="1">
+ </argument>
+ <argument index="3" name="deep" type="bool" default="False">
+ </argument>
+ <description>
+ Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is true. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
+ </description>
+ </method>
<method name="clear">
<description>
Clears the array. This is equivalent to using [method resize] with a size of [code]0[/code].
diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml
index 1363287dc1..b270c7e279 100644
--- a/doc/classes/AtlasTexture.xml
+++ b/doc/classes/AtlasTexture.xml
@@ -4,15 +4,14 @@
Packs multiple small textures in a single, bigger one. Helps to optimize video memory costs and render calls.
</brief_description>
<description>
- [Texture] resource aimed at managing big textures files that pack multiple smaller textures. Consists of a [Texture], a margin that defines the border width,
- and a region that defines the actual area of the AtlasTexture.
+ [Texture] resource aimed at managing big textures files that pack multiple smaller textures. Consists of a [Texture], a margin that defines the border width, and a region that defines the actual area of the AtlasTexture.
</description>
<tutorials>
</tutorials>
<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/AudioServer.xml b/doc/classes/AudioServer.xml
index 7581ae6935..2d3ceebed5 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -32,24 +32,25 @@
Adds an [AudioEffect] effect to the bus [code]bus_idx[/code] at [code]at_position[/code].
</description>
</method>
- <method name="capture_get_device">
- <return type="String">
+ <method name="capture_get_device_list">
+ <return type="Array">
</return>
<description>
+ Returns the names of all audio input devices detected on the system.
</description>
</method>
- <method name="capture_get_device_list">
- <return type="Array">
+ <method name="capture_start">
+ <return type="int" enum="Error">
</return>
<description>
+ Attempts to start recording from the audio driver's capture device. On success, the return value is [constant OK].
</description>
</method>
- <method name="capture_set_device">
- <return type="void">
+ <method name="capture_stop">
+ <return type="int" enum="Error">
</return>
- <argument index="0" name="name" type="String">
- </argument>
<description>
+ Attempts to stop recording from the audio driver's capture device. On success, the return value is [constant OK].
</description>
</method>
<method name="generate_bus_layout" qualifiers="const">
@@ -158,11 +159,32 @@
Returns the volume of the bus at index [code]bus_idx[/code] in dB.
</description>
</method>
+ <method name="get_capture_buffer">
+ <return type="PoolIntArray">
+ </return>
+ <description>
+ Returns an [PoolIntArray] containing audio frames from the capture device.
+ </description>
+ </method>
+ <method name="get_capture_position">
+ <return type="int">
+ </return>
+ <description>
+ Returns the write position of the capture device buffer.
+ </description>
+ </method>
+ <method name="get_capture_size">
+ <return type="int">
+ </return>
+ <description>
+ Returns the size of the capture device buffer.
+ </description>
+ </method>
<method name="get_device_list">
<return type="Array">
</return>
<description>
- Returns the names of all audio devices detected on the system.
+ Returns the names of all audio output devices detected on the system.
</description>
</method>
<method name="get_mix_rate" qualifiers="const">
@@ -387,14 +409,25 @@
<member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count" default="1">
Number of available audio buses.
</member>
+ <member name="capture_device" type="String" setter="capture_set_device" getter="capture_get_device" default="&quot;&quot;">
+ Name of the current device for audio input (see [method capture_get_device_list]).
+ </member>
<member name="device" type="String" setter="set_device" getter="get_device" default="&quot;Default&quot;">
- Name of the current device (see [method get_device_list]).
+ Name of the current device for audio output (see [method get_device_list]).
</member>
<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>
<signals>
+ <signal name="audio_mix_callback">
+ <description>
+ </description>
+ </signal>
+ <signal name="audio_update_callback">
+ <description>
+ </description>
+ </signal>
<signal name="bus_layout_changed">
<description>
Emitted when the [AudioBusLayout] changes.
diff --git a/doc/classes/AudioStreamGenerator.xml b/doc/classes/AudioStreamGenerator.xml
index 9d67b88c71..9a1e4432f1 100644
--- a/doc/classes/AudioStreamGenerator.xml
+++ b/doc/classes/AudioStreamGenerator.xml
@@ -5,6 +5,7 @@
<description>
</description>
<tutorials>
+ <link>https://github.com/godotengine/godot-demo-projects/tree/master/audio/generator</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/AudioStreamGeneratorPlayback.xml b/doc/classes/AudioStreamGeneratorPlayback.xml
index 310b58c4e5..448284e670 100644
--- a/doc/classes/AudioStreamGeneratorPlayback.xml
+++ b/doc/classes/AudioStreamGeneratorPlayback.xml
@@ -5,6 +5,7 @@
<description>
</description>
<tutorials>
+ <link>https://github.com/godotengine/godot-demo-projects/tree/master/audio/generator</link>
</tutorials>
<methods>
<method name="can_push_buffer" qualifiers="const">
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/AudioStreamSample.xml b/doc/classes/AudioStreamSample.xml
index 6d03301749..a496902ded 100644
--- a/doc/classes/AudioStreamSample.xml
+++ b/doc/classes/AudioStreamSample.xml
@@ -24,6 +24,7 @@
<members>
<member name="data" type="PoolByteArray" setter="set_data" getter="get_data" default="PoolByteArray( )">
Contains the audio data in bytes.
+ [b]Note:[/b] This property expects signed PCM8 data. To convert unsigned PCM8 to signed PCM8, subtract 128 from each byte.
</member>
<member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="0">
Audio format. See [code]FORMAT_*[/code] constants for values.
diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml
index 4baf3a6bb2..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>
@@ -32,8 +34,10 @@
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.
@@ -45,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].
@@ -55,7 +60,7 @@
<member name="image_path" type="String" setter="set_image_path" getter="get_image_path" default="&quot;.&quot;">
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/Basis.xml b/doc/classes/Basis.xml
index 4d5c76a75c..df9438e695 100644
--- a/doc/classes/Basis.xml
+++ b/doc/classes/Basis.xml
@@ -208,5 +208,13 @@
</member>
</members>
<constants>
+ <constant name="IDENTITY" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_X" value="Basis( -1, 0, 0, 0, 1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_Y" value="Basis( 1, 0, 0, 0, -1, 0, 0, 0, 1 )">
+ </constant>
+ <constant name="FLIP_Z" value="Basis( 1, 0, 0, 0, 1, 0, 0, 0, -1 )">
+ </constant>
</constants>
</class>
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 f92cf8fabc..305be8b58d 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -15,12 +15,15 @@
Text alignment policy for the button's text, use one of the [code]ALIGN_*[/code] constants.
</member>
<member name="clip_text" type="bool" setter="set_clip_text" getter="get_clip_text" default="false">
- When this property is enabled, text that is too large to fit the button is clipped, when disabled the Button will always be wide enough to hold the text. This property is disabled by default.
+ When this property is enabled, text that is too large to fit the button is clipped, when disabled the Button will always be wide enough to hold the text.
+ </member>
+ <member name="expand_icon" type="bool" setter="set_expand_icon" getter="is_expand_icon" default="false">
+ When enabled, the button's icon will expand/shrink to fit the button's size while keeping its aspect.
</member>
<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="&quot;&quot;">
diff --git a/doc/classes/CPUParticles.xml b/doc/classes/CPUParticles.xml
index 12e00be04a..e68b0feb2d 100644
--- a/doc/classes/CPUParticles.xml
+++ b/doc/classes/CPUParticles.xml
@@ -106,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">
@@ -115,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">
@@ -124,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">
@@ -133,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">
@@ -142,13 +142,13 @@
<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">
@@ -205,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">
@@ -220,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">
@@ -232,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">
@@ -254,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">
@@ -266,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">
@@ -281,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">
@@ -299,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 7380014b96..c8dbffb4cb 100644
--- a/doc/classes/CPUParticles2D.xml
+++ b/doc/classes/CPUParticles2D.xml
@@ -107,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">
@@ -116,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">
@@ -125,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">
@@ -134,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">
@@ -143,13 +143,13 @@
<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">
@@ -199,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">
@@ -214,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">
@@ -226,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">
@@ -235,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">
@@ -247,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">
@@ -259,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">
@@ -274,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>
@@ -292,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 750b6851b6..aeeebdf00d 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -110,7 +110,7 @@
<member name="drag_margin_bottom" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
- <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="true">
+ <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="false">
If [code]true[/code], the camera only moves when reaching the horizontal drag margins. If [code]false[/code], the camera moves horizontally regardless of margins.
</member>
<member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
@@ -122,7 +122,7 @@
<member name="drag_margin_top" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
- <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="true">
+ <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="false">
If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins.
</member>
<member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" default="false">
@@ -154,9 +154,11 @@
</member>
<member name="offset_h" type="float" setter="set_h_offset" getter="get_h_offset" default="0.0">
The horizontal offset of the camera, relative to the drag margins.
+ [b]Note:[/b] Offset H is used only to force offset relative to margins. It's not updated in any way if drag margins are enabled and can be used to set initial offset.
</member>
<member name="offset_v" type="float" setter="set_v_offset" getter="get_v_offset" default="0.0">
The vertical offset of the camera, relative to the drag margins.
+ [b]Note:[/b] Used the same as [member offset_h].
</member>
<member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Camera2D.Camera2DProcessMode" default="1">
</member>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 79e3676068..87b8f5c83d 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -519,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 80b5e90717..93c42a85a3 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -14,6 +14,7 @@
</constants>
<theme_items>
<theme_item name="check_vadjust" type="int" default="0">
+ The vertical offset used when rendering the check icons.
</theme_item>
<theme_item name="checked" type="Texture">
</theme_item>
diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml
index f4d0e0657b..4744894fc1 100644
--- a/doc/classes/CheckButton.xml
+++ b/doc/classes/CheckButton.xml
@@ -14,6 +14,7 @@
</constants>
<theme_items>
<theme_item name="check_vadjust" type="int" default="0">
+ The vertical offset used when rendering the icons.
</theme_item>
<theme_item name="disabled" type="StyleBox">
</theme_item>
diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml
index b7b77bc02a..fd08643dd5 100644
--- a/doc/classes/ClassDB.xml
+++ b/doc/classes/ClassDB.xml
@@ -134,7 +134,7 @@
<argument index="2" name="no_inheritance" type="bool" default="false">
</argument>
<description>
- Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is false) has a method called [code]method[/code] or not.
+ Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is [code]false[/code]) has a method called [code]method[/code] or not.
</description>
</method>
<method name="class_has_signal" qualifiers="const">
@@ -201,7 +201,7 @@
<argument index="0" name="class" type="String">
</argument>
<description>
- Returns whether this class is enabled or not.
+ Returns whether this [code]class[/code] is enabled or not.
</description>
</method>
<method name="is_parent_class" qualifiers="const">
diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml
index eb69a4aed4..b9ec9480cf 100644
--- a/doc/classes/CollisionObject2D.xml
+++ b/doc/classes/CollisionObject2D.xml
@@ -19,7 +19,7 @@
<argument index="2" name="shape_idx" type="int">
</argument>
<description>
- Accepts unhandled [InputEvent]s. [code]shape_idx[/code] is the child index of the clicked [Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up these events.
+ Accepts unhandled [InputEvent]s. Requires [member input_pickable] to be [code]true[/code]. [code]shape_idx[/code] is the child index of the clicked [Shape2D]. Connect to the [code]input_event[/code] signal to easily pick up these events.
</description>
</method>
<method name="create_shape_owner">
@@ -227,17 +227,17 @@
<argument index="2" name="shape_idx" type="int">
</argument>
<description>
- Emitted when an input event occurs. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set. See [method _input_event] for details.
+ Emitted when an input event occurs. Requires [member input_pickable] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set. See [method _input_event] for details.
</description>
</signal>
<signal name="mouse_entered">
<description>
- Emitted when the mouse pointer enters any of this object's shapes. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
+ Emitted when the mouse pointer enters any of this object's shapes. Requires [member input_pickable] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
</description>
</signal>
<signal name="mouse_exited">
<description>
- Emitted when the mouse pointer exits all this object's shapes. Requires [code]input_pickable[/code] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
+ Emitted when the mouse pointer exits all this object's shapes. Requires [member input_pickable] to be [code]true[/code] and at least one [code]collision_layer[/code] bit to be set.
</description>
</signal>
</signals>
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/Control.xml b/doc/classes/Control.xml
index 8ca0bb0b9b..05ffac803a 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Control" inherits="CanvasItem" category="Core" version="3.2">
<brief_description>
- All User Interface nodes inherit from Control. A control's anchors and margins adapt its position and size relative to its parent.
+ All user interface nodes inherit from Control. A control's anchors and margins adapt its position and size relative to its parent.
</brief_description>
<description>
Base class for all UI-related nodes. [Control] features a bounding rectangle that defines its extents, an anchor position relative to its parent control or the current viewport, and margins that represent an offset to the anchor. The margins update automatically when the node, any of its parents, or the screen size change.
@@ -21,13 +21,16 @@
<return type="bool">
</return>
<description>
+ Virtual method to be implemented by the user. Returns whether [method _gui_input] should not be called for children controls outside this control's rectangle. Input will be clipped to the Rect of this [Control]. Similar to [member rect_clip_content], but doesn't affect visibility.
+ If not overridden, defaults to [code]false[/code].
</description>
</method>
<method name="_get_minimum_size" qualifiers="virtual">
<return type="Vector2">
</return>
<description>
- Returns the minimum size for this control. See [member rect_min_size].
+ Virtual method to be implemented by the user. Returns the minimum size for this control. Alternative to [member rect_min_size] for controlling minimum size via code. The actual minimum size will be the max value of these two (in each axis separately).
+ If not overridden, defaults to [constant Vector2.ZERO].
</description>
</method>
<method name="_gui_input" qualifiers="virtual">
@@ -36,8 +39,20 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Use this method to process and accept inputs on UI elements. See [method accept_event].
- Replaces Godot 2's [code]_input_event[/code].
+ Virtual method to be implemented by the user. Use this method to process and accept inputs on UI elements. See [method accept_event].
+ Example: clicking a control.
+ [codeblock]
+ func _gui_input(event):
+ if event is InputEventMouseButton:
+ if event.button_index == BUTTON_LEFT and event.pressed:
+ print("I've been clicked D:")
+ [/codeblock]
+ The event won't trigger if:
+ * clicking outside the control (see [method has_point]);
+ * control has [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE];
+ * control is obstructed by another [Control] on top of it, which doesn't have [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE];
+ * control's parent has [member mouse_filter] set to [constant MOUSE_FILTER_STOP] or has accepted the event;
+ * it happens outside parent's rectangle and the parent has either [member rect_clip_content] or [method _clips_input] enabled.
</description>
</method>
<method name="_make_custom_tooltip" qualifiers="virtual">
@@ -46,6 +61,23 @@
<argument index="0" name="for_text" type="String">
</argument>
<description>
+ Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. Use [code]for_text[/code] parameter to determine what text the tooltip should contain (likely the contents of [member hint_tooltip]).
+ The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When null or non-Control node is returned, the default tooltip will be used instead.
+ [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value.
+ Example of usage with custom-constructed node:
+ [codeblock]
+ func _make_custom_tooltip(for_text):
+ var label = Label.new()
+ label.text = for_text
+ return label
+ [/codeblock]
+ Example of usage with custom scene instance:
+ [codeblock]
+ func _make_custom_tooltip(for_text):
+ var tooltip = preload("SomeTooltipScene.tscn").instance()
+ tooltip.get_node("Label").text = for_text
+ return tooltip
+ [/codeblock]
</description>
</method>
<method name="accept_event">
@@ -63,7 +95,7 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
- Overrides the color in the [member theme] resource the node uses.
+ Overrides the [Color] with given [code]name[/code] in the [member theme] resource the control uses. If the [code]color[/code] is empty or invalid, the override is cleared and the color from assigned [Theme] is used.
</description>
</method>
<method name="add_constant_override">
@@ -74,7 +106,7 @@
<argument index="1" name="constant" type="int">
</argument>
<description>
- Overrides an integer constant in the [member theme] resource the node uses. If the [code]constant[/code] is invalid, Godot clears the override.
+ Overrides an integer constant with given [code]name[/code] in the [member theme] resource the control uses. If the [code]constant[/code] is empty or invalid, the override is cleared and the constant from assigned [Theme] is used.
</description>
</method>
<method name="add_font_override">
@@ -85,7 +117,7 @@
<argument index="1" name="font" type="Font">
</argument>
<description>
- Overrides the [code]name[/code] font in the [member theme] resource the node uses. If [code]font[/code] is empty, Godot clears the override.
+ Overrides the font with given [code]name[/code] in the [member theme] resource the control uses. If [code]font[/code] is empty or invalid, the override is cleared and the font from assigned [Theme] is used.
</description>
</method>
<method name="add_icon_override">
@@ -96,7 +128,7 @@
<argument index="1" name="texture" type="Texture">
</argument>
<description>
- Overrides the [code]name[/code] icon in the [member theme] resource the node uses. If [code]icon[/code] is empty, Godot clears the override.
+ Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. If [code]icon[/code] is empty or invalid, the override is cleared and the icon from assigned [Theme] is used.
</description>
</method>
<method name="add_shader_override">
@@ -107,7 +139,7 @@
<argument index="1" name="shader" type="Shader">
</argument>
<description>
- Overrides the [code]name[/code] shader in the [member theme] resource the node uses. If [code]shader[/code] is empty, Godot clears the override.
+ Overrides the [Shader] with given [code]name[/code] in the [member theme] resource the control uses. If [code]shader[/code] is empty or invalid, the override is cleared and the shader from assigned [Theme] is used.
</description>
</method>
<method name="add_stylebox_override">
@@ -118,7 +150,7 @@
<argument index="1" name="stylebox" type="StyleBox">
</argument>
<description>
- Overrides the [code]name[/code] [StyleBox] in the [member theme] resource the node uses. If [code]stylebox[/code] is empty, Godot clears the override.
+ Overrides the [StyleBox] with given [code]name[/code] in the [member theme] resource the control uses. If [code]stylebox[/code] is empty or invalid, the override is cleared and the [StyleBox] from assigned [Theme] is used.
</description>
</method>
<method name="can_drop_data" qualifiers="virtual">
@@ -132,8 +164,6 @@
Godot calls this method to test if [code]data[/code] from a control's [method get_drag_data] can be dropped at [code]position[/code]. [code]position[/code] is local to this control.
This method should only be used to test the data. Process the data in [method drop_data].
[codeblock]
- extends Control
-
func can_drop_data(position, data):
# Check position if it is relevant to you
# Otherwise, just check data
@@ -151,8 +181,6 @@
<description>
Godot calls this method to pass you the [code]data[/code] from a control's [method get_drag_data] result. Godot first calls [method can_drop_data] to test if [code]data[/code] is allowed to drop at [code]position[/code] where [code]position[/code] is local to this control.
[codeblock]
- extends ColorRect
-
func can_drop_data(position, data):
return typeof(data) == TYPE_DICTIONARY and data.has("color")
@@ -179,6 +207,7 @@
<argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
+ Returns the anchor identified by [code]margin[/code] constant from [enum Margin] enum. A getter method for [member anchor_bottom], [member anchor_left], [member anchor_right] and [member anchor_top].
</description>
</method>
<method name="get_begin" qualifiers="const">
@@ -196,12 +225,18 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns a color from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
+ [codeblock]
+ func _ready():
+ modulate = get_color("font_color", "Button") #get the color defined for button fonts
+ [/codeblock]
</description>
</method>
<method name="get_combined_minimum_size" qualifiers="const">
<return type="Vector2">
</return>
<description>
+ Returns combined minimum size from [member rect_min_size] and [method get_minimum_size].
</description>
</method>
<method name="get_constant" qualifiers="const">
@@ -212,6 +247,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns a constant from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
</description>
</method>
<method name="get_cursor_shape" qualifiers="const">
@@ -224,7 +260,7 @@
</description>
</method>
<method name="get_drag_data" qualifiers="virtual">
- <return type="Object">
+ <return type="Variant">
</return>
<argument index="0" name="position" type="Vector2">
</argument>
@@ -232,8 +268,6 @@
Godot calls this method to get data that can be dragged and dropped onto controls that expect drop data. Returns [code]null[/code] if there is no data to drag. Controls that want to receive drop data should implement [method can_drop_data] and [method drop_data]. [code]position[/code] is local to this control. Drag may be forced with [method force_drag].
A preview that will follow the mouse that should represent the data can be set with [method set_drag_preview]. A good time to set the preview is in this method.
[codeblock]
- extends Control
-
func get_drag_data(position):
var mydata = make_data()
set_drag_preview(make_preview(mydata))
@@ -254,6 +288,7 @@
<argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
+ Returns the focus neighbour identified by [code]margin[/code] constant from [enum Margin] enum. A getter method for [member focus_neighbour_bottom], [member focus_neighbour_left], [member focus_neighbour_right] and [member focus_neighbour_top].
</description>
</method>
<method name="get_focus_owner" qualifiers="const">
@@ -271,6 +306,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns a font from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
</description>
</method>
<method name="get_global_rect" qualifiers="const">
@@ -288,6 +324,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns an icon from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
</description>
</method>
<method name="get_margin" qualifiers="const">
@@ -296,6 +333,7 @@
<argument index="0" name="margin" type="int" enum="Margin">
</argument>
<description>
+ Returns the anchor identified by [code]margin[/code] constant from [enum Margin] enum. A getter method for [member margin_bottom], [member margin_left], [member margin_right] and [member margin_top].
</description>
</method>
<method name="get_minimum_size" qualifiers="const">
@@ -341,6 +379,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns a [StyleBox] from assigned [Theme] with given [code]name[/code] and associated with [Control] of given [code]type[/code].
</description>
</method>
<method name="get_tooltip" qualifiers="const">
@@ -349,13 +388,18 @@
<argument index="0" name="at_position" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
- Returns the tooltip, which will appear when the cursor is resting over this control.
+ Returns the tooltip, which will appear when the cursor is resting over this control. See [member hint_tooltip].
</description>
</method>
<method name="grab_click_focus">
<return type="void">
</return>
<description>
+ Creates an [InputEventMouseButton] that attempts to click the control. If the event is received, the control acquires focus.
+ [codeblock]
+ func _process(delta):
+ grab_click_focus() #when clicking another Control node, this node will be clicked instead
+ [/codeblock]
</description>
</method>
<method name="grab_focus">
@@ -373,6 +417,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns [code]true[/code] if [Color] with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme].
</description>
</method>
<method name="has_color_override" qualifiers="const">
@@ -381,6 +426,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if [Color] with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="has_constant" qualifiers="const">
@@ -391,6 +437,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns [code]true[/code] if constant with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme].
</description>
</method>
<method name="has_constant_override" qualifiers="const">
@@ -399,6 +446,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if constant with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="has_focus" qualifiers="const">
@@ -416,6 +464,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns [code]true[/code] if font with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme].
</description>
</method>
<method name="has_font_override" qualifiers="const">
@@ -424,6 +473,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if font with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="has_icon" qualifiers="const">
@@ -434,6 +484,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns [code]true[/code] if icon with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme].
</description>
</method>
<method name="has_icon_override" qualifiers="const">
@@ -442,6 +493,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if icon with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="has_point" qualifiers="virtual">
@@ -450,6 +502,9 @@
<argument index="0" name="point" type="Vector2">
</argument>
<description>
+ Virtual method to be implemented by the user. Returns whether the given [code]point[/code] is inside this control.
+ If not overridden, default behavior is checking if the point is within control's Rect.
+ [b]Node:[/b] If you want to check if a point is inside the control, you can use [code]get_rect().has_point(point)[/code].
</description>
</method>
<method name="has_shader_override" qualifiers="const">
@@ -458,6 +513,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if [Shader] with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="has_stylebox" qualifiers="const">
@@ -468,6 +524,7 @@
<argument index="1" name="type" type="String" default="&quot;&quot;">
</argument>
<description>
+ Returns [code]true[/code] if [StyleBox] with given [code]name[/code] and associated with [Control] of given [code]type[/code] exists in assigned [Theme].
</description>
</method>
<method name="has_stylebox_override" qualifiers="const">
@@ -476,12 +533,14 @@
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns [code]true[/code] if [StyleBox] with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
<method name="minimum_size_changed">
<return type="void">
</return>
<description>
+ Invalidates the size cache in this node and in parent nodes up to toplevel. Intended to be used with [method get_minimum_size] when the return value is changed. Setting [member rect_min_size] directly calls this method automatically.
</description>
</method>
<method name="release_focus">
@@ -503,6 +562,9 @@
<argument index="3" name="push_opposite_anchor" type="bool" default="true">
</argument>
<description>
+ Sets the anchor identified by [code]margin[/code] constant from [enum Margin] enum to value [code]anchor[/code]. A setter method for [member anchor_bottom], [member anchor_left], [member anchor_right] and [member anchor_top].
+ If [code]keep_margin[/code] is [code]true[/code], margins aren't updated after this operation.
+ If [code]push_opposite_anchor[/code] is [code]true[/code] and the opposite anchor overlaps this anchor, the opposite one will have its value overridden. For example, when setting left anchor to 1 and the right anchor has value of 0.5, the right anchor will also get value of 1. If [code]push_opposite_anchor[/code] was [code]false[/code], the left anchor would get value 0.5.
</description>
</method>
<method name="set_anchor_and_margin">
@@ -517,6 +579,7 @@
<argument index="3" name="push_opposite_anchor" type="bool" default="false">
</argument>
<description>
+ Works the same as [method set_anchor], but instead of [code]keep_margin[/code] argument and automatic update of margin, it allows to set the margin offset yourself (see [method set_margin]).
</description>
</method>
<method name="set_anchors_and_margins_preset">
@@ -529,6 +592,7 @@
<argument index="2" name="margin" type="int" default="0">
</argument>
<description>
+ Sets both anchor preset and margin preset. See [method set_anchors_preset] and [method set_margins_preset].
</description>
</method>
<method name="set_anchors_preset">
@@ -539,6 +603,8 @@
<argument index="1" name="keep_margins" type="bool" default="false">
</argument>
<description>
+ Sets the anchors to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is code equivalent of using the Layout menu in 2D editor.
+ If [code]keep_margins[/code] is [code]true[/code], control's position will also be updated.
</description>
</method>
<method name="set_begin">
@@ -547,7 +613,7 @@
<argument index="0" name="position" type="Vector2">
</argument>
<description>
- Sets [member margin_left] and [member margin_top] at the same time.
+ Sets [member margin_left] and [member margin_top] at the same time. Equivalent of changing [member rect_position].
</description>
</method>
<method name="set_drag_forwarding">
@@ -606,6 +672,7 @@
<argument index="1" name="neighbour" type="NodePath">
</argument>
<description>
+ Sets the anchor identified by [code]margin[/code] constant from [enum Margin] enum to [Control] at [code]neighbor[/code] node path. A setter method for [member focus_neighbour_bottom], [member focus_neighbour_left], [member focus_neighbour_right] and [member focus_neighbour_top].
</description>
</method>
<method name="set_global_position">
@@ -616,6 +683,8 @@
<argument index="1" name="keep_margins" type="bool" default="false">
</argument>
<description>
+ Sets the [member rect_global_position] to given [code]position[/code].
+ If [code]keep_margins[/code] is [code]true[/code], control's anchors will be updated instead of margins.
</description>
</method>
<method name="set_margin">
@@ -626,6 +695,7 @@
<argument index="1" name="offset" type="float">
</argument>
<description>
+ Sets the margin identified by [code]margin[/code] constant from [enum Margin] enum to given [code]offset[/code]. A setter method for [member margin_bottom], [member margin_left], [member margin_right] and [member margin_top].
</description>
</method>
<method name="set_margins_preset">
@@ -638,6 +708,9 @@
<argument index="2" name="margin" type="int" default="0">
</argument>
<description>
+ Sets the margins to a [code]preset[/code] from [enum Control.LayoutPreset] enum. This is code equivalent of using the Layout menu in 2D editor.
+ Use parameter [code]resize_mode[/code] with constants from [enum Control.LayoutPresetMode] to better determine the resulting size of the [Control]. Constant size will be ignored if used with presets that change size, e.g. [code]PRESET_LEFT_WIDE[/code].
+ Use parameter [code]margin[/code] to determine the gap between the [Control] and the edges.
</description>
</method>
<method name="set_position">
@@ -648,6 +721,8 @@
<argument index="1" name="keep_margins" type="bool" default="false">
</argument>
<description>
+ Sets the [member rect_position] to given [code]position[/code].
+ If [code]keep_margins[/code] is [code]true[/code], control's anchors will be updated instead of margins.
</description>
</method>
<method name="set_rotation">
@@ -667,6 +742,8 @@
<argument index="1" name="keep_margins" type="bool" default="false">
</argument>
<description>
+ Sets the size (see [member rect_size]).
+ If [code]keep_margins[/code] is [code]true[/code], control's anchors will be updated instead of margins.
</description>
</method>
<method name="show_modal">
@@ -676,6 +753,7 @@
</argument>
<description>
Displays a control as modal. Control must be a subwindow. Modal controls capture the input signals until closed or the area outside them is accessed. When a modal control loses focus, or the ESC key is pressed, they automatically hide. Modal controls are used extensively for popup dialogs and menus.
+ If [code]exclusive[/code] is [code]true[/code], other controls will not receive input and clicking outside this control will not close it.
</description>
</method>
<method name="warp_mouse">
@@ -684,21 +762,22 @@
<argument index="0" name="to_position" type="Vector2">
</argument>
<description>
+ Moves the mouse cursor to [code]to_position[/code], relative to [member rect_position] of this [Control].
</description>
</method>
</methods>
<members>
<member name="anchor_bottom" type="float" setter="_set_anchor" getter="get_anchor" default="0.0">
- Anchors the bottom edge of the node to the origin, the center, or the end of its parent control. It changes how the bottom margin updates when the node moves or changes size. You can use one of the [code]ANCHOR_*[/code] constants for convenience.
+ Anchors the bottom edge of the node to the origin, the center, or the end of its parent control. It changes how the bottom margin updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="anchor_left" type="float" setter="_set_anchor" getter="get_anchor" default="0.0">
- Anchors the left edge of the node to the origin, the center or the end of its parent control. It changes how the left margin updates when the node moves or changes size. You can use one of the [code]ANCHOR_*[/code] constants for convenience.
+ Anchors the left edge of the node to the origin, the center or the end of its parent control. It changes how the left margin updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="anchor_right" type="float" setter="_set_anchor" getter="get_anchor" default="0.0">
- Anchors the right edge of the node to the origin, the center or the end of its parent control. It changes how the right margin updates when the node moves or changes size. You can use one of the [code]ANCHOR_*[/code] constants for convenience.
+ Anchors the right edge of the node to the origin, the center or the end of its parent control. It changes how the right margin updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="anchor_top" type="float" setter="_set_anchor" getter="get_anchor" default="0.0">
- Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top margin updates when the node moves or changes size. You can use one of the [code]ANCHOR_*[/code] constants for convenience.
+ Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top margin updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0">
The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals.
@@ -730,7 +809,7 @@
Controls the direction on the vertical axis in which the control should grow if its vertical minimum size is changed to be greater than its current size, as the control always has to be at least the minimum size.
</member>
<member name="hint_tooltip" type="String" setter="set_tooltip" getter="_get_tooltip" default="&quot;&quot;">
- Changes the tooltip text. The tooltip appears when the user's mouse cursor stays idle over this control for a few moments, provided that the [member mouse_filter] property is not [constant MOUSE_FILTER_IGNORE].
+ Changes the tooltip text. The tooltip appears when the user's mouse cursor stays idle over this control for a few moments, provided that the [member mouse_filter] property is not [constant MOUSE_FILTER_IGNORE]. You can change the time required for the tooltip to appear with [code]gui/timers/tooltip_delay_sec[/code] option in Project Settings.
</member>
<member name="margin_bottom" type="float" setter="set_margin" getter="get_margin" default="0.0">
Distance between the node's bottom edge and its parent control, based on [member anchor_bottom].
@@ -780,15 +859,15 @@
The size of the node's bounding rectangle, in pixels. [Container] nodes update this property automatically.
</member>
<member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" default="1">
- Tells the parent [Container] nodes how they should resize and place the node on the X axis. Use one of the [code]SIZE_*[/code] constants to change the flags. See the constants to learn what each does.
+ Tells the parent [Container] nodes how they should resize and place the node on the X axis. Use one of the [enum SizeFlags] constants to change the flags. See the constants to learn what each does.
</member>
<member name="size_flags_stretch_ratio" type="float" setter="set_stretch_ratio" getter="get_stretch_ratio" default="1.0">
If the node and at least one of its neighbours uses the [constant SIZE_EXPAND] size flag, the parent [Container] will let it take more or less space depending on this property. If this node has a stretch ratio of 2 and its neighbour a ratio of 1, this node will take two thirds of the available space.
</member>
<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.
+ Tells the parent [Container] nodes how they should resize and place the node on the Y axis. Use one of the [enum SizeFlags] 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>
@@ -978,12 +1057,16 @@
Snap all 4 anchors to the respective corners of the parent control. Set all 4 margins to 0 after you applied this preset and the [Control] will fit its parent control. This is equivalent to the "Full Rect" layout option in the editor. Use with [method set_anchors_preset].
</constant>
<constant name="PRESET_MODE_MINSIZE" value="0" enum="LayoutPresetMode">
+ The control will be resized to its minimum size.
</constant>
<constant name="PRESET_MODE_KEEP_WIDTH" value="1" enum="LayoutPresetMode">
+ The control's width will not change.
</constant>
<constant name="PRESET_MODE_KEEP_HEIGHT" value="2" enum="LayoutPresetMode">
+ The control's height will not change.
</constant>
<constant name="PRESET_MODE_KEEP_SIZE" value="3" enum="LayoutPresetMode">
+ The control's size will not change.
</constant>
<constant name="SIZE_FILL" value="1" enum="SizeFlags">
Tells the parent [Container] to expand the bounds of this node to fill all the available space without pushing any other node. Use with [member size_flags_horizontal] and [member size_flags_vertical].
diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml
new file mode 100644
index 0000000000..bb852f5fff
--- /dev/null
+++ b/doc/classes/Crypto.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Crypto" inherits="Reference" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="generate_random_bytes">
+ <return type="PoolByteArray">
+ </return>
+ <argument index="0" name="size" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="generate_rsa">
+ <return type="CryptoKey">
+ </return>
+ <argument index="0" name="size" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="generate_self_signed_certificate">
+ <return type="X509Certificate">
+ </return>
+ <argument index="0" name="key" type="CryptoKey">
+ </argument>
+ <argument index="1" name="issuer_name" type="String" default="&quot;CN=myserver,O=myorganisation,C=IT&quot;">
+ </argument>
+ <argument index="2" name="not_before" type="String" default="&quot;20140101000000&quot;">
+ </argument>
+ <argument index="3" name="not_after" type="String" default="&quot;20340101000000&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/CryptoKey.xml b/doc/classes/CryptoKey.xml
new file mode 100644
index 0000000000..d3cd485a5f
--- /dev/null
+++ b/doc/classes/CryptoKey.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="CryptoKey" inherits="Resource" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="load">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="save">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
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/DirectionalLight.xml b/doc/classes/DirectionalLight.xml
index 4d0ff7f13b..687e7519b2 100644
--- a/doc/classes/DirectionalLight.xml
+++ b/doc/classes/DirectionalLight.xml
@@ -21,7 +21,7 @@
<member name="directional_shadow_depth_range" type="int" setter="set_shadow_depth_range" getter="get_shadow_depth_range" enum="DirectionalLight.ShadowDepthRange" default="0">
Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange].
</member>
- <member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="200.0">
+ <member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="100.0">
The maximum distance for shadow splits.
</member>
<member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="DirectionalLight.ShadowMode" default="2">
diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml
index 9294a515d2..8aae85563a 100644
--- a/doc/classes/Directory.xml
+++ b/doc/classes/Directory.xml
@@ -127,8 +127,8 @@
</argument>
<description>
Initializes the stream used to list all files and directories using the [method get_next] function, closing the current opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end].
- If you pass [code]skip_navigational[/code], then [code].[/code] and [code]..[/code] would be filtered out.
- If you pass [code]skip_hidden[/code], then hidden files would be filtered out.
+ If [code]skip_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are filtered out.
+ If [code]skip_hidden[/code] is [code]true[/code], hidden files are filtered out.
</description>
</method>
<method name="list_dir_end">
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index ac707d09bc..0820d4e1b6 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -92,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/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 6f07682b04..4f7a6d89a9 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -166,6 +166,23 @@
<argument index="0" name="file" type="String">
</argument>
<description>
+ Selects the file, with the path provided by [code]file[/code], in the FileSystem dock.
+ </description>
+ </method>
+ <method name="set_distraction_free_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="enter" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_main_screen_editor">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
</description>
</method>
<method name="set_plugin_enabled">
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index bd9a100267..89e2f0580b 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -29,7 +29,7 @@
<argument index="1" name="title" type="String">
</argument>
<description>
- Adds a control to the bottom panel (together with Output, Debug, Animation, etc). Returns a reference to the button added. It's up to you to hide/show the button when needed. When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_bottom_panel] and free it with [code]queue_free()[/code].
+ Adds a control to the bottom panel (together with Output, Debug, Animation, etc). Returns a reference to the button added. It's up to you to hide/show the button when needed. When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_bottom_panel] and free it with [method Node.queue_free].
</description>
</method>
<method name="add_control_to_container">
@@ -40,9 +40,9 @@
<argument index="1" name="control" type="Control">
</argument>
<description>
- Adds a custom control to a container (see [code]CONTAINER_*[/code] enum). There are many locations where custom controls can be added in the editor UI.
+ Adds a custom control to a container (see [enum CustomControlContainer]). There are many locations where custom controls can be added in the editor UI.
Please remember that you have to manage the visibility of your custom controls yourself (and likely hide it after adding it).
- When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_container] and free it with [code]queue_free()[/code].
+ When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_container] and free it with [method Node.queue_free].
</description>
</method>
<method name="add_control_to_dock">
@@ -53,9 +53,9 @@
<argument index="1" name="control" type="Control">
</argument>
<description>
- Adds the control to a specific dock slot (see [code]DOCK_*[/code] enum for options).
+ Adds the control to a specific dock slot (see [enum DockSlot] for options).
If the dock is repositioned and as long as the plugin is active, the editor will save the dock position on further sessions.
- When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_docks] and free it with [code]queue_free()[/code].
+ When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_docks] and free it with [method Node.queue_free].
</description>
</method>
<method name="add_custom_type">
@@ -128,7 +128,7 @@
<argument index="3" name="ud" type="Variant" default="null">
</argument>
<description>
- Adds a custom menu to [b]Project &gt; Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it.
+ Adds a custom menu item to [b]Project &gt; Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it.
</description>
</method>
<method name="add_tool_submenu_item">
@@ -139,7 +139,7 @@
<argument index="1" name="submenu" type="Object">
</argument>
<description>
- Like [method add_tool_menu_item] but adds the [code]submenu[/code] item inside the [code]name[/code] menu.
+ Adds a custom submenu under [b]Project &gt; Tools &gt;[/b] [code]name[/code]. [code]submenu[/code] should be an object of class [PopupMenu]. This submenu should be cleaned up using [code]remove_tool_menu_item(name)[/code].
</description>
</method>
<method name="apply_changes" qualifiers="virtual">
@@ -167,6 +167,7 @@
<return type="void">
</return>
<description>
+ Called by the engine when the user disables the [EditorPlugin] in the Plugin tab of the project settings window.
</description>
</method>
<method name="edit" qualifiers="virtual">
@@ -182,6 +183,7 @@
<return type="void">
</return>
<description>
+ Called by the engine when the user enables the [EditorPlugin] in the Plugin tab of the project settings window.
</description>
</method>
<method name="forward_canvas_draw_over_viewport" qualifiers="virtual">
@@ -190,12 +192,6 @@
<argument index="0" name="overlay" type="Control">
</argument>
<description>
- This method is called when there is an input event in the 2D viewport, e.g. the user clicks with the mouse in the 2D space (canvas GUI). Keep in mind that for this method to be called you have to first declare the virtual method [method handles] so the editor knows that you want to work with the workspace:
- [codeblock]
- func handles(object):
- return true
- [/codeblock]
- Also note that the edited scene must have a root node.
</description>
</method>
<method name="forward_canvas_force_draw_over_viewport" qualifiers="virtual">
@@ -212,6 +208,22 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
+ Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
+ [codeblock]
+ # Prevents the InputEvent to reach other Editor classes
+ func forward_canvas_gui_input(event):
+ var forward = true
+ return forward
+ [/codeblock]
+ Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example:
+ [codeblock]
+ # Consumes InputEventMouseMotion and forwards other InputEvent types
+ func forward_canvas_gui_input(event):
+ var forward = false
+ if event is InputEventMouseMotion:
+ forward = true
+ return forward
+ [/codeblock]
</description>
</method>
<method name="forward_spatial_gui_input" qualifiers="virtual">
@@ -222,12 +234,22 @@
<argument index="1" name="event" type="InputEvent">
</argument>
<description>
- This method is called when there is an input event in the 3D viewport, e.g. the user clicks with the mouse in the 3D space (spatial GUI). Keep in mind that for this method to be called you have to first declare the virtual method [method handles] so the editor knows that you want to work with the workspace:
+ Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
+ [codeblock]
+ # Prevents the InputEvent to reach other Editor classes
+ func forward_spatial_gui_input(camera, event):
+ var forward = true
+ return forward
+ [/codeblock]
+ Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example:
[codeblock]
- func handles(object):
- return true
+ # Consumes InputEventMouseMotion and forwards other InputEvent types
+ func forward_spatial_gui_input(camera, event):
+ var forward = false
+ if event is InputEventMouseMotion:
+ forward = true
+ return forward
[/codeblock]
- Also note that the edited scene must have a root node.
</description>
</method>
<method name="get_breakpoints" qualifiers="virtual">
@@ -349,7 +371,7 @@
<argument index="0" name="control" type="Control">
</argument>
<description>
- Removes the control from the bottom panel. You have to manually [code]queue_free()[/code] the control.
+ Removes the control from the bottom panel. You have to manually [method Node.queue_free] the control.
</description>
</method>
<method name="remove_control_from_container">
@@ -360,7 +382,7 @@
<argument index="1" name="control" type="Control">
</argument>
<description>
- Removes the control from the specified container. You have to manually [code]queue_free()[/code] the control.
+ Removes the control from the specified container. You have to manually [method Node.queue_free] the control.
</description>
</method>
<method name="remove_control_from_docks">
@@ -369,7 +391,7 @@
<argument index="0" name="control" type="Control">
</argument>
<description>
- Removes the control from the dock. You have to manually [code]queue_free()[/code] the control.
+ Removes the control from the dock. You have to manually [method Node.queue_free] the control.
</description>
</method>
<method name="remove_custom_type">
diff --git a/doc/classes/EditorSceneImporter.xml b/doc/classes/EditorSceneImporter.xml
index 4707543c91..96d8ce698d 100644
--- a/doc/classes/EditorSceneImporter.xml
+++ b/doc/classes/EditorSceneImporter.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSceneImporter" inherits="Reference" category="Core" version="3.2">
<brief_description>
+ Imports scenes from third-parties' 3D files.
</brief_description>
<description>
</description>
diff --git a/doc/classes/EditorVCSInterface.xml b/doc/classes/EditorVCSInterface.xml
new file mode 100644
index 0000000000..f67c1c9eb5
--- /dev/null
+++ b/doc/classes/EditorVCSInterface.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="EditorVCSInterface" inherits="Object" category="Core" version="3.2">
+ <brief_description>
+ Version Control System (VCS) interface which reads and writes to the local VCS in use.
+ </brief_description>
+ <description>
+ Used by the editor to display VCS extracted information in the editor. The implementation of this API is included in VCS addons, which are essentially GDNative plugins that need to be put into the project folder. These VCS addons are scripts which are attached (on demand) to the object instance of [code]EditorVCSInterface[/code]. All the functions listed below, instead of performing the task themselves, they call the internally defined functions in the VCS addons to provide a plug-n-play experience.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="commit">
+ <return type="void">
+ </return>
+ <argument index="0" name="msg" type="String">
+ </argument>
+ <description>
+ Creates a version commit if the addon is initialized, else returns without doing anything. Uses the files which have been staged previously, with the commit message set to a value as provided as in the argument.
+ </description>
+ </method>
+ <method name="get_file_diff">
+ <return type="Array">
+ </return>
+ <argument index="0" name="file_path" type="String">
+ </argument>
+ <description>
+ Returns an [Array] of [Dictionary] objects containing the diff output from the VCS in use, if a VCS addon is initialized, else returns an empty [Array] object. The diff contents also consist of some contextual lines which provide context to the observed line change in the file.
+ Each [Dictionary] object has the line diff contents under the keys:
+ - [code]"content"[/code] to store a [String] containing the line contents
+ - [code]"status"[/code] to store a [String] which contains [code]"+"[/code] in case the content is a line addition but it stores a [code]"-"[/code] in case of deletion and an empty string in the case the line content is neither an addition nor a deletion.
+ - [code]"new_line_number"[/code] to store an integer containing the new line number of the line content.
+ - [code]"line_count"[/code] to store an integer containing the number of lines in the line content.
+ - [code]"old_line_number"[/code] to store an integer containing the old line number of the line content.
+ - [code]"offset"[/code] to store the offset of the line change since the first contextual line content.
+ </description>
+ </method>
+ <method name="get_is_vcs_intialized">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the VCS addon has been initialized, else returns [code]false[/code].
+ </description>
+ </method>
+ <method name="get_modified_files_data">
+ <return type="Dictionary">
+ </return>
+ <description>
+ Returns a [Dictionary] containing the path of the detected file change mapped to an integer signifying what kind of a change the corresponding file has experienced.
+ The following integer values are being used to signify that the detected file is:
+ - [code]0[/code]: New to the VCS working directory
+ - [code]1[/code]: Modified
+ - [code]2[/code]: Renamed
+ - [code]3[/code]: Deleted
+ - [code]4[/code]: Typechanged
+ </description>
+ </method>
+ <method name="get_project_name">
+ <return type="String">
+ </return>
+ <description>
+ Return the project name of the VCS working directory
+ </description>
+ </method>
+ <method name="get_vcs_name">
+ <return type="String">
+ </return>
+ <description>
+ Return the name of the VCS if the VCS has been initialized, else return an empty string.
+ </description>
+ </method>
+ <method name="initialize">
+ <return type="bool">
+ </return>
+ <argument index="0" name="project_root_path" type="String">
+ </argument>
+ <description>
+ Initialize the VCS addon if not already. Uses the argument value as the path to the working directory of the project. Creates the initial commit if required. Returns [code]true[/code] if no failure occurs, else returns [code]false[/code].
+ </description>
+ </method>
+ <method name="is_addon_ready">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the addon is ready to respond to function calls, else returns [code]false[/code].
+ </description>
+ </method>
+ <method name="shut_down">
+ <return type="bool">
+ </return>
+ <description>
+ Shuts down the VCS addon to allow cleanup code to run on call. Returns [code]true[/code] is no failure occurs, else returns [code]false[/code].
+ </description>
+ </method>
+ <method name="stage_file">
+ <return type="void">
+ </return>
+ <argument index="0" name="file_path" type="String">
+ </argument>
+ <description>
+ Stage the file which should be committed when [method EditorVCSInterface.commit] is called. Argument should contain the absolute path.
+ </description>
+ </method>
+ <method name="unstage_file">
+ <return type="void">
+ </return>
+ <argument index="0" name="file_path" type="String">
+ </argument>
+ <description>
+ Unstage the file which was staged previously to be committed, so that it is no longer committed when [method EditorVCSInterface.commit] is called. Argument should contain the absolute path.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index 60a807c304..187e13d7bd 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -72,6 +72,13 @@
Returns the main loop object (see [MainLoop] and [SceneTree]).
</description>
</method>
+ <method name="get_physics_interpolation_fraction" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ Returns the fraction through the current physics tick we are at the time of rendering the frame. This can be used to implement fixed timestep interpolation.
+ </description>
+ </method>
<method name="get_singleton" qualifiers="const">
<return type="Object">
</return>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 613c5b6563..9a943aba51 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -38,7 +38,7 @@
<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">
@@ -89,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">
@@ -146,10 +146,11 @@
<member name="fog_depth_enabled" type="bool" setter="set_fog_depth_enabled" getter="is_fog_depth_enabled" default="true">
Enables the fog depth.
</member>
- <member name="fog_depth_end" type="float" setter="set_fog_depth_end" getter="get_fog_depth_end" default="0.0">
+ <member name="fog_depth_end" type="float" setter="set_fog_depth_end" getter="get_fog_depth_end" default="100.0">
+ Fog's depth end distance from the camera. If this value is set to 0, it will be equal to the current camera's [member Camera.far] value.
</member>
<member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" default="false">
- Enables the fog. Needs fog_height_enabled and/or for_depth_enabled to actually display fog.
+ Enables the fog. Needs [member fog_height_enabled] and/or [member fog_depth_enabled] to actually display fog.
</member>
<member name="fog_height_curve" type="float" setter="set_fog_height_curve" getter="get_fog_height_curve" default="1.0">
Value defining the fog height intensity.
@@ -157,11 +158,11 @@
<member name="fog_height_enabled" type="bool" setter="set_fog_height_enabled" getter="is_fog_height_enabled" default="false">
Enables the fog height.
</member>
- <member name="fog_height_max" type="float" setter="set_fog_height_max" getter="get_fog_height_max" default="100.0">
- Maximum height of fog.
+ <member name="fog_height_max" type="float" setter="set_fog_height_max" getter="get_fog_height_max" default="0.0">
+ The Y coordinate where the height fog will be the most intense. If this value is greater than [member fog_height_min], fog will be displayed from bottom to top. Otherwise, it will be displayed from top to bottom.
</member>
- <member name="fog_height_min" type="float" setter="set_fog_height_min" getter="get_fog_height_min" default="0.0">
- Minimum height of fog.
+ <member name="fog_height_min" type="float" setter="set_fog_height_min" getter="get_fog_height_min" default="10.0">
+ The Y coordinate where the height fog will be the least intense. If this value is greater than [member fog_height_max], fog will be displayed from top to bottom. Otherwise, it will be displayed from bottom to top.
</member>
<member name="fog_sun_amount" type="float" setter="set_fog_sun_amount" getter="get_fog_sun_amount" default="0.0">
Amount of sun that affects the fog rendering.
@@ -305,7 +306,7 @@
Replace glow blending mode. Replaces all pixels' color by the glow value.
</constant>
<constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper">
- Linear tonemapper operator. Reads the linear data and performs an exposure adjustment.
+ Linear tonemapper operator. Reads the linear data and passes it on unmodified.
</constant>
<constant name="TONE_MAPPER_REINHARDT" value="1" enum="ToneMapper">
Reinhardt tonemapper operator. Performs a variation on rendered pixels' colors by this formula: [code]color = color / (1 + color)[/code].
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index e78f21b274..4f1e8cc309 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -134,6 +134,8 @@
</theme_item>
<theme_item name="folder" type="Texture">
</theme_item>
+ <theme_item name="folder_icon_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
+ </theme_item>
<theme_item name="parent_folder" type="Texture">
</theme_item>
<theme_item name="reload" type="Texture">
diff --git a/doc/classes/FuncRef.xml b/doc/classes/FuncRef.xml
index e35d7a68c5..9803ae0838 100644
--- a/doc/classes/FuncRef.xml
+++ b/doc/classes/FuncRef.xml
@@ -17,10 +17,20 @@
Calls the referenced function previously set by [method set_function] or [method @GDScript.funcref].
</description>
</method>
+ <method name="call_funcv">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="arg_array" type="Array">
+ </argument>
+ <description>
+ Calls the referenced function previously set by [method set_function] or [method @GDScript.funcref]. Contrarily to [method call_func], this method does not support a variable number of arguments but expects all parameters to be passed via a single [Array].
+ </description>
+ </method>
<method name="is_valid" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether the object still exists and has the function assigned.
</description>
</method>
<method name="set_function">
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/Geometry.xml b/doc/classes/Geometry.xml
index 3cbbe6da56..3824baa4dc 100644
--- a/doc/classes/Geometry.xml
+++ b/doc/classes/Geometry.xml
@@ -216,6 +216,19 @@
Intersects [code]polyline[/code] with [code]polygon[/code] and returns an array of intersected polylines. This performs [constant OPERATION_INTERSECTION] between the polyline and the polygon. This operation can be thought of as chopping a line with a closed shape.
</description>
</method>
+ <method name="is_point_in_circle">
+ <return type="bool">
+ </return>
+ <argument index="0" name="point" type="Vector2">
+ </argument>
+ <argument index="1" name="circle_position" type="Vector2">
+ </argument>
+ <argument index="2" name="circle_radius" type="float">
+ </argument>
+ <description>
+ Returns [code]true[/code] if [code]point[/code] is inside the circle or if it's located exactly [i]on[/i] the circle's boundary, otherwise returns [code]false[/code].
+ </description>
+ </method>
<method name="is_point_in_polygon">
<return type="bool">
</return>
@@ -428,18 +441,6 @@
Tests if the segment ([code]from[/code], [code]to[/code]) intersects the triangle [code]a[/code], [code]b[/code], [code]c[/code]. If yes, returns the point of intersection as [Vector3]. If no intersection takes place, an empty [Variant] is returned.
</description>
</method>
- <method name="transform_points_2d">
- <return type="PoolVector2Array">
- </return>
- <argument index="0" name="points" type="PoolVector2Array">
- </argument>
- <argument index="1" name="transform" type="Transform2D">
- </argument>
- <description>
- Transforms an array of points by [code]transform[/code] and returns the result.
- Can be useful in conjunction with performing polygon boolean operations in a CSG-like manner, see [method merge_polygons_2d], [method clip_polygons_2d], [method intersect_polygons_2d], [method exclude_polygons_2d].
- </description>
- </method>
<method name="triangulate_delaunay_2d">
<return type="PoolIntArray">
</return>
diff --git a/doc/classes/GeometryInstance.xml b/doc/classes/GeometryInstance.xml
index 49c1ce480f..02f2c27043 100644
--- a/doc/classes/GeometryInstance.xml
+++ b/doc/classes/GeometryInstance.xml
@@ -46,22 +46,26 @@
</member>
<member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0">
The GeometryInstance's max LOD distance.
+ [b]Note:[/b] This property currently has no effect.
</member>
<member name="lod_max_hysteresis" type="float" setter="set_lod_max_hysteresis" getter="get_lod_max_hysteresis" default="0.0">
The GeometryInstance's max LOD margin.
+ [b]Note:[/b] This property currently has no effect.
</member>
<member name="lod_min_distance" type="float" setter="set_lod_min_distance" getter="get_lod_min_distance" default="0.0">
The GeometryInstance's min LOD distance.
+ [b]Note:[/b] This property currently has no effect.
</member>
<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.
+ [b]Note:[/b] This property currently has no effect.
</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.
+ If a material is assigned to this property, it will be used instead of any material set in any material slot of the mesh.
</member>
<member name="use_in_baked_light" type="bool" setter="set_flag" getter="get_flag" default="false">
- If [code]true[/code], this GeometryInstance will be used when baking lights using a [GIProbe] and/or any other form of baked lighting.
+ If [code]true[/code], this GeometryInstance will be used when baking lights using a [GIProbe] or [BakedLightmap].
</member>
</members>
<constants>
@@ -78,10 +82,10 @@
</constant>
<constant name="SHADOW_CASTING_SETTING_SHADOWS_ONLY" value="3" enum="ShadowCastingSetting">
Will only show the shadows casted from this object.
- In other words: The actual mesh will not be visible, only the shadows casted from the mesh.
+ In other words, the actual mesh will not be visible, only the shadows casted from the mesh will be.
</constant>
<constant name="FLAG_USE_BAKED_LIGHT" value="0" enum="Flags">
- Will allow the GeometryInstance to be used when baking lights using a [GIProbe] and/or any other form of baked lighting.
+ Will allow the GeometryInstance to be used when baking lights using a [GIProbe] or [BakedLightmap].
</constant>
<constant name="FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="1" enum="Flags">
Unused in this class, exposed for consistency with [enum VisualServer.InstanceFlags].
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/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 111bf2109e..3cc40b7cef 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -233,6 +233,11 @@
Signal sent when user dragging connection from output port into empty space of the graph.
</description>
</signal>
+ <signal name="copy_nodes_request">
+ <description>
+ Signal sent when the user presses [code]Ctrl + C[/code].
+ </description>
+ </signal>
<signal name="delete_nodes_request">
<description>
Signal sent when a GraphNode is attempted to be removed from the GraphEdit.
@@ -263,6 +268,11 @@
Emitted when a GraphNode is selected.
</description>
</signal>
+ <signal name="paste_nodes_request">
+ <description>
+ Signal sent when the user presses [code]Ctrl + V[/code].
+ </description>
+ </signal>
<signal name="popup_request">
<argument index="0" name="position" type="Vector2">
</argument>
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index 6bc09e5289..8470a346ff 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -174,6 +174,7 @@
</methods>
<members>
<member name="comment" type="bool" setter="set_comment" getter="is_comment" default="false">
+ If [code]true[/code], the GraphNode is a comment node.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
The offset of the GraphNode, relative to the scroll offset of the [GraphEdit].
@@ -257,6 +258,8 @@
</theme_item>
<theme_item name="resizer" type="Texture">
</theme_item>
+ <theme_item name="resizer_color" type="Color" default="Color( 0, 0, 0, 1 )">
+ </theme_item>
<theme_item name="selectedframe" type="StyleBox">
</theme_item>
<theme_item name="separation" type="int" default="1">
diff --git a/doc/classes/HashingContext.xml b/doc/classes/HashingContext.xml
new file mode 100644
index 0000000000..552a74eba4
--- /dev/null
+++ b/doc/classes/HashingContext.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="HashingContext" inherits="Reference" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="finish">
+ <return type="PoolByteArray">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="start">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="type" type="int" enum="HashingContext.HashType">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="update">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="chunk" type="PoolByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ <constant name="HASH_MD5" value="0" enum="HashType">
+ </constant>
+ <constant name="HASH_SHA1" value="1" enum="HashType">
+ </constant>
+ <constant name="HASH_SHA256" value="2" enum="HashType">
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 65d5fbedc3..d297bc98ae 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -252,7 +252,7 @@
<argument index="1" name="y" type="int">
</argument>
<description>
- Returns the color of the pixel at [code](x, y)[/code] if the image is locked. If the image is unlocked it always returns a [Color] with the value [code](0, 0, 0, 1.0)[/code].
+ Returns the color of the pixel at [code](x, y)[/code] if the image is locked. If the image is unlocked, it always returns a [Color] with the value [code](0, 0, 0, 1.0)[/code]. This is the same as [method get_pixelv], but two integer arguments instead of a Vector2 argument.
</description>
</method>
<method name="get_pixelv" qualifiers="const">
@@ -261,6 +261,7 @@
<argument index="0" name="src" type="Vector2">
</argument>
<description>
+ Returns the color of the pixel at [code]src[/code] if the image is locked. If the image is unlocked, it always returns a [Color] with the value [code](0, 0, 0, 1.0)[/code]. This is the same as [method get_pixel], but with a Vector2 argument instead of two integer arguments.
</description>
</method>
<method name="get_rect" qualifiers="const">
@@ -406,6 +407,17 @@
<description>
</description>
</method>
+ <method name="save_exr" qualifiers="const">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="grayscale" type="bool" default="false">
+ </argument>
+ <description>
+ Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitly as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
+ </description>
+ </method>
<method name="save_png" qualifiers="const">
<return type="int" enum="Error">
</return>
@@ -469,13 +481,7 @@
</method>
</methods>
<members>
- <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{
-&quot;data&quot;: PoolByteArray( ),
-&quot;format&quot;: &quot;Lum8&quot;,
-&quot;height&quot;: 0,
-&quot;mipmaps&quot;: false,
-&quot;width&quot;: 0
-}">
+ <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{&quot;data&quot;: PoolByteArray( ),&quot;format&quot;: &quot;Lum8&quot;,&quot;height&quot;: 0,&quot;mipmaps&quot;: false,&quot;width&quot;: 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..afb3977849 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -20,6 +20,7 @@
<description>
This will simulate pressing the specified action.
The strength can be used for non-boolean actions, it's ranged between 0 and 1 representing the intensity of the given action.
+ [b]Note:[/b] This method will not cause any [method Node._input] calls. It is intended to be used with [method is_action_pressed] and [method is_action_just_pressed]. If you want to simulate [code]_input[/code], use [method parse_input_event] instead.
</description>
</method>
<method name="action_release">
@@ -222,7 +223,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
- Returns [code]true[/code] if you are pressing the action event.
+ Returns [code]true[/code] if you are pressing the action event. Note that if an action has multiple buttons assigned and more than one of them is pressed, releasing one button will release the action, even if some other button assigned to this action is still pressed.
</description>
</method>
<method name="is_joy_button_pressed" qualifiers="const">
@@ -283,7 +284,14 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Feeds an [InputEvent] to the game. Can be used to artificially trigger input events from code.
+ Feeds an [InputEvent] to the game. Can be used to artificially trigger input events from code. Also generates [method Node._input] calls.
+ Example:
+ [codeblock]
+ var a = InputEventAction.new()
+ a.action = "ui_cancel"
+ a.pressed = true
+ Input.parse_input_event(a)
+ [/codeblock]
</description>
</method>
<method name="remove_joy_mapping">
@@ -308,6 +316,8 @@
Sets a custom mouse cursor image, which is only visible inside the game window. The hotspot can also be specified. Passing [code]null[/code] to the image parameter resets to the system cursor. See enum [code]CURSOR_*[/code] for the list of shapes.
[code]image[/code]'s size must be lower than 256×256.
[code]hotspot[/code] must be within [code]image[/code]'s size.
+ [b]Note:[/b] [AnimatedTexture]s aren't supported as custom mouse cursors. If using an [AnimatedTexture], only the first frame will be displayed.
+ [b]Note:[/b] Only images imported with the [b]Lossless[/b], [b]Lossy[/b] or [b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] compression mode can't be used for custom cursors.
</description>
</method>
<method name="set_default_cursor_shape">
@@ -318,6 +328,7 @@
<description>
Sets the default cursor shape to be used in the viewport instead of [constant CURSOR_ARROW].
[b]Note:[/b] If you want to change the default cursor shape for [Control]'s nodes, use [member Control.mouse_default_cursor_shape] instead.
+ [b]Note:[/b] This method generates an [InputEventMouseMotion] to update cursor immediately.
</description>
</method>
<method name="set_mouse_mode">
@@ -363,6 +374,16 @@
Stops the vibration of the joypad.
</description>
</method>
+ <method name="vibrate_handheld">
+ <return type="void">
+ </return>
+ <argument index="0" name="duration_ms" type="int" default="500">
+ </argument>
+ <description>
+ Vibrate Android and iOS devices.
+ [b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS does not support duration.
+ </description>
+ </method>
<method name="warp_mouse_position">
<return type="void">
</return>
@@ -392,7 +413,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/InputEvent.xml b/doc/classes/InputEvent.xml
index f2c00908f6..4c8d83adba 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -17,6 +17,8 @@
<argument index="0" name="with_event" type="InputEvent">
</argument>
<description>
+ Returns [code]true[/code] if the given input event and this input event can be added together (only for events of type [InputEventMouseMotion]).
+ The given input event's position, global position and speed will be copied. The resulting [code]relative[/code] is a sum of both events. Both events' modifiers have to be identical.
</description>
</method>
<method name="as_text" qualifiers="const">
@@ -32,6 +34,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
+ Returns a value between 0.0 and 1.0 depending on the given actions' state. Useful for getting the value of events of type [InputEventJoypadMotion].
</description>
</method>
<method name="is_action" qualifiers="const">
@@ -88,6 +91,7 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
+ Returns [code]true[/code] if the given input event is checking for the same key ([InputEventKey]), button ([InputEventJoypadButton]) or action ([InputEventAction]).
</description>
</method>
<method name="xformed_by" qualifiers="const">
@@ -98,6 +102,7 @@
<argument index="1" name="local_ofs" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
+ Returns a copy of the given input event which has been offset by [code]local_ofs[/code] and transformed by [code]xform[/code]. Relevant for events of type [InputEventMouseButton], [InputEventMouseMotion], [InputEventScreenTouch], [InputEventScreenDrag], [InputEventMagnifyGesture] and [InputEventPanGesture].
</description>
</method>
</methods>
diff --git a/doc/classes/JSONRPC.xml b/doc/classes/JSONRPC.xml
new file mode 100644
index 0000000000..921161afb4
--- /dev/null
+++ b/doc/classes/JSONRPC.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="JSONRPC" inherits="Object" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="make_notification">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="method" type="String">
+ </argument>
+ <argument index="1" name="params" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="make_request">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="method" type="String">
+ </argument>
+ <argument index="1" name="params" type="Variant">
+ </argument>
+ <argument index="2" name="id" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="make_response">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="result" type="Variant">
+ </argument>
+ <argument index="1" name="id" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="make_response_error" qualifiers="const">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="code" type="int">
+ </argument>
+ <argument index="1" name="message" type="String">
+ </argument>
+ <argument index="2" name="id" type="Variant" default="null">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="process_action">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="action" type="Variant">
+ </argument>
+ <argument index="1" name="recurse" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="process_string">
+ <return type="String">
+ </return>
+ <argument index="0" name="action" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_scope">
+ <return type="void">
+ </return>
+ <argument index="0" name="scope" type="String">
+ </argument>
+ <argument index="1" name="target" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ <constant name="ParseError" value="-32700" enum="ErrorCode">
+ </constant>
+ <constant name="InvalidRequest" value="-32600" enum="ErrorCode">
+ </constant>
+ <constant name="MethodNotFound" value="-32601" enum="ErrorCode">
+ </constant>
+ <constant name="InvalidParams" value="-32602" enum="ErrorCode">
+ </constant>
+ <constant name="InternalError" value="-32603" enum="ErrorCode">
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml
index b7c4200b95..2fab689f89 100644
--- a/doc/classes/KinematicBody.xml
+++ b/doc/classes/KinematicBody.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses:
- [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
+ [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
[b]Kinematic characters:[/b] KinematicBody also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<tutorials>
diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml
index 39d84c6e31..99a83765eb 100644
--- a/doc/classes/KinematicBody2D.xml
+++ b/doc/classes/KinematicBody2D.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all; to other types of bodies, such as a character or a rigid body, these are the same as a static body. However, they have two main uses:
- [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
+ [b]Simulated motion:[/b] When these bodies are moved manually, either from code or from an [AnimationPlayer] (with [member AnimationPlayer.playback_process_mode] set to "physics"), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc).
[b]Kinematic characters:[/b] KinematicBody2D also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<tutorials>
@@ -76,6 +76,7 @@
</argument>
<description>
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision.
+ If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
</description>
</method>
<method name="move_and_slide">
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/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 106c736147..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">
@@ -99,7 +99,7 @@
<member name="width" type="float" setter="set_width" getter="get_width" default="10.0">
The line's width.
</member>
- <member name="width_curve" type="Curve" setter="set_curve" getter="get_curve" default="null">
+ <member name="width_curve" type="Curve" setter="set_curve" getter="get_curve">
The line's width varies with the curve. The original width is simply multiply by the value of the Curve.
</member>
</members>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index d90a290fdc..c1dca9f95e 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -119,6 +119,9 @@
<member name="placeholder_text" type="String" setter="set_placeholder" getter="get_placeholder" default="&quot;&quot;">
Text shown when the [LineEdit] is empty. It is [b]not[/b] the [LineEdit]'s default value (see [member text]).
</member>
+ <member name="right_icon" type="Texture" setter="set_right_icon" getter="get_right_icon">
+ Sets the icon that will appear in the right end of the [LineEdit] if there's no [member text], or always, if [member clear_button_enabled] is set to [code]false[/code].
+ </member>
<member name="secret" type="bool" setter="set_secret" getter="is_secret" default="false">
If [code]true[/code], every character is replaced with the secret character (see [member secret_character]).
</member>
diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml
index f5bf12a876..23ce20a434 100644
--- a/doc/classes/MainLoop.xml
+++ b/doc/classes/MainLoop.xml
@@ -4,7 +4,7 @@
Abstract base class for the game's main loop.
</brief_description>
<description>
- [MainLoop] is the abstract base class for a Godot project's game loop. It in inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree.
+ [MainLoop] is the abstract base class for a Godot project's game loop. It is inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree.
Upon the application start, a [MainLoop] implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a [SceneTree] is created) unless a main [Script] is provided from the command line (with e.g. [code]godot -s my_loop.gd[/code], which should then be a [MainLoop] implementation.
Here is an example script implementing a simple [MainLoop]:
[codeblock]
@@ -61,6 +61,16 @@
Called before the program exits.
</description>
</method>
+ <method name="_global_menu_action" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="Variant">
+ </argument>
+ <argument index="1" name="meta" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="_idle" qualifiers="virtual">
<return type="bool">
</return>
@@ -205,5 +215,13 @@
Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string).
Specific to the macOS platform.
</constant>
+ <constant name="NOTIFICATION_APP_RESUMED" value="1014">
+ Notification received from the OS when the app is resumed.
+ Specific to the Android platform.
+ </constant>
+ <constant name="NOTIFICATION_APP_PAUSED" value="1015">
+ Notification received from the OS when the app is paused.
+ Specific to the Android platform.
+ </constant>
</constants>
</class>
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/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(&quot;..&quot;)">
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 c50c1b6079..ce7a6ef54c 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -51,9 +51,9 @@
The height of the 9-slice's top row.
</member>
<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.
+ 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. If the rect is empty, NinePatchRect will use the whole texture.
</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 889ce4d3eb..b206d4a4d2 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -122,6 +122,12 @@
<description>
Adds a child node. Nodes can have any number of children, but every child must have a unique name. Child nodes are automatically deleted when the parent node is deleted, so an entire scene can be removed by deleting its topmost node.
If [code]legible_unique_name[/code] is [code]true[/code], the child node will have an human-readable name based on the name of the node being instanced instead of its type.
+ [b]Note:[/b] If the child node already has a parent, the function will fail. Use [method remove_child] first to remove the node from its current parent. For example:
+ [codeblock]
+ if child_node.get_parent():
+ child_node.get_parent().remove_child(child_node)
+ add_child(child_node)
+ [/codeblock]
</description>
</method>
<method name="add_child_below_node">
@@ -165,6 +171,7 @@
<description>
Duplicates the node, returning a new node.
You can fine-tune the behavior using the [code]flags[/code] (see [enum DuplicateFlags]).
+ [b]Note:[/b] It will not work properly if the node contains a script with constructor arguments (i.e. needs to supply arguments to [method Object._init] method). In that case, the node will be duplicated without a script.
</description>
</method>
<method name="find_node" qualifiers="const">
@@ -956,6 +963,14 @@
Notification received from the OS when an update of the Input Method Engine occurs (e.g. change of IME cursor position or composition string).
Specific to the macOS platform.
</constant>
+ <constant name="NOTIFICATION_APP_RESUMED" value="1014">
+ Notification received from the OS when the app is resumed.
+ Specific to the Android platform.
+ </constant>
+ <constant name="NOTIFICATION_APP_PAUSED" value="1015">
+ Notification received from the OS when the app is paused.
+ Specific to the Android platform.
+ </constant>
<constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode">
Inherits pause mode from the node's parent. For the root node, it is equivalent to [constant PAUSE_MODE_STOP]. Default.
</constant>
diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml
index abdbfa09f7..29c4680685 100644
--- a/doc/classes/Node2D.xml
+++ b/doc/classes/Node2D.xml
@@ -52,7 +52,7 @@
<argument index="0" name="point" type="Vector2">
</argument>
<description>
- Rotates the node so it points towards the [code]point[/code].
+ Rotates the node so it points towards the [code]point[/code], which is expected to use global coordinates.
</description>
</method>
<method name="move_local_x">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index c770e78c7c..938777a36b 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -497,6 +497,50 @@
Returns unobscured area of the window where interactive controls should be rendered.
</description>
</method>
+ <method name="global_menu_add_item">
+ <return type="void">
+ </return>
+ <argument index="0" name="menu" type="String">
+ </argument>
+ <argument index="1" name="label" type="String">
+ </argument>
+ <argument index="2" name="id" type="Variant">
+ </argument>
+ <argument index="3" name="meta" type="Variant">
+ </argument>
+ <description>
+ Add a new item with text "label" to global menu. Use "_dock" menu to add item to the macOS dock icon menu.
+ </description>
+ </method>
+ <method name="global_menu_add_separator">
+ <return type="void">
+ </return>
+ <argument index="0" name="menu" type="String">
+ </argument>
+ <description>
+ Add a separator between items. Separators also occupy an index.
+ </description>
+ </method>
+ <method name="global_menu_clear">
+ <return type="void">
+ </return>
+ <argument index="0" name="menu" type="String">
+ </argument>
+ <description>
+ Clear the global menu, in effect removing all items.
+ </description>
+ </method>
+ <method name="global_menu_remove_item">
+ <return type="void">
+ </return>
+ <argument index="0" name="menu" type="String">
+ </argument>
+ <argument index="1" name="idx" type="int">
+ </argument>
+ <description>
+ Removes the item at index "idx" from the global menu. Note that the indexes of items after the removed item are going to be shifted by one.
+ </description>
+ </method>
<method name="has_environment" qualifiers="const">
<return type="bool">
</return>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index b87e912b45..4b77197e29 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -112,7 +112,7 @@
<argument index="1" name="arg_array" type="Array">
</argument>
<description>
- Calls the [code]method[/code] on the object and returns the result. Contrarily to [method call], this method does not support a variable number of arguments but expected all parameters passed via a single [Array].
+ Calls the [code]method[/code] on the object and returns the result. Contrarily to [method call], this method does not support a variable number of arguments but expects all parameters to be via a single [Array].
[codeblock]
callv("set", [ "position", Vector2(42.0, 0.0) ])
[/codeblock]
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="{
-&quot;conn_count&quot;: 0,
-&quot;conns&quot;: PoolIntArray( ),
-&quot;editable_instances&quot;: [ ],
-&quot;names&quot;: PoolStringArray( ),
-&quot;node_count&quot;: 0,
-&quot;node_paths&quot;: [ ],
-&quot;nodes&quot;: PoolIntArray( ),
-&quot;variants&quot;: [ ],
-&quot;version&quot;: 2
-}">
+ <member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene" default="{&quot;conn_count&quot;: 0,&quot;conns&quot;: PoolIntArray( ),&quot;editable_instances&quot;: [ ],&quot;names&quot;: PoolStringArray( ),&quot;node_count&quot;: 0,&quot;node_paths&quot;: [ ],&quot;nodes&quot;: PoolIntArray( ),&quot;variants&quot;: [ ],&quot;version&quot;: 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 3b9a0554e8..fb74c5a3d4 100644
--- a/doc/classes/Particles.xml
+++ b/doc/classes/Particles.xml
@@ -51,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">
@@ -90,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 624a8d4dc5..64751cdf76 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -89,7 +89,7 @@
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">
@@ -99,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">
@@ -108,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">
@@ -117,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">
@@ -126,13 +126,13 @@
<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">
@@ -180,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">
@@ -192,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">
@@ -214,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">
@@ -223,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">
@@ -235,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,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;bake_interval&quot;:0.2,&quot;_data&quot;:{
-&quot;points&quot;: PoolVector3Array( ),
-&quot;tilts&quot;: PoolRealArray( )
-},&quot;up_vector_enabled&quot;:true,&quot;script&quot;: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,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;bake_interval&quot;:5.0,&quot;_data&quot;:{
-&quot;points&quot;: PoolVector2Array( )
-},&quot;script&quot;:null)
-">
+ <member name="curve" type="Curve2D" setter="set_curve" getter="get_curve">
A [Curve2D] describing the path.
</member>
</members>
diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml
index ba00438ea1..a139fa4664 100644
--- a/doc/classes/Physics2DServer.xml
+++ b/doc/classes/Physics2DServer.xml
@@ -822,7 +822,7 @@
<argument index="5" name="result" type="Physics2DTestMotionResult" default="null">
</argument>
<description>
- Returns whether a body can move from a given point in a given direction. Apart from the boolean return value, a [Physics2DTestMotionResult] can be passed to return additional information in.
+ Returns [code]true[/code] if a collision would result from moving in the given direction from a given point in space. Margin increases the size of the shapes involved in the collision detection. [Physics2DTestMotionResult] can be passed to return additional information in.
</description>
</method>
<method name="capsule_shape_create">
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/PointMesh.xml b/doc/classes/PointMesh.xml
new file mode 100644
index 0000000000..dc7dd065cf
--- /dev/null
+++ b/doc/classes/PointMesh.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="PointMesh" inherits="PrimitiveMesh" category="Core" version="3.2">
+ <brief_description>
+ Mesh with a single Point primitive.
+ </brief_description>
+ <description>
+ The PointMesh is made from a single point. Instead of relying on triangles, points are rendered as a single rectangle on the screen with a constant size. They are intended to be used with Particle systems, but can be used as a cheap way to render constant size billboarded sprites (for example in a point cloud).
+ PointMeshes, must be used with a material that has a point size. Point size can be accessed in a shader with [code]POINT_SIZE[/code], or in a [SpatialMaterial] by setting [member SpatialMaterial.flags_use_point_size] and the variable [member SpatialMaterial.params_point_size].
+ When using PointMeshes, properties that normally alter vertices will be ignored, including billboard mode, grow, and cull face.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
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(&quot;&quot;)">
</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/PoolByteArray.xml b/doc/classes/PoolByteArray.xml
index 08848e789b..21bf078017 100644
--- a/doc/classes/PoolByteArray.xml
+++ b/doc/classes/PoolByteArray.xml
@@ -67,6 +67,12 @@
Returns a copy of the array's contents as [String]. Slower than [method get_string_from_ascii] but supports UTF-8 encoded data. Use this function if you are unsure about the source of the data. For user input this function should always be preferred.
</description>
</method>
+ <method name="hex_encode">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
@@ -113,13 +119,6 @@
Changes the byte at the given index.
</description>
</method>
- <method name="sha256_string">
- <return type="String">
- </return>
- <description>
- Returns SHA-256 string of the PoolByteArray.
- </description>
- </method>
<method name="size">
<return type="int">
</return>
diff --git a/doc/classes/PoolIntArray.xml b/doc/classes/PoolIntArray.xml
index 730833b097..28a28b2bba 100644
--- a/doc/classes/PoolIntArray.xml
+++ b/doc/classes/PoolIntArray.xml
@@ -6,6 +6,7 @@
<description>
An [Array] specifically designed to hold integer values ([int]). Optimized for memory usage, does not fragment the memory.
[b]Note:[/b] This type is passed by value and not by reference.
+ [b]Note:[/b] This type is limited to signed 32-bit integers, which means it can only take values in the interval [code][-2^31, 2^31 - 1][/code], i.e. [code][-2147483648, 2147483647][/code]. Exceeding those bounds will wrap around. In comparison, [int] uses signed 64-bit integers which can hold much larger values.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml
index 1e24aadfd9..fb8168c344 100644
--- a/doc/classes/Popup.xml
+++ b/doc/classes/Popup.xml
@@ -56,6 +56,13 @@
Popup (show the control in modal form) in the center of the screen relative to the current canvas transform, scaled at a ratio of size of the screen.
</description>
</method>
+ <method name="set_as_minsize">
+ <return type="void">
+ </return>
+ <description>
+ Shrink popup to keep to the minimum size of content.
+ </description>
+ </method>
</methods>
<members>
<member name="popup_exclusive" type="bool" setter="set_exclusive" getter="is_exclusive" default="false">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 3d6693da15..d917f7d7f8 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -233,7 +233,7 @@
<argument index="0" name="id" type="int">
</argument>
<description>
- Returns the index of the item containing the specified [code]id[/code]. Index is automatically assigned to each item by the engine. Index can not be set manualy.
+ Returns the index of the item containing the specified [code]id[/code]. Index is automatically assigned to each item by the engine. Index can not be set manually.
</description>
</method>
<method name="get_item_metadata" qualifiers="const">
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/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 22dae4fe71..b42a10b13b 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -180,6 +180,9 @@
This user directory is used for storing persistent data ([code]user://[/code] filesystem). If left empty, [code]user://[/code] resolves to a project-specific folder in Godot's own configuration folder (see [method OS.get_user_data_dir]). If a custom directory name is defined, this name will be used instead and appended to the system-specific user data directory (same parent folder as the Godot configuration folder documented in [method OS.get_user_data_dir]).
The [member application/config/use_custom_user_dir] setting must be enabled for this to take effect.
</member>
+ <member name="application/config/description" type="String" setter="" getter="" default="&quot;&quot;">
+ The project's description, displayed as a tooltip in the Project Manager when hovering the project.
+ </member>
<member name="application/config/icon" type="String" setter="" getter="" default="&quot;&quot;">
Icon used for the project, set when project loads. Exporters will also use this icon when possible.
</member>
@@ -412,6 +415,8 @@
<member name="editor/active" type="bool" setter="" getter="" default="false">
Internal editor setting, don't touch.
</member>
+ <member name="editor/script_templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
+ </member>
<member name="editor/search_in_file_extensions" type="PoolStringArray" setter="" getter="" default="PoolStringArray( &quot;gd&quot;, &quot;shader&quot; )">
</member>
<member name="gui/common/default_scroll_deadzone" type="int" setter="" getter="" default="0">
@@ -434,92 +439,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="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777221,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777222,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:32,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:0,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_cancel" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777217,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:1,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_down" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777234,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:13,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_end" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777230,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_focus_next" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777218,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_focus_prev" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:true,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777218,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_home" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777229,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_left" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777231,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:14,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_page_down" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777236,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_page_up" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777235,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_right" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777233,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:15,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_select" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:32,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:3,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
- </member>
- <member name="input/ui_up" type="Dictionary" setter="" getter="" default="{
-&quot;deadzone&quot;: 0.5,
-&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777232,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null)
-, Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:12,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null)
- ]
-}">
+ <member name="input/ui_accept" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777221,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777222,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:32,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:0,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_cancel" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777217,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:1,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_down" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777234,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:13,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_end" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777230,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_focus_next" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777218,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_focus_prev" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:true,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777218,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_home" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777229,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_left" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777231,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:14,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_page_down" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777236,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_page_up" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777235,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_right" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777233,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:15,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_select" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:32,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:3,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;:null) ]}">
+ </member>
+ <member name="input/ui_up" type="Dictionary" setter="" getter="" default="{&quot;deadzone&quot;: 0.5,&quot;events&quot;: [ Object(InputEventKey,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;alt&quot;:false,&quot;shift&quot;:false,&quot;control&quot;:false,&quot;meta&quot;:false,&quot;command&quot;:false,&quot;pressed&quot;:false,&quot;scancode&quot;:16777232,&quot;unicode&quot;:0,&quot;echo&quot;:false,&quot;script&quot;:null), Object(InputEventJoypadButton,&quot;resource_local_to_scene&quot;:false,&quot;resource_name&quot;:&quot;&quot;,&quot;device&quot;:0,&quot;button_index&quot;:12,&quot;pressure&quot;:0.0,&quot;pressed&quot;:false,&quot;script&quot;: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.
@@ -711,17 +655,22 @@
<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
- <member name="network/limits/debugger_stdout/max_errors_per_frame" type="int" setter="" getter="" default="10">
- Maximum amount of errors allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
+ <member name="network/limits/debugger_stdout/max_errors_per_second" type="int" setter="" getter="" default="100">
+ Maximum number of errors allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
<member name="network/limits/debugger_stdout/max_messages_per_frame" type="int" setter="" getter="" default="10">
Maximum amount of messages allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
+ <member name="network/limits/debugger_stdout/max_warnings_per_second" type="int" setter="" getter="" default="100">
+ Maximum number of warnings allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
+ </member>
<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/webrtc/max_channel_in_buffer_kb" type="int" setter="" getter="" default="64">
+ </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">
@@ -744,6 +693,8 @@
<member name="network/remote_fs/page_size" type="int" setter="" getter="" default="65536">
Page size used by remote filesystem (in bytes).
</member>
+ <member name="network/ssl/certificates" type="String" setter="" getter="" default="&quot;&quot;">
+ </member>
<member name="node/name_casing" type="int" setter="" getter="" default="0">
When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
</member>
@@ -771,7 +722,7 @@
Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS.
</member>
<member name="rendering/environment/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )">
- Default background clear color. Overriddable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method VisualServer.set_default_clear_color].
+ Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method VisualServer.set_default_clear_color].
</member>
<member name="rendering/limits/buffers/blend_shape_max_buffer_size_kb" type="int" setter="" getter="" default="4096">
Max buffer size for blend shapes. Any blend shape bigger than this will not work.
@@ -788,6 +739,12 @@
<member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="65536">
Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves.
</member>
+ <member name="rendering/limits/rendering/max_renderable_lights" type="int" setter="" getter="" default="4096">
+ Max number of lights renderable in a frame. If more than this number are used, they will be ignored. On some systems (particularly web) setting this number as low as possible can increase the speed of shader compilation.
+ </member>
+ <member name="rendering/limits/rendering/max_renderable_reflections" type="int" setter="" getter="" default="1024">
+ Max number of reflection probes renderable in a frame. If more than this number are used, they will be ignored. On some systems (particularly web) setting this number as low as possible can increase the speed of shader compilation.
+ </member>
<member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
Shaders have a time variable that constantly increases. At some point, it needs to be rolled back to zero to avoid precision errors on shader animations. This setting specifies when (in seconds).
</member>
@@ -886,7 +843,7 @@
<member name="rendering/quality/subsurface_scattering/weight_samples" type="bool" setter="" getter="" default="true">
Weight subsurface scattering samples. Helps to avoid reading samples from unrelated parts of the screen.
</member>
- <member name="rendering/quality/voxel_cone_tracing/high_quality" type="bool" setter="" getter="" default="true">
+ <member name="rendering/quality/voxel_cone_tracing/high_quality" type="bool" setter="" getter="" default="false">
Use high-quality voxel cone tracing. This results in better-looking reflections, but is much more expensive on the GPU.
</member>
<member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1">
@@ -907,7 +864,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/ResourceFormatLoaderCrypto.xml b/doc/classes/ResourceFormatLoaderCrypto.xml
new file mode 100644
index 0000000000..8bc7d50c75
--- /dev/null
+++ b/doc/classes/ResourceFormatLoaderCrypto.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ResourceFormatLoaderCrypto" inherits="ResourceFormatLoader" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/ResourceFormatSaverCrypto.xml b/doc/classes/ResourceFormatSaverCrypto.xml
new file mode 100644
index 0000000000..2f7d224dab
--- /dev/null
+++ b/doc/classes/ResourceFormatSaverCrypto.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ResourceFormatSaverCrypto" inherits="ResourceFormatSaver" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RigidBody.xml b/doc/classes/RigidBody.xml
index 07eed6bb34..4378fc3ffe 100644
--- a/doc/classes/RigidBody.xml
+++ b/doc/classes/RigidBody.xml
@@ -182,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..32a1634f77 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -154,7 +154,7 @@
Multiplies the gravity applied to the body. The body's gravity is calculated from the [b]Default Gravity[/b] value in [b]Project &gt; Project Settings &gt; Physics &gt; 2d[/b] and/or any additional gravity vector applied by [Area2D]s.
</member>
<member name="inertia" type="float" setter="set_inertia" getter="get_inertia">
- The body's moment of inertia. This is like mass, but for rotation: it determines how much torque it takes to rotate the body. The moment of inertia is usually computed automatically from the mass and the shapes, but this function allows you to set a custom value. Set 0 (or negative) inertia to return to automatically computing it.
+ The body's moment of inertia. This is like mass, but for rotation: it determines how much torque it takes to rotate the body. The moment of inertia is usually computed automatically from the mass and the shapes, but this function allows you to set a custom value. Set 0 inertia to return to automatically computing it.
</member>
<member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="-1.0">
Damps the body's [member linear_velocity]. If [code]-1[/code], the body will use the [b]Default Linear Damp[/b] in [b]Project &gt; Project Settings &gt; Physics &gt; 2d[/b].
@@ -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/SceneTree.xml b/doc/classes/SceneTree.xml
index 1302c1e6bf..ed43f83f05 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -324,6 +324,15 @@
Emitted when files are dragged from the OS file manager and dropped in the game window. The arguments are a list of file paths and the identifier of the screen where the drag originated.
</description>
</signal>
+ <signal name="global_menu_action">
+ <argument index="0" name="id" type="Nil">
+ </argument>
+ <argument index="1" name="meta" type="Nil">
+ </argument>
+ <description>
+ Emitted whenever global menu item is clicked.
+ </description>
+ </signal>
<signal name="idle_frame">
<description>
Emitted immediately before [method Node._process] is called on every node in the [SceneTree].
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/Skeleton.xml b/doc/classes/Skeleton.xml
index b1e71ee924..8b17928f90 100644
--- a/doc/classes/Skeleton.xml
+++ b/doc/classes/Skeleton.xml
@@ -4,7 +4,7 @@
Skeleton for characters and animated objects.
</brief_description>
<description>
- Skeleton provides a hierarchical interface for managing bones, including pose, rest and animation (see [Animation]). Skeleton will support rag doll dynamics in the future.
+ Skeleton provides a hierarchical interface for managing bones, including pose, rest and animation (see [Animation]). It can also use ragdoll physics.
The overall transform of a bone with respect to the skeleton is determined by the following hierarchical order: rest pose, custom pose and pose.
Note that "global pose" below refers to the overall transform of the bone with respect to skeleton, so it not the actual global/world transform of the bone.
</description>
diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml
index f739fed733..df315d7430 100644
--- a/doc/classes/SpatialMaterial.xml
+++ b/doc/classes/SpatialMaterial.xml
@@ -69,7 +69,7 @@
<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.
@@ -190,9 +190,9 @@
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 name="metallic_texture_channel" type="int" setter="set_metallic_texture_channel" getter="get_metallic_texture_channel" enum="SpatialMaterial.TextureChannel" default="0">
</member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], normal mapping is enabled.
@@ -275,9 +275,9 @@
<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 name="roughness_texture_channel" type="int" setter="set_roughness_texture_channel" getter="get_roughness_texture_channel" enum="SpatialMaterial.TextureChannel" default="0">
</member>
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
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..b77db1ce9a 100644
--- a/doc/classes/Sprite.xml
+++ b/doc/classes/Sprite.xml
@@ -46,10 +46,13 @@
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1.
</member>
+ <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords" default="Vector2( 0, 0 )">
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member vframes] or [member hframes] must be greater than 1.
+ </member>
<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 +67,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..e458d4301e 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -14,6 +14,9 @@
<member name="frame" type="int" setter="set_frame" getter="get_frame" default="0">
Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1.
</member>
+ <member name="frame_coords" type="Vector2" setter="set_frame_coords" getter="get_frame_coords" default="Vector2( 0, 0 )">
+ Coordinates of the frame to display from sprite sheet. This is as an alias for the [member frame] property. [member vframes] or [member hframes] must be greater than 1.
+ </member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1">
The number of columns in the sprite sheet.
</member>
@@ -23,7 +26,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 5529da909d..15d5d7beb4 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -46,6 +46,8 @@
<member name="axis" type="int" setter="set_axis" getter="get_axis" enum="Vector3.Axis" default="2">
The direction in which the front of the texture faces.
</member>
+ <member name="billboard" type="int" setter="set_billboard_mode" getter="get_billboard_mode" enum="SpatialMaterial.BillboardMode" default="0">
+ </member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" default="true">
If [code]true[/code], texture will be centered.
</member>
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/StreamPeerSSL.xml b/doc/classes/StreamPeerSSL.xml
index 9b5f4e7580..c960a794e2 100644
--- a/doc/classes/StreamPeerSSL.xml
+++ b/doc/classes/StreamPeerSSL.xml
@@ -13,7 +13,13 @@
<method name="accept_stream">
<return type="int" enum="Error">
</return>
- <argument index="0" name="base" type="StreamPeer">
+ <argument index="0" name="stream" type="StreamPeer">
+ </argument>
+ <argument index="1" name="private_key" type="CryptoKey">
+ </argument>
+ <argument index="2" name="certificate" type="X509Certificate">
+ </argument>
+ <argument index="3" name="chain" type="X509Certificate" default="null">
</argument>
<description>
</description>
@@ -27,6 +33,8 @@
</argument>
<argument index="2" name="for_hostname" type="String" default="&quot;&quot;">
</argument>
+ <argument index="3" name="valid_certificate" type="X509Certificate" default="null">
+ </argument>
<description>
Connects to a peer using an underlying [StreamPeer] [code]stream[/code]. If [code]validate_certs[/code] is [code]true[/code], [StreamPeerSSL] will validate that the certificate presented by the peer matches the [code]for_hostname[/code].
</description>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index e513a44b1d..f6ec85c87d 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -272,6 +272,32 @@
Performs a case-sensitive comparison to another string. Returns [code]-1[/code] if less than, [code]+1[/code] if greater than, or [code]0[/code] if equal.
</description>
</method>
+ <method name="count">
+ <return type="int">
+ </return>
+ <argument index="0" name="what" type="String">
+ </argument>
+ <argument index="1" name="from" type="int" default="0">
+ </argument>
+ <argument index="2" name="to" type="int" default="0">
+ </argument>
+ <description>
+ Returns the number of occurrences of substring [code]what[/code] between [code]from[/code] and [code]to[/code] positions. If [code]from[/code] and [code]to[/code] equals 0 the whole string will be used. If only [code]to[/code] equals 0 the remained substring will be used.
+ </description>
+ </method>
+ <method name="countn">
+ <return type="int">
+ </return>
+ <argument index="0" name="what" type="String">
+ </argument>
+ <argument index="1" name="from" type="int" default="0">
+ </argument>
+ <argument index="2" name="to" type="int" default="0">
+ </argument>
+ <description>
+ Returns the number of occurrences of substring [code]what[/code] (ignoring case) between [code]from[/code] and [code]to[/code] positions. If [code]from[/code] and [code]to[/code] equals 0 the whole string will be used. If only [code]to[/code] equals 0 the remained substring will be used.
+ </description>
+ </method>
<method name="dedent">
<return type="String">
</return>
diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml
index f68d749d3b..d5efc80846 100644
--- a/doc/classes/StyleBoxTexture.xml
+++ b/doc/classes/StyleBoxTexture.xml
@@ -110,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/TextEdit.xml b/doc/classes/TextEdit.xml
index 22c769330d..fb5f20361b 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -418,6 +418,10 @@
<member name="highlight_current_line" type="bool" setter="set_highlight_current_line" getter="is_highlight_current_line_enabled" default="false">
If [code]true[/code], the line containing the cursor is highlighted.
</member>
+ <member name="minimap_draw" type="bool" setter="draw_minimap" getter="is_drawing_minimap" default="false">
+ </member>
+ <member name="minimap_width" type="int" setter="set_minimap_width" getter="get_minimap_width" default="80">
+ </member>
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
</member>
<member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false">
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="{
-&quot;depth&quot;: 0,
-&quot;flags&quot;: 4,
-&quot;format&quot;: 37,
-&quot;height&quot;: 0,
-&quot;layers&quot;: [ ],
-&quot;width&quot;: 0
-}">
+ <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{&quot;depth&quot;: 0,&quot;flags&quot;: 4,&quot;format&quot;: 37,&quot;height&quot;: 0,&quot;layers&quot;: [ ],&quot;width&quot;: 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 3900b8bf45..4f8ea6438b 100644
--- a/doc/classes/TextureProgress.xml
+++ b/doc/classes/TextureProgress.xml
@@ -57,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 3f9c2e8647..efb7a0d900 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -306,7 +306,7 @@
<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/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="&quot;&quot;">
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 9916d25af5..6ebc389ed7 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -144,7 +144,7 @@
<argument index="0" name="v" type="Variant">
</argument>
<description>
- Transforms the given [Vector3], [Plane], or [AABB] by this transform.
+ Transforms the given [Vector3], [Plane], [AABB], or [PoolVector3Array] by this transform.
</description>
</method>
<method name="xform_inv">
@@ -153,7 +153,7 @@
<argument index="0" name="v" type="Variant">
</argument>
<description>
- Inverse-transforms the given [Vector3], [Plane], or [AABB] by this transform.
+ Inverse-transforms the given [Vector3], [Plane], [AABB], or [PoolVector3Array] by this transform.
</description>
</method>
</methods>
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index f6fce1aaa1..580da080b3 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -146,7 +146,7 @@
<argument index="0" name="v" type="Variant">
</argument>
<description>
- Transforms the given [Vector2] or [Rect2] by this transform.
+ Transforms the given [Vector2], [Rect2], or [PoolVector2Array] by this transform.
</description>
</method>
<method name="xform_inv">
@@ -155,7 +155,7 @@
<argument index="0" name="v" type="Variant">
</argument>
<description>
- Inverse-transforms the given [Vector2] or [Rect2] by this transform.
+ Inverse-transforms the given [Vector2], [Rect2], or [PoolVector2Array] by this transform.
</description>
</method>
</methods>
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 22c74d4ca5..82f948c54d 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -16,6 +16,7 @@
var subchild1 = tree.create_item(child1)
subchild1.set_text(0, "Subchild1")
[/codeblock]
+ To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root].
</description>
<tutorials>
</tutorials>
@@ -182,7 +183,7 @@
<argument index="1" name="expand" type="bool">
</argument>
<description>
- If [code]true[/code], the column will have the "Expand" flag of [Control].
+ If [code]true[/code], the column will have the "Expand" flag of [Control]. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
</description>
</method>
<method name="set_column_min_width">
@@ -193,7 +194,7 @@
<argument index="1" name="min_width" type="int">
</argument>
<description>
- Sets the minimum width of a column.
+ Sets the minimum width of a column. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio].
</description>
</method>
<method name="set_column_title">
@@ -402,8 +403,6 @@
</theme_item>
<theme_item name="guide_color" type="Color" default="Color( 0, 0, 0, 0.1 )">
</theme_item>
- <theme_item name="guide_width" type="int" default="2">
- </theme_item>
<theme_item name="hseparation" type="int" default="4">
</theme_item>
<theme_item name="item_margin" type="int" default="12">
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 3a4acb351d..04deae6bf5 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -136,6 +136,15 @@
Returns the column's icon's maximum width.
</description>
</method>
+ <method name="get_icon_modulate" qualifiers="const">
+ <return type="Color">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ Returns the [Color] modulating the column's icon.
+ </description>
+ </method>
<method name="get_icon_region" qualifiers="const">
<return type="Rect2">
</return>
@@ -347,6 +356,7 @@
<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">
@@ -463,6 +473,17 @@
Sets the given column's icon's maximum width.
</description>
</method>
+ <method name="set_icon_modulate">
+ <return type="void">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="modulate" type="Color">
+ </argument>
+ <description>
+ Modulates the given column's icon with [code]modulate[/code].
+ </description>
+ </method>
<method name="set_icon_region">
<return type="void">
</return>
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index eb07c70cc6..522e131b45 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -5,6 +5,19 @@
</brief_description>
<description>
A Variant takes up only 20 bytes and can store almost any engine datatype inside of it. Variants are rarely used to hold information for long periods of time. Instead, they are used mainly for communication, editing, serialization and moving data around.
+ A Variant:
+ - Can store almost any datatype.
+ - Can perform operations between many variants. GDScript uses Variant as its atomic/native datatype.
+ - Can be hashed, so it can be compared quickly to other variants.
+ - Can be used to convert safely between datatypes.
+ - Can be used to abstract calling methods and their arguments. Godot exports all its functions through variants.
+ - Can be used to defer calls or move data between threads.
+ - Can be serialized as binary and stored to disk, or transferred via network.
+ - Can be serialized to text and use it for printing values and editable settings.
+ - Can work as an exported property, so the editor can edit it universally.
+ - Can be used for dictionaries, arrays, parsers, etc.
+ [b]Containers ([Array] and [Dictionary]):[/b] Both are implemented using variants. A [Dictionary] can match any datatype used as key to any other datatype. An [Array] just holds an array of Variants. Of course, a Variant can also hold a [Dictionary] and an [Array] inside, making it even more flexible.
+ Modifications to a container will modify all references to it. A [Mutex] should be created to lock it if multi-threaded access is desired.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 0c96c50c58..987ed9867b 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -4,7 +4,7 @@
Vector used for 2D math.
</brief_description>
<description>
- 2-element structure that can be used to represent positions in 2d space or any other pair of numeric values.
+ 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
@@ -203,6 +203,24 @@
Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code].
</description>
</method>
+ <method name="posmod">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="mod" type="float">
+ </argument>
+ <description>
+ Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
+ </description>
+ </method>
+ <method name="posmodv">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="modv" type="Vector2">
+ </argument>
+ <description>
+ Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
+ </description>
+ </method>
<method name="project">
<return type="Vector2">
</return>
@@ -237,6 +255,13 @@
Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
+ <method name="sign">
+ <return type="Vector2">
+ </return>
+ <description>
+ Returns the vector with each component set to one or negative one, depending on the signs of the components.
+ </description>
+ </method>
<method name="slerp">
<return type="Vector2">
</return>
@@ -284,6 +309,12 @@
</member>
</members>
<constants>
+ <constant name="AXIS_X" value="0">
+ Enumerated value for the X axis.
+ </constant>
+ <constant name="AXIS_Y" value="1">
+ Enumerated value for the Y axis.
+ </constant>
<constant name="ZERO" value="Vector2( 0, 0 )">
Zero vector.
</constant>
@@ -291,7 +322,7 @@
One vector.
</constant>
<constant name="INF" value="Vector2( inf, inf )">
- Infinite vector.
+ Infinity vector.
</constant>
<constant name="LEFT" value="Vector2( -1, 0 )">
Left unit vector.
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 3e1083ab69..05ce6c43ae 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Vector3" category="Built-In Types" version="3.2">
<brief_description>
- Vector class, which performs basic 3D vector math operations.
+ Vector used for 3D math.
</brief_description>
<description>
- Vector3 is one of the core classes of the engine, and includes several built-in helper functions to perform basic vector math operations.
+ 3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
@@ -202,6 +202,24 @@
Returns the outer product with [code]b[/code].
</description>
</method>
+ <method name="posmod">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="mod" type="float">
+ </argument>
+ <description>
+ Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
+ </description>
+ </method>
+ <method name="posmodv">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="modv" type="Vector3">
+ </argument>
+ <description>
+ Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
+ </description>
+ </method>
<method name="project">
<return type="Vector3">
</return>
@@ -238,6 +256,13 @@
Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
</description>
</method>
+ <method name="sign">
+ <return type="Vector3">
+ </return>
+ <description>
+ Returns the vector with each component set to one or negative one, depending on the signs of the components.
+ </description>
+ </method>
<method name="slerp">
<return type="Vector3">
</return>
@@ -292,10 +317,10 @@
Enumerated value for the X axis. Returned by [method max_axis] and [method min_axis].
</constant>
<constant name="AXIS_Y" value="1">
- Enumerated value for the Y axis.
+ Enumerated value for the Y axis. Returned by [method max_axis] and [method min_axis].
</constant>
<constant name="AXIS_Z" value="2">
- Enumerated value for the Z axis.
+ Enumerated value for the Z axis. Returned by [method max_axis] and [method min_axis].
</constant>
<constant name="ZERO" value="Vector3( 0, 0, 0 )">
Zero vector.
@@ -304,7 +329,7 @@
One vector.
</constant>
<constant name="INF" value="Vector3( inf, inf, inf )">
- Infinite vector.
+ Infinity vector.
</constant>
<constant name="LEFT" value="Vector3( -1, 0, 0 )">
Left unit vector.
diff --git a/doc/classes/VehicleWheel.xml b/doc/classes/VehicleWheel.xml
index 6de6429531..ff6004bcba 100644
--- a/doc/classes/VehicleWheel.xml
+++ b/doc/classes/VehicleWheel.xml
@@ -13,6 +13,7 @@
<return type="float">
</return>
<description>
+ Returns the rotational speed of the wheel in revolutions per minute.
</description>
</method>
<method name="get_skidinfo" qualifiers="const">
@@ -31,12 +32,23 @@
</method>
</methods>
<members>
+ <member name="brake" type="float" setter="set_brake" getter="get_brake" default="0.0">
+ Slows down the wheel by applying a braking force. The wheel is only slowed down if it is in contact with a surface. The force you need to apply to adequately slow down your vehicle depends on the [member RigidBody.mass] of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 30 range for hard braking.
+ </member>
<member name="damping_compression" type="float" setter="set_damping_compression" getter="get_damping_compression" default="0.83">
The damping applied to the spring when the spring is being compressed. This value should be between 0.0 (no damping) and 1.0. A value of 0.0 means the car will keep bouncing as the spring keeps its energy. A good value for this is around 0.3 for a normal car, 0.5 for a race car.
</member>
<member name="damping_relaxation" type="float" setter="set_damping_relaxation" getter="get_damping_relaxation" default="0.88">
The damping applied to the spring when relaxing. This value should be between 0.0 (no damping) and 1.0. This value should always be slightly higher than the [member damping_compression] property. For a [member damping_compression] value of 0.3, try a relaxation value of 0.5.
</member>
+ <member name="engine_force" type="float" setter="set_engine_force" getter="get_engine_force" default="0.0">
+ Accelerates the wheel by applying an engine force. The wheel is only speed up if it is in contact with a surface. The [member RigidBody.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration.
+ [b]Note:[/b] The simulation does not take the effect of gears into account, you will need to add logic for this if you wish to simulate gears.
+ A negative value will result in the wheel reversing.
+ </member>
+ <member name="steering" type="float" setter="set_steering" getter="get_steering" default="0.0">
+ The steering angle for the wheel. Setting this to a non-zero value will result in the vehicle turning when it's moving.
+ </member>
<member name="suspension_max_force" type="float" setter="set_suspension_max_force" getter="get_suspension_max_force" default="6000.0">
The maximum force the spring can resist. This value should be higher than a quarter of the [member RigidBody.mass] of the [VehicleBody] or the spring will not carry the weight of the vehicle. Good results are often obtained by a value that is about 3× to 4× this number.
</member>
@@ -47,10 +59,10 @@
This is the distance the suspension can travel. As Godot units are equivalent to meters, keep this setting relatively low. Try a value between 0.1 and 0.3 depending on the type of car.
</member>
<member name="use_as_steering" type="bool" setter="set_use_as_steering" getter="is_used_as_steering" default="false">
- If [code]true[/code], this wheel will be turned when the car steers.
+ If [code]true[/code], this wheel will be turned when the car steers. This value is used in conjunction with [member VehicleBody.steering] and ignored if you are using the per-wheel [member steering] value instead.
</member>
<member name="use_as_traction" type="bool" setter="set_use_as_traction" getter="is_used_as_traction" default="false">
- If [code]true[/code], this wheel transfers engine force to the ground to propel the vehicle forward.
+ If [code]true[/code], this wheel transfers engine force to the ground to propel the vehicle forward. This value is used in conjunction with [member VehicleBody.engine_force] and ignored if you are using the per-wheel [member engine_force] value instead.
</member>
<member name="wheel_friction_slip" type="float" setter="set_friction_slip" getter="get_friction_slip" default="10.5">
This determines how much grip this wheel has. It is combined with the friction setting of the surface the wheel is in contact with. 0.0 means no grip, 1.0 is normal grip. For a drift car setup, try setting the grip of the rear wheels slightly lower than the front wheels, or use a lower value to simulate tire wear.
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 9b24aa1a86..117c4835eb 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -295,7 +295,7 @@
<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/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index 19495a8859..3e80349b13 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -39,5 +39,20 @@
</signal>
</signals>
<constants>
+ <constant name="PORT_TYPE_SCALAR" value="0" enum="PortType">
+ Floating-point scalar. Translated to [code]float[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_VECTOR" value="1" enum="PortType">
+ 3D vector of floating-point values. Translated to [code]vec3[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_BOOLEAN" value="2" enum="PortType">
+ Boolean type. Translated to [code]bool[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_TRANSFORM" value="3" enum="PortType">
+ Transform type. Translated to [code]mat4[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_ICON_COLOR" value="4" enum="PortType">
+ Color type. Can be used for return icon type in members dialog (see [method VisualShaderNodeCustom._get_return_icon_type]) - do not use it in other cases!
+ </constant>
</constants>
</class>
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/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
new file mode 100644
index 0000000000..9e58abae97
--- /dev/null
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeCustom" inherits="VisualShaderNode" category="Core" version="3.2">
+ <brief_description>
+ Virtual class to define custom [VisualShaderNode]s for use in the Visual Shader Editor.
+ </brief_description>
+ <description>
+ By inheriting this class you can create a custom [VisualShader] script addon which will be automatically added to the Visual Shader Editor. The [VisualShaderNode]'s behavior is defined by overriding the provided virtual methods.
+ In order for the node to be registered as an editor addon, you must use the [code]tool[/code] keyword and provide a [code]class_name[/code] for your custom script. For example:
+ [codeblock]
+ tool
+ extends VisualShaderNodeCustom
+ class_name VisualShaderNodeNoise
+ [/codeblock]
+ </description>
+ <tutorials>
+ <link>http://docs.godotengine.org/en/latest/tutorials/plugins/editor/visual_shader_plugins.html</link>
+ </tutorials>
+ <methods>
+ <method name="_get_category" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the category of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the "Custom" category.
+ </description>
+ </method>
+ <method name="_get_code" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="input_vars" type="Array">
+ </argument>
+ <argument index="1" name="output_vars" type="Array">
+ </argument>
+ <argument index="2" name="mode" type="int">
+ </argument>
+ <argument index="3" name="type" type="int">
+ </argument>
+ <description>
+ Override this method to define the actual shader code of the associated custom node. The shader code should be returned as a string, which can have multiple lines (the [code]"""[/code] multiline string construct can be used for convenience).
+ The [code]input_vars[/code] and [code]output_vars[/code] arrays contain the string names of the various input and output variables, as defined by [code]_get_input_*[/code] and [code]_get_output_*[/code] virtual methods in this class.
+ The output ports can be assigned values in the shader code. For example, [code]return output_vars[0] + " = " + input_vars[0] + ";"[/code].
+ You can customize the generated code based on the shader [code]mode[/code] (see [enum Shader.Mode]) and/or [code]type[/code] (see [enum VisualShader.Type]).
+ Defining this method is [b]required[/b].
+ </description>
+ </method>
+ <method name="_get_description" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the description of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b].
+ </description>
+ </method>
+ <method name="_get_global_code" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ Override this method to add shader code on top of the global shader, to define your own standard library of reusable methods, varyings, constants, uniforms, etc. The shader code should be returned as a string, which can have multiple lines (the [code]"""[/code] multiline string construct can be used for convenience).
+ Be careful with this functionality as it can cause name conflicts with other custom nodes, so be sure to give the defined entities unique names.
+ You can customize the generated code based on the shader [code]mode[/code] (see [enum Shader.Mode]).
+ Defining this method is [b]optional[/b].
+ </description>
+ </method>
+ <method name="_get_input_port_count" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ Override this method to define the amount of input ports of the associated custom node.
+ Defining this method is [b]required[/b]. If not overridden, the node has no input ports.
+ </description>
+ </method>
+ <method name="_get_input_port_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the names of input ports of the associated custom node. The names are used both for the input slots in the editor and as identifiers in the shader code, and are passed in the [code]input_vars[/code] array in [method _get_code].
+ Defining this method is [b]optional[/b], but recommended. If not overridden, input ports are named as [code]"in" + str(port)[/code].
+ </description>
+ </method>
+ <method name="_get_input_port_type" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the returned type of each input port of the associated custom node (see [enum VisualShaderNode.PortType] for possible types).
+ Defining this method is [b]optional[/b], but recommended. If not overridden, input ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
+ </description>
+ </method>
+ <method name="_get_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the name of the associated custom node in the Visual Shader Editor's members dialog and graph.
+ Defining this method is [b]optional[/b], but recommended. If not overridden, the node will be named as "Unnamed".
+ </description>
+ </method>
+ <method name="_get_output_port_count" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ Override this method to define the amount of output ports of the associated custom node.
+ Defining this method is [b]required[/b]. If not overridden, the node has no output ports.
+ </description>
+ </method>
+ <method name="_get_output_port_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the names of output ports of the associated custom node. The names are used both for the output slots in the editor and as identifiers in the shader code, and are passed in the [code]output_vars[/code] array in [method _get_code].
+ Defining this method is [b]optional[/b], but recommended. If not overridden, output ports are named as [code]"out" + str(port)[/code].
+ </description>
+ </method>
+ <method name="_get_output_port_type" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <argument index="0" name="port" type="int">
+ </argument>
+ <description>
+ Override this method to define the returned type of each output port of the associated custom node (see [enum VisualShaderNode.PortType] for possible types).
+ Defining this method is [b]optional[/b], but recommended. If not overridden, output ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
+ </description>
+ </method>
+ <method name="_get_return_icon_type" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ Override this method to define the return icon of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, no return icon is shown.
+ </description>
+ </method>
+ <method name="_get_subcategory" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to define the subcategory of the associated custom node in the Visual Shader Editor's members dialog.
+ Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the root of the main category (see [method _get_category]).
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeGlobalExpression.xml b/doc/classes/VisualShaderNodeGlobalExpression.xml
new file mode 100644
index 0000000000..3c5a26bf47
--- /dev/null
+++ b/doc/classes/VisualShaderNodeGlobalExpression.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeGlobalExpression" inherits="VisualShaderNodeExpression" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeGroupBase.xml b/doc/classes/VisualShaderNodeGroupBase.xml
index c2e9b9503b..d32a63d605 100644
--- a/doc/classes/VisualShaderNodeGroupBase.xml
+++ b/doc/classes/VisualShaderNodeGroupBase.xml
@@ -208,6 +208,10 @@
</description>
</method>
</methods>
+ <members>
+ <member name="editable" type="bool" setter="set_editable" getter="is_editable" default="false">
+ </member>
+ </members>
<constants>
</constants>
</class>
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 b3b89eb29b..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>
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/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml
new file mode 100644
index 0000000000..d83c2e7d44
--- /dev/null
+++ b/doc/classes/VisualShaderNodeVectorScalarMix.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" 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/doc/classes/X509Certificate.xml b/doc/classes/X509Certificate.xml
new file mode 100644
index 0000000000..013f768843
--- /dev/null
+++ b/doc/classes/X509Certificate.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="X509Certificate" inherits="Resource" category="Core" version="3.2">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="load">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="save">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 763c29ab4e..b42ae3ce01 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -347,6 +347,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f = open(os.path.join(output_dir, "class_" + class_name.lower() + '.rst'), 'w', encoding='utf-8')
# Warn contributors not to edit this file directly
+ f.write(":github_url: hide\n\n")
f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n")
f.write(".. DO NOT EDIT THIS FILE, but the " + class_name + ".xml source instead.\n")
f.write(".. The source is found in doc/classes or modules/<name>/doc_classes.\n\n")
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 0611d7d4e0..42899c0f76 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -171,14 +171,14 @@ void AudioDriverALSA::thread_func(void *p_udata) {
ad->start_counting_ticks();
if (!ad->active) {
- for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
+ for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
ad->samples_out.write[i] = 0;
}
} else {
ad->audio_server_process(ad->period_size, ad->samples_in.ptrw());
- for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
+ for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
ad->samples_out.write[i] = ad->samples_in[i] >> 16;
}
}
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 97d16d3a6a..3b06c47244 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -233,11 +233,11 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
if (result == noErr) {
for (int i = 0; i < inNumberFrames * ad->capture_channels; i++) {
int32_t sample = ad->input_buf[i] << 16;
- ad->input_buffer_write(sample);
+ ad->capture_buffer_write(sample);
if (ad->capture_channels == 1) {
- // In case input device is single channel convert it to Stereo
- ad->input_buffer_write(sample);
+ // In case capture device is single channel convert it to Stereo
+ ad->capture_buffer_write(sample);
}
}
} else {
@@ -487,7 +487,7 @@ void AudioDriverCoreAudio::capture_finish() {
Error AudioDriverCoreAudio::capture_start() {
- input_buffer_init(buffer_frames);
+ capture_buffer_init(buffer_frames);
OSStatus result = AudioOutputUnitStart(input_unit);
if (result != noErr) {
@@ -642,9 +642,9 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
ERR_FAIL_COND(result != noErr);
if (capture) {
- // Reset audio input to keep synchronisation.
- input_position = 0;
- input_size = 0;
+ // Reset audio capture to keep synchronisation.
+ capture_position = 0;
+ capture_size = 0;
}
}
}
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index b82186162d..6be48a4c58 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;
@@ -1216,14 +1265,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
- ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen");
+ ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen.");
return;
}
- if (storage->frame.current_rt->copy_screen_effect.color == 0) {
- ERR_EXPLAIN("Can't use screen texture copying in a render target configured without copy buffers");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(storage->frame.current_rt->copy_screen_effect.color == 0, "Can't use screen texture copying in a render target configured without copy buffers.");
glDisable(GL_BLEND);
@@ -1601,6 +1647,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
//always re-set uniforms, since light parameters changed
_set_uniforms();
+ state.canvas_shader.use_material((void *)material_ptr);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(light->texture);
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index af41e91e0c..ab636dca71 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -84,7 +84,7 @@ public:
Transform2D skeleton_transform;
Transform2D skeleton_transform_inverse;
- Vector2i skeleton_texture_size;
+ Size2i skeleton_texture_size;
RID current_tex;
RID current_normal;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index ea29af7d9e..a8fa30c709 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -880,7 +880,10 @@ RID RasterizerSceneGLES2::light_instance_create(RID p_light) {
light_instance->light_index = 0xFFFF;
- ERR_FAIL_COND_V(!light_instance->light_ptr, RID());
+ if (!light_instance->light_ptr) {
+ memdelete(light_instance);
+ ERR_FAIL_V_MSG(RID(), "Condition ' !light_instance->light_ptr ' is true.");
+ }
light_instance->self = light_instance_owner.make_rid(light_instance);
@@ -1133,8 +1136,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) {
@@ -1429,11 +1432,11 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
}
}
- bool clear_skeleton_buffer = !storage->config.float_texture_supported;
+ bool clear_skeleton_buffer = storage->config.use_skeleton_software;
if (p_skeleton) {
- if (storage->config.float_texture_supported) {
+ if (!storage->config.use_skeleton_software) {
//use float texture workflow
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, p_skeleton->tex_id);
@@ -1906,14 +1909,14 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
}
}
-void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform) {
+void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass) {
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
//common parameters
float energy = light_ptr->param[VS::LIGHT_PARAM_ENERGY];
float specular = light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
- float sign = light_ptr->negative ? -1 : 1;
+ float sign = (light_ptr->negative && !accum_pass) ? -1 : 1; //inverse color for base pass lights only
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPECULAR, specular);
Color color = light_ptr->color * sign * energy * Math_PI;
@@ -1963,9 +1966,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
width /= 2;
height /= 2;
- if (k == 0) {
-
- } else if (k == 1) {
+ if (k == 1) {
x += width;
} else if (k == 2) {
y += height;
@@ -1978,9 +1979,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
height /= 2;
- if (k == 0) {
-
- } else {
+ if (k != 0) {
y += height;
}
}
@@ -2287,19 +2286,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
prev_unshaded = unshaded;
}
- bool depth_prepass = false;
-
- if (!p_alpha_pass && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
- depth_prepass = true;
- }
-
- if (depth_prepass != prev_depth_prepass) {
-
- state.scene_shader.set_conditional(SceneShaderGLES2::USE_DEPTH_PREPASS, depth_prepass);
- prev_depth_prepass = depth_prepass;
- rebind = true;
- }
-
bool base_pass = !accum_pass && !unshaded; //conditions for a base pass
if (base_pass != prev_base_pass) {
@@ -2323,6 +2309,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (accum_pass) { //accum pass force pass
blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD;
+ if (rebind_light && light && light->light_ptr->negative) {
+ glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB;
+ }
}
if (prev_blend_mode != blend_mode) {
@@ -2434,6 +2425,19 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
}
+ bool depth_prepass = false;
+
+ if (!p_alpha_pass && material->shader->spatial.depth_draw_mode == RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
+ depth_prepass = true;
+ }
+
+ if (depth_prepass != prev_depth_prepass) {
+
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_DEPTH_PREPASS, depth_prepass);
+ prev_depth_prepass = depth_prepass;
+ rebind = true;
+ }
+
bool instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH;
if (instancing != prev_instancing) {
@@ -2448,7 +2452,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (skeleton) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON, true);
- state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, !storage->config.float_texture_supported);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, storage->config.use_skeleton_software);
} else {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, false);
@@ -2553,7 +2557,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
if (rebind_light && light) {
- _setup_light(light, shadow_atlas, p_view_transform);
+ _setup_light(light, shadow_atlas, p_view_transform, accum_pass);
}
if (rebind_reflection && (refprobe_1 || refprobe_2)) {
@@ -2566,12 +2570,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
- if (skeleton) {
- state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_IN_WORLD_COORDS, skeleton->use_world_transform);
- state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM, skeleton->world_transform);
- state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TRANSFORM_INVERSE, skeleton->world_transform_inverse);
- }
-
if (use_lightmap_capture) { //this is per instance, must be set always if present
glUniform4fv(state.scene_shader.get_uniform_location(SceneShaderGLES2::LIGHTMAP_CAPTURES), 12, (const GLfloat *)e->instance->lightmap_capture_data.ptr());
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHTMAP_CAPTURE_SKY, false);
@@ -3171,9 +3169,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
width /= 2;
height /= 2;
- if (p_pass == 0) {
-
- } else if (p_pass == 1) {
+ if (p_pass == 1) {
x += width;
} else if (p_pass == 2) {
y += height;
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index c95385eb24..69a2295fc1 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -398,8 +398,8 @@ public:
fog_transmit_enabled(true),
fog_transmit_curve(1),
fog_height_enabled(false),
- fog_height_min(0),
- fog_height_max(100),
+ fog_height_min(10),
+ fog_height_max(0),
fog_height_curve(1) {
}
};
@@ -694,7 +694,7 @@ public:
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
_FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas);
- _FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform);
+ _FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass);
_FORCE_INLINE_ void _setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index c591db4f3d..9f511cd787 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -1570,7 +1570,7 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
- pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]);
+ pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
@@ -2171,8 +2171,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
//must have index and bones, both.
{
uint32_t bones_weight = VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS;
- ERR_EXPLAIN("Array must have both bones and weights in format or none.");
- ERR_FAIL_COND((p_format & bones_weight) && (p_format & bones_weight) != bones_weight);
+ ERR_FAIL_COND_MSG((p_format & bones_weight) && (p_format & bones_weight) != bones_weight, "Array must have both bones and weights in format or none.");
}
//bool has_morph = p_blend_shapes.size();
@@ -2433,7 +2432,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
// from surface->data.
// if USE_SKELETON_SOFTWARE is active
- if (!config.float_texture_supported) {
+ if (config.use_skeleton_software) {
// if this geometry is used specifically for skinning
if (p_format & (VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS))
surface->data = array;
@@ -3497,6 +3496,8 @@ RID RasterizerStorageGLES2::skeleton_create() {
Skeleton *skeleton = memnew(Skeleton);
+ glGenTextures(1, &skeleton->tex_id);
+
return skeleton_owner.make_rid(skeleton);
}
@@ -3513,8 +3514,7 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool
skeleton->size = p_bones;
skeleton->use_2d = p_2d_skeleton;
- if (config.float_texture_supported) {
- glGenTextures(1, &skeleton->tex_id);
+ if (!config.use_skeleton_software) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
@@ -3663,23 +3663,6 @@ void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform;
}
-void RasterizerStorageGLES2::skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {
-
- Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
-
- ERR_FAIL_COND(skeleton->use_2d);
-
- skeleton->world_transform = p_world_transform;
- skeleton->use_world_transform = p_enable;
- if (p_enable) {
- skeleton->world_transform_inverse = skeleton->world_transform.affine_inverse();
- }
-
- if (!skeleton->update_list.in_list()) {
- skeleton_update_list.add(&skeleton->update_list);
- }
-}
-
void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size) {
glBindBuffer(GL_ARRAY_BUFFER, resources.skeleton_transform_buffer);
@@ -3699,7 +3682,7 @@ void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector<
void RasterizerStorageGLES2::update_dirty_skeletons() {
- if (!config.float_texture_supported)
+ if (config.use_skeleton_software)
return;
glActiveTexture(GL_TEXTURE0);
@@ -3976,20 +3959,19 @@ AABB RasterizerStorageGLES2::light_get_aabb(RID p_light) const {
float len = light->param[VS::LIGHT_PARAM_RANGE];
float size = Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
- } break;
+ };
case VS::LIGHT_OMNI: {
float r = light->param[VS::LIGHT_PARAM_RANGE];
return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
- } break;
+ };
case VS::LIGHT_DIRECTIONAL: {
return AABB();
- } break;
+ };
}
ERR_FAIL_V(AABB());
- return AABB();
}
/* PROBE API */
@@ -5692,21 +5674,49 @@ void RasterizerStorageGLES2::initialize() {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
+ glDeleteFramebuffers(1, &fbo);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &depth);
+
if (status == GL_FRAMEBUFFER_COMPLETE) {
config.depth_internalformat = GL_DEPTH_COMPONENT;
config.depth_type = GL_UNSIGNED_INT;
} else {
+ // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT
+ // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT
+
config.depth_internalformat = GL_DEPTH_COMPONENT16;
config.depth_type = GL_UNSIGNED_SHORT;
- }
- glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
- glDeleteFramebuffers(1, &fbo);
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &depth);
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ glGenTextures(1, &depth);
+ glBindTexture(GL_TEXTURE_2D, depth);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 32, 32, 0, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ //if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth
+ config.support_depth_texture = false;
+ config.use_rgba_3d_shadows = true;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
+ glDeleteFramebuffers(1, &fbo);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &depth);
+ }
} else {
- // Will use renderbuffer for depth
+ // Will use renderbuffer for depth, on mobile check for 24 bit depth support
if (config.extensions.has("GL_OES_depth24")) {
config.depth_internalformat = _DEPTH_COMPONENT24_OES;
config.depth_type = GL_UNSIGNED_INT;
@@ -5724,9 +5734,14 @@ void RasterizerStorageGLES2::initialize() {
frame.current_rt = NULL;
frame.clear_request = false;
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &config.max_vertex_texture_image_units);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &config.max_texture_size);
+ // the use skeleton software path should be used if either float texture is not supported,
+ // OR max_vertex_texture_image_units is zero
+ config.use_skeleton_software = (config.float_texture_supported == false) || (config.max_vertex_texture_image_units == 0);
+
shaders.copy.init();
shaders.cubemap_filter.init();
bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index d139697b86..ba9274b576 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -60,7 +60,9 @@ public:
bool shrink_textures_x2;
bool use_fast_texture_filter;
+ bool use_skeleton_software;
+ int max_vertex_texture_image_units;
int max_texture_image_units;
int max_texture_size;
@@ -868,16 +870,12 @@ public:
Set<RasterizerScene::InstanceBase *> instances;
Transform2D base_transform_2d;
- Transform world_transform;
- Transform world_transform_inverse;
- bool use_world_transform;
Skeleton() :
use_2d(false),
size(0),
tex_id(0),
- update_list(this),
- use_world_transform(false) {
+ update_list(this) {
}
};
@@ -895,7 +893,6 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
- virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
void _update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index ee34a478b1..1db8a870a2 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -353,6 +353,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
varying_code += _typestr(E->get().type);
varying_code += " ";
varying_code += _mkid(E->key());
+ if (E->get().array_size > 0) {
+ varying_code += "[";
+ varying_code += itos(E->get().array_size);
+ varying_code += "]";
+ }
varying_code += ";\n";
String final_code = varying_code.as_string();
@@ -449,7 +454,9 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node;
StringBuffer<> declaration;
-
+ if (var_dec_node->is_const) {
+ declaration += "const ";
+ }
declaration += _prestr(var_dec_node->precision);
declaration += _typestr(var_dec_node->datatype);
@@ -510,7 +517,99 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
}
} break;
+ case SL::Node::TYPE_ARRAY_DECLARATION: {
+
+ SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
+
+ StringBuffer<> declaration;
+ if (arr_dec_node->is_const) {
+ declaration += "const ";
+ }
+ declaration += _prestr(arr_dec_node->precision);
+ declaration += _typestr(arr_dec_node->datatype);
+
+ for (int i = 0; i < arr_dec_node->declarations.size(); i++) {
+
+ if (i > 0) {
+ declaration += ",";
+ }
+
+ declaration += " ";
+
+ declaration += _mkid(arr_dec_node->declarations[i].name);
+ declaration += "[";
+ declaration += itos(arr_dec_node->declarations[i].size);
+ declaration += "]";
+ int sz = arr_dec_node->declarations[i].initializer.size();
+ if (sz > 0) {
+ declaration += "=";
+ declaration += _typestr(arr_dec_node->datatype);
+ declaration += "[";
+ declaration += itos(sz);
+ declaration += "]";
+ declaration += "(";
+ for (int j = 0; j < sz; j++) {
+ declaration += _dump_node_code(arr_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 *arr_node = (SL::ArrayNode *)p_node;
+
+ if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) {
+ *p_actions.write_flag_pointers[arr_node->name] = true;
+ }
+
+ if (p_default_actions.usage_defines.has(arr_node->name) && !used_name_defines.has(arr_node->name)) {
+ String define = p_default_actions.usage_defines[arr_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(arr_node->name);
+ }
+
+ if (p_actions.usage_flag_pointers.has(arr_node->name) && !used_flag_pointers.has(arr_node->name)) {
+ *p_actions.usage_flag_pointers[arr_node->name] = true;
+ used_flag_pointers.insert(arr_node->name);
+ }
+ if (p_default_actions.renames.has(arr_node->name)) {
+ code += p_default_actions.renames[arr_node->name];
+ } else {
+ code += _mkid(arr_node->name);
+ }
+
+ if (arr_node->call_expression != NULL) {
+ code += ".";
+ code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ }
+
+ if (arr_node->index_expression != NULL) {
+ code += "[";
+ code += _dump_node_code(arr_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += "]";
+ }
+
+ if (arr_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;
@@ -643,6 +742,17 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += ")";
+ 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);
+ }
+
} break;
case SL::OP_INDEX: {
@@ -653,11 +763,13 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_SELECT_IF: {
+ code += "(";
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " ? ";
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " : ";
code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ")";
} break;
case SL::OP_MOD: {
@@ -697,6 +809,23 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "else\n";
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
+ } else if (cf_node->flow_op == SL::FLOW_OP_SWITCH) {
+ code += _mktab(p_level) + "switch (" + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
+ code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cf_node->flow_op == SL::FLOW_OP_CASE) {
+ code += _mktab(p_level) + "case " + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n";
+ code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cf_node->flow_op == SL::FLOW_OP_DEFAULT) {
+ code += _mktab(p_level) + "default:\n";
+ code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cf_node->flow_op == SL::FLOW_OP_DO) {
+ code += _mktab(p_level);
+ code += "do";
+ code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _mktab(p_level);
+ code += "while (";
+ code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ");";
} else if (cf_node->flow_op == SL::FLOW_OP_WHILE) {
code += _mktab(p_level);
code += "while (";
@@ -795,7 +924,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix";
+ actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix_instance";
actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time";
actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";
@@ -819,6 +948,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
@@ -828,6 +958,25 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
+
+ // Ported from GLES3
+
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["sinh"] = "#define SINH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["cosh"] = "#define COSH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["tanh"] = "#define TANH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["asinh"] = "#define ASINH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["acosh"] = "#define ACOSH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["atanh"] = "#define ATANH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["round"] = "#define ROUND_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["inverse"] = "#define INVERSE_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["isinf"] = "#define IS_INF_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["isnan"] = "#define IS_NAN_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["trunc"] = "#define TRUNC_USED\n";
/** SPATIAL SHADER **/
@@ -921,6 +1070,24 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ // Ported from GLES3
+
+ actions[VS::SHADER_SPATIAL].usage_defines["sinh"] = "#define SINH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["cosh"] = "#define COSH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["tanh"] = "#define TANH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["asinh"] = "#define ASINH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["acosh"] = "#define ACOSH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["atanh"] = "#define ATANH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["round"] = "#define ROUND_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["inverse"] = "#define INVERSE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["isinf"] = "#define IS_INF_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["isnan"] = "#define IS_NAN_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["trunc"] = "#define TRUNC_USED\n";
+
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 0818942b0a..08548ded17 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -258,6 +258,8 @@ precision mediump int;
#endif
#endif
+#include "stdlib.glsl"
+
uniform sampler2D color_texture; // texunit:-1
/* clang-format on */
uniform highp vec2 color_texpixel_size;
@@ -329,6 +331,7 @@ void light_compute(
inout vec4 light_color,
vec2 light_uv,
inout vec4 shadow_color,
+ inout vec2 shadow_vec,
vec3 normal,
vec2 uv,
#if defined(SCREEN_UV_USED)
@@ -405,6 +408,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTING
vec2 light_vec = transformed_light_uv;
+ vec2 shadow_vec = transformed_light_uv;
if (normal_used) {
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
@@ -432,6 +436,7 @@ FRAGMENT_SHADER_CODE
real_light_color,
light_uv,
real_light_shadow_color,
+ shadow_vec,
normal,
uv,
#if defined(SCREEN_UV_USED)
@@ -450,11 +455,18 @@ FRAGMENT_SHADER_CODE
color *= light;
#ifdef USE_SHADOWS
- // Reset light_vec to compute shadows, the shadow map is created from the light origin, so it only
- // makes sense to compute shadows from there.
- light_vec = light_uv_interp.zw;
- float angle_to_light = -atan(light_vec.x, light_vec.y);
+#ifdef SHADOW_VEC_USED
+ mat3 inverse_light_matrix = mat3(light_matrix);
+ inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
+ inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
+ inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
+ shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy;
+#else
+ shadow_vec = light_uv_interp.zw;
+#endif
+
+ float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/
@@ -465,18 +477,18 @@ FRAGMENT_SHADER_CODE
vec2 point;
float sh;
if (abs_angle < 45.0 * PI / 180.0) {
- point = light_vec;
+ point = shadow_vec;
sh = 0.0 + (1.0 / 8.0);
} else if (abs_angle > 135.0 * PI / 180.0) {
- point = -light_vec;
+ point = -shadow_vec;
sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light > 0.0) {
- point = vec2(light_vec.y, -light_vec.x);
+ point = vec2(shadow_vec.y, -shadow_vec.x);
sh = 0.25 + (1.0 / 8.0);
} else {
- point = vec2(-light_vec.y, light_vec.x);
+ point = vec2(-shadow_vec.y, shadow_vec.x);
sh = 0.75 + (1.0 / 8.0);
}
@@ -489,8 +501,7 @@ FRAGMENT_SHADER_CODE
highp float shadow_attenuation = 0.0;
#ifdef USE_RGBA_SHADOWS
-
-#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
+#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
#else
diff --git a/drivers/gles2/shaders/canvas_shadow.glsl b/drivers/gles2/shaders/canvas_shadow.glsl
index 01b2c59325..dcb43d523f 100644
--- a/drivers/gles2/shaders/canvas_shadow.glsl
+++ b/drivers/gles2/shaders/canvas_shadow.glsl
@@ -47,8 +47,8 @@ void main() {
#ifdef USE_RGBA_SHADOWS
- highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
- comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ highp vec4 comp = fract(depth * vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0));
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
gl_FragColor = comp;
#else
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index 195db7c45f..aa967115da 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -144,11 +144,11 @@ void main() {
#elif defined(USE_ASYM_PANO)
// When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
- // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // Asymmetrical projection means the center of projection is no longer in the center of the screen but shifted.
// The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
vec3 cube_normal;
- cube_normal.z = -1000000.0;
+ cube_normal.z = -1.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
cube_normal = mat3(sky_transform) * mat3(pano_transform) * cube_normal;
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index ca222362e7..51447dc00f 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -10,7 +10,9 @@ precision highp float;
precision highp int;
#endif
+/* clang-format on */
#include "stdlib.glsl"
+/* clang-format off */
#define SHADER_IS_SRGB true
@@ -59,9 +61,6 @@ uniform ivec2 skeleton_texture_size;
#endif
-uniform highp mat4 skeleton_transform;
-uniform highp mat4 skeleton_transform_inverse;
-uniform bool skeleton_in_world_coords;
#endif
@@ -408,12 +407,9 @@ void main() {
#endif
- if (skeleton_in_world_coords) {
- bone_transform = skeleton_transform * (bone_transform * skeleton_transform_inverse);
- world_matrix = bone_transform * world_matrix;
- } else {
- world_matrix = world_matrix * bone_transform;
- }
+
+ world_matrix = world_matrix * bone_transform;
+
#endif
@@ -1365,7 +1361,7 @@ LIGHT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_val) dot(m_val, vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
+#define SHADOW_DEPTH(m_val) dot(m_val, vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
#else
@@ -1549,7 +1545,7 @@ FRAGMENT_SHADER_CODE
#endif // ALPHA_SCISSOR_USED
#ifdef USE_DEPTH_PREPASS
- if (alpha < 0.99) {
+ if (alpha < 0.1) {
discard;
}
#endif // USE_DEPTH_PREPASS
@@ -2112,7 +2108,7 @@ FRAGMENT_SHADER_CODE
#endif // ALPHA_SCISSOR_USED
#ifdef USE_DEPTH_PREPASS
- if (alpha < 0.99) {
+ if (alpha < 0.1) {
discard;
}
#endif // USE_DEPTH_PREPASS
@@ -2207,8 +2203,8 @@ FRAGMENT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
- highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
- comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ highp vec4 comp = fract(depth * vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0));
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
gl_FragColor = comp;
#endif
diff --git a/drivers/gles2/shaders/stdlib.glsl b/drivers/gles2/shaders/stdlib.glsl
index 3674d70c9f..9c74418743 100644
--- a/drivers/gles2/shaders/stdlib.glsl
+++ b/drivers/gles2/shaders/stdlib.glsl
@@ -36,12 +36,385 @@ highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord) {
return texture2DLod(tex, vec2(x_coord, y_coord), 0.0);
}
+#if defined(SINH_USED)
+
+highp float sinh(highp float x) {
+ return 0.5 * (exp(x) - exp(-x));
+}
+
+highp vec2 sinh(highp vec2 x) {
+ return 0.5 * vec2(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y));
+}
+
+highp vec3 sinh(highp vec3 x) {
+ return 0.5 * vec3(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z));
+}
+
+highp vec4 sinh(highp vec4 x) {
+ return 0.5 * vec4(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z), exp(x.w) - exp(-x.w));
+}
+
+#endif
+
+#if defined(COSH_USED)
+
+highp float cosh(highp float x) {
+ return 0.5 * (exp(x) + exp(-x));
+}
+
+highp vec2 cosh(highp vec2 x) {
+ return 0.5 * vec2(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y));
+}
+
+highp vec3 cosh(highp vec3 x) {
+ return 0.5 * vec3(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z));
+}
+
+highp vec4 cosh(highp vec4 x) {
+ return 0.5 * vec4(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z), exp(x.w) + exp(-x.w));
+}
+
+#endif
+
+#if defined(TANH_USED)
+
+highp float tanh(highp float x) {
+ highp float exp2x = exp(2.0 * x);
+ return (exp2x - 1.0) / (exp2x + 1.0);
+}
+
+highp vec2 tanh(highp vec2 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ return vec2((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0));
+}
+
+highp vec3 tanh(highp vec3 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ highp float exp2z = exp(2.0 * x.z);
+ return vec3((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0));
+}
+
+highp vec4 tanh(highp vec4 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ highp float exp2z = exp(2.0 * x.z);
+ highp float exp2w = exp(2.0 * x.w);
+ return vec4((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0), (exp2w - 1.0) / (exp2w + 1.0));
+}
+
+#endif
+
+#if defined(ASINH_USED)
+
+highp float asinh(highp float x) {
+ return sign(x) * log(abs(x) + sqrt(1.0 + x * x));
+}
+
+highp vec2 asinh(highp vec2 x) {
+ return vec2(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)));
+}
+
+highp vec3 asinh(highp vec3 x) {
+ return vec3(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)));
+}
+
+highp vec4 asinh(highp vec4 x) {
+ return vec4(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)), sign(x.w) * log(abs(x.w) + sqrt(1.0 + x.w * x.w)));
+}
+
+#endif
+
+#if defined(ACOSH_USED)
+
+highp float acosh(highp float x) {
+ return log(x + sqrt(x * x - 1.0));
+}
+
+highp vec2 acosh(highp vec2 x) {
+ return vec2(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)));
+}
+
+highp vec3 acosh(highp vec3 x) {
+ return vec3(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)));
+}
+
+highp vec4 acosh(highp vec4 x) {
+ return vec4(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)), log(x.w + sqrt(x.w * x.w - 1.0)));
+}
+
+#endif
+
+#if defined(ATANH_USED)
+
+highp float atanh(highp float x) {
+ return 0.5 * log((1.0 + x) / (1.0 - x));
+}
+
+highp vec2 atanh(highp vec2 x) {
+ return 0.5 * vec2(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)));
+}
+
+highp vec3 atanh(highp vec3 x) {
+ return 0.5 * vec3(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)));
+}
+
+highp vec4 atanh(highp vec4 x) {
+ return 0.5 * vec4(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)), log((1.0 + x.w) / (1.0 - x.w)));
+}
+
+#endif
+
+#if defined(ROUND_USED)
+
+highp float round(highp float x) {
+ return floor(x + 0.5);
+}
+
+highp vec2 round(highp vec2 x) {
+ return floor(x + vec2(0.5));
+}
+
+highp vec3 round(highp vec3 x) {
+ return floor(x + vec3(0.5));
+}
+
+highp vec4 round(highp vec4 x) {
+ return floor(x + vec4(0.5));
+}
+
+#endif
+
+#if defined(ROUND_EVEN_USED)
+
+highp float roundEven(highp float x) {
+ highp float t = x + 0.5;
+ highp float f = floor(t);
+ highp float r;
+ if (t == f) {
+ if (x > 0)
+ r = f - mod(f, 2);
+ else
+ r = f + mod(f, 2);
+ } else
+ r = f;
+ return r;
+}
+
+highp vec2 roundEven(highp vec2 x) {
+ return vec2(roundEven(x.x), roundEven(x.y));
+}
+
+highp vec3 roundEven(highp vec3 x) {
+ return vec3(roundEven(x.x), roundEven(x.y), roundEven(x.z));
+}
+
+highp vec4 roundEven(highp vec4 x) {
+ return vec4(roundEven(x.x), roundEven(x.y), roundEven(x.z), roundEven(x.w));
+}
+
+#endif
+
+#if defined(IS_INF_USED)
+
+bool isinf(highp float x) {
+ return (2 * x == x) && (x != 0);
+}
+
+bvec2 isinf(highp vec2 x) {
+ return bvec2((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0));
+}
+
+bvec3 isinf(highp vec3 x) {
+ return bvec3((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0));
+}
+
+bvec4 isinf(highp vec4 x) {
+ return bvec4((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0), (2 * x.w == x.w) && (x.w != 0));
+}
+
+#endif
+
+#if defined(IS_NAN_USED)
+
+bool isnan(highp float x) {
+ return x != x;
+}
+
+bvec2 isnan(highp vec2 x) {
+ return bvec2(x.x != x.x, x.y != x.y);
+}
+
+bvec3 isnan(highp vec3 x) {
+ return bvec3(x.x != x.x, x.y != x.y, x.z != x.z);
+}
+
+bvec4 isnan(highp vec4 x) {
+ return bvec4(x.x != x.x, x.y != x.y, x.z != x.z, x.w != x.w);
+}
+
+#endif
+
+#if defined(TRUNC_USED)
+
+highp float trunc(highp float x) {
+ return x < 0 ? -floor(-x) : floor(x);
+}
+
+highp vec2 trunc(highp vec2 x) {
+ return vec2(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y));
+}
+
+highp vec3 trunc(highp vec3 x) {
+ return vec3(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z));
+}
+
+highp vec4 trunc(highp vec4 x) {
+ return vec4(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z), x.w < 0 ? -floor(-x.w) : floor(x.w));
+}
+
+#endif
+
+#if defined(DETERMINANT_USED)
+
+highp float determinant(highp mat2 m) {
+ return m[0].x * m[1].y - m[1].x * m[0].y;
+}
+
+highp float determinant(highp mat3 m) {
+ return m[0].x * (m[1].y * m[2].z - m[2].y * m[1].z) - m[1].x * (m[0].y * m[2].z - m[2].y * m[0].z) + m[2].x * (m[0].y * m[1].z - m[1].y * m[0].z);
+}
+
+highp float determinant(highp mat4 m) {
+ highp float s00 = m[2].z * m[3].w - m[3].z * m[2].w;
+ highp float s01 = m[2].y * m[3].w - m[3].y * m[2].w;
+ highp float s02 = m[2].y * m[3].z - m[3].y * m[2].z;
+ highp float s03 = m[2].x * m[3].w - m[3].x * m[2].w;
+ highp float s04 = m[2].x * m[3].z - m[3].x * m[2].z;
+ highp float s05 = m[2].x * m[3].y - m[3].x * m[2].y;
+ highp vec4 c = vec4((m[1].y * s00 - m[1].z * s01 + m[1].w * s02), -(m[1].x * s00 - m[1].z * s03 + m[1].w * s04), (m[1].x * s01 - m[1].y * s03 + m[1].w * s05), -(m[1].x * s02 - m[1].y * s04 + m[1].z * s05));
+ return m[0].x * c.x + m[0].y * c.y + m[0].z * c.z + m[0].w * c.w;
+}
+
+#endif
+
+#if defined(INVERSE_USED)
+
+highp mat2 inverse(highp mat2 m) {
+ highp float d = 1.0 / (m[0].x * m[1].y - m[1].x * m[0].y);
+ return mat2(
+ vec2(m[1].y * d, -m[0].y * d),
+ vec2(-m[1].x * d, m[0].x * d));
+}
+
+highp mat3 inverse(highp mat3 m) {
+ highp float d = 1.0 / (m[0].x * (m[1].y * m[2].z - m[2].y * m[1].z) - m[1].x * (m[0].y * m[2].z - m[2].y * m[0].z) + m[2].x * (m[0].y * m[1].z - m[1].y * m[0].z));
+ return mat3(
+ vec3((m[1].y * m[2].z - m[2].y * m[1].z), -(m[1].x * m[2].z - m[2].x * m[1].z), (m[1].x * m[2].y - m[2].x * m[1].y)) * d,
+ vec3(-(m[0].y * m[2].z - m[2].y * m[0].z), (m[0].x * m[2].z - m[2].x * m[0].z), -(m[0].x * m[2].y - m[2].x * m[0].y)) * d,
+ vec3((m[0].y * m[1].z - m[1].y * m[0].z), -(m[0].x * m[1].z - m[1].x * m[0].z), (m[0].x * m[1].y - m[1].x * m[0].y)) * d);
+}
+
+highp mat4 inverse(highp mat4 m) {
+ highp float c00 = m[2].z * m[3].w - m[3].z * m[2].w;
+ highp float c02 = m[1].z * m[3].w - m[3].z * m[1].w;
+ highp float c03 = m[1].z * m[2].w - m[2].z * m[1].w;
+
+ highp float c04 = m[2].y * m[3].w - m[3].y * m[2].w;
+ highp float c06 = m[1].y * m[3].w - m[3].y * m[1].w;
+ highp float c07 = m[1].y * m[2].w - m[2].y * m[1].w;
+
+ highp float c08 = m[2].y * m[3].z - m[3].y * m[2].z;
+ highp float c10 = m[1].y * m[3].z - m[3].y * m[1].z;
+ highp float c11 = m[1].y * m[2].z - m[2].y * m[1].z;
+
+ highp float c12 = m[2].x * m[3].w - m[3].x * m[2].w;
+ highp float c14 = m[1].x * m[3].w - m[3].x * m[1].w;
+ highp float c15 = m[1].x * m[2].w - m[2].x * m[1].w;
+
+ highp float c16 = m[2].x * m[3].z - m[3].x * m[2].z;
+ highp float c18 = m[1].x * m[3].z - m[3].x * m[1].z;
+ highp float c19 = m[1].x * m[2].z - m[2].x * m[1].z;
+
+ highp float c20 = m[2].x * m[3].y - m[3].x * m[2].y;
+ highp float c22 = m[1].x * m[3].y - m[3].x * m[1].y;
+ highp float c23 = m[1].x * m[2].y - m[2].x * m[1].y;
+
+ vec4 f0 = vec4(c00, c00, c02, c03);
+ vec4 f1 = vec4(c04, c04, c06, c07);
+ vec4 f2 = vec4(c08, c08, c10, c11);
+ vec4 f3 = vec4(c12, c12, c14, c15);
+ vec4 f4 = vec4(c16, c16, c18, c19);
+ vec4 f5 = vec4(c20, c20, c22, c23);
+
+ vec4 v0 = vec4(m[1].x, m[0].x, m[0].x, m[0].x);
+ vec4 v1 = vec4(m[1].y, m[0].y, m[0].y, m[0].y);
+ vec4 v2 = vec4(m[1].z, m[0].z, m[0].z, m[0].z);
+ vec4 v3 = vec4(m[1].w, m[0].w, m[0].w, m[0].w);
+
+ vec4 inv0 = vec4(v1 * f0 - v2 * f1 + v3 * f2);
+ vec4 inv1 = vec4(v0 * f0 - v2 * f3 + v3 * f4);
+ vec4 inv2 = vec4(v0 * f1 - v1 * f3 + v3 * f5);
+ vec4 inv3 = vec4(v0 * f2 - v1 * f4 + v2 * f5);
+
+ vec4 sa = vec4(+1, -1, +1, -1);
+ vec4 sb = vec4(-1, +1, -1, +1);
+
+ mat4 inv = mat4(inv0 * sa, inv1 * sb, inv2 * sa, inv3 * sb);
+
+ vec4 r0 = vec4(inv[0].x, inv[1].x, inv[2].x, inv[3].x);
+ vec4 d0 = vec4(m[0] * r0);
+
+ highp float d1 = (d0.x + d0.y) + (d0.z + d0.w);
+ highp float d = 1.0 / d1;
+
+ return inv * d;
+}
+
+#endif
+
#ifndef USE_GLES_OVER_GL
-highp mat4 transpose(highp mat4 src) {
+
+#if defined(TRANSPOSE_USED)
+
+highp mat2 transpose(highp mat2 m) {
+ return mat2(
+ vec2(m[0].x, m[1].x),
+ vec2(m[0].y, m[1].y));
+}
+
+highp mat3 transpose(highp mat3 m) {
+ return mat3(
+ vec3(m[0].x, m[1].x, m[2].x),
+ vec3(m[0].y, m[1].y, m[2].y),
+ vec3(m[0].z, m[1].z, m[2].z));
+}
+
+#endif
+
+highp mat4 transpose(highp mat4 m) {
return mat4(
- vec4(src[0].x, src[1].x, src[2].x, src[3].x),
- vec4(src[0].y, src[1].y, src[2].y, src[3].y),
- vec4(src[0].z, src[1].z, src[2].z, src[3].z),
- vec4(src[0].w, src[1].w, src[2].w, src[3].w));
+ vec4(m[0].x, m[1].x, m[2].x, m[3].x),
+ vec4(m[0].y, m[1].y, m[2].y, m[3].y),
+ vec4(m[0].z, m[1].z, m[2].z, m[3].z),
+ vec4(m[0].w, m[1].w, m[2].w, m[3].w));
}
+
+#if defined(OUTER_PRODUCT_USED)
+
+highp mat2 outerProduct(highp vec2 c, highp vec2 r) {
+ return mat2(c * r.x, c * r.y);
+}
+
+highp mat3 outerProduct(highp vec3 c, highp vec3 r) {
+ return mat3(c * r.x, c * r.y, c * r.z);
+}
+
+highp mat4 outerProduct(highp vec4 c, highp vec4 r) {
+ return mat4(c * r.x, c * r.y, c * r.z, c * r.w);
+}
+
+#endif
+
#endif
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index eb5ab53421..edffe852a2 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -200,6 +200,8 @@ void RasterizerCanvasGLES3::canvas_end() {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0);
glColorMask(1, 1, 1, 1);
+ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
+
state.using_texture_rect = false;
state.using_ninepatch = false;
}
@@ -1154,10 +1156,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
- if (storage->frame.current_rt->effects.mip_maps[0].sizes.size() == 0) {
- ERR_EXPLAIN("Can't use screen texture copying in a render target configured without copy buffers");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(storage->frame.current_rt->effects.mip_maps[0].sizes.size() == 0, "Can't use screen texture copying in a render target configured without copy buffers.");
glDisable(GL_BLEND);
@@ -1585,6 +1584,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D());
+ if (storage->frame.current_rt) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0));
+ }
}
glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index fb3d154a7a..35f414cf09 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1008,7 +1008,7 @@ RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
if (!light_instance->light_ptr) {
memdelete(light_instance);
- ERR_FAIL_COND_V(!light_instance->light_ptr, RID());
+ ERR_FAIL_V_MSG(RID(), "Condition ' !light_instance->light_ptr ' is true.");
}
light_instance->self = light_instance_owner.make_rid(light_instance);
@@ -1120,13 +1120,23 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) {
switch (p_material->shader->spatial.depth_draw_mode) {
- case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
+ case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS: {
+ glDepthMask(GL_TRUE);
+ // If some transparent objects write to depth, we need to re-copy depth texture when we need it
+ if (p_alpha_pass && !state.used_depth_prepass) {
+ state.prepared_depth_texture = false;
+ }
+ } break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
glDepthMask(!p_alpha_pass);
} break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
glDepthMask(GL_TRUE);
+ // If some transparent objects write to depth, we need to re-copy depth texture when we need it
+ if (p_alpha_pass) {
+ state.prepared_depth_texture = false;
+ }
} break;
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER: {
glDepthMask(GL_FALSE);
@@ -2250,11 +2260,6 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
_set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, e->sort_key & RenderList::SORT_KEY_CULL_DISABLED_FLAG, p_reverse_cull);
- if (skeleton) {
- state.scene_shader.set_uniform(SceneShaderGLES3::SKELETON_TRANSFORM, skeleton->world_transform);
- state.scene_shader.set_uniform(SceneShaderGLES3::SKELETON_IN_WORLD_COORDS, skeleton->use_world_transform);
- }
-
state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform);
_render_geometry(e);
@@ -2364,7 +2369,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (p_depth_pass) {
- if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test)
+ if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test || p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
return; //bye
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
@@ -2763,9 +2768,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
width /= 2;
height /= 2;
- if (j == 0) {
-
- } else if (j == 1) {
+ if (j == 1) {
x += width;
} else if (j == 2) {
y += height;
@@ -2778,9 +2781,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
height /= 2;
- if (j == 0) {
-
- } else {
+ if (j != 0) {
y += height;
}
}
@@ -2827,7 +2828,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
for (int i = 0; i < p_light_cull_count; i++) {
- ERR_BREAK(i >= RenderList::MAX_LIGHTS);
+ ERR_BREAK(i >= render_list.max_lights);
LightInstance *li = light_instance_owner.getptr(p_light_cull_result[i]);
@@ -4192,7 +4193,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
for (int i = 0; i < p_light_cull_count; i++) {
- ERR_BREAK(i >= RenderList::MAX_LIGHTS);
+ ERR_BREAK(i >= render_list.max_lights);
LightInstance *li = light_instance_owner.getptr(p_light_cull_result[i]);
if (li->light_ptr->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] > CMP_EPSILON) {
@@ -4329,6 +4330,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt->buffers.active) {
current_fbo = storage->frame.current_rt->buffers.fbo;
} else {
+ if (storage->frame.current_rt->effects.mip_maps[0].sizes.size() == 0) {
+ ERR_PRINT_ONCE("Can't use canvas background mode in a render target configured without sampling");
+ return;
+ }
current_fbo = storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo;
}
@@ -4619,6 +4624,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
return;
}
+ if (env && (env->dof_blur_far_enabled || env->dof_blur_near_enabled) && storage->frame.current_rt && storage->frame.current_rt->buffers.active)
+ _prepare_depth_texture();
_post_process(env, p_cam_projection);
// Needed only for debugging
/* if (shadow_atlas && storage->frame.current_rt) {
@@ -4741,9 +4748,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
width /= 2;
height /= 2;
- if (p_pass == 0) {
-
- } else if (p_pass == 1) {
+ if (p_pass == 1) {
x += width;
} else if (p_pass == 2) {
y += height;
@@ -5069,6 +5074,10 @@ void RasterizerSceneGLES3::initialize() {
render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/rendering/max_renderable_elements", PropertyInfo(Variant::INT, "rendering/limits/rendering/max_renderable_elements", PROPERTY_HINT_RANGE, "1024,1000000,1"));
+ render_list.max_lights = GLOBAL_DEF("rendering/limits/rendering/max_renderable_lights", (int)RenderList::DEFAULT_MAX_LIGHTS);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/rendering/max_renderable_lights", PropertyInfo(Variant::INT, "rendering/limits/rendering/max_renderable_lights", PROPERTY_HINT_RANGE, "16,4096,1"));
+ render_list.max_reflections = GLOBAL_DEF("rendering/limits/rendering/max_renderable_reflections", (int)RenderList::DEFAULT_MAX_REFLECTIONS);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/rendering/max_renderable_reflections", PropertyInfo(Variant::INT, "rendering/limits/rendering/max_renderable_reflections", PROPERTY_HINT_RANGE, "8,1024,1"));
{
//quad buffers
@@ -5163,7 +5172,7 @@ void RasterizerSceneGLES3::initialize() {
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_ubo_size);
const int ubo_light_size = 160;
state.ubo_light_size = ubo_light_size;
- state.max_ubo_lights = MIN(RenderList::MAX_LIGHTS, max_ubo_size / ubo_light_size);
+ state.max_ubo_lights = MIN(render_list.max_lights, max_ubo_size / ubo_light_size);
state.spot_array_tmp = (uint8_t *)memalloc(ubo_light_size * state.max_ubo_lights);
state.omni_array_tmp = (uint8_t *)memalloc(ubo_light_size * state.max_ubo_lights);
@@ -5188,7 +5197,7 @@ void RasterizerSceneGLES3::initialize() {
state.scene_shader.add_custom_define("#define MAX_LIGHT_DATA_STRUCTS " + itos(state.max_ubo_lights) + "\n");
state.scene_shader.add_custom_define("#define MAX_FORWARD_LIGHTS " + itos(state.max_forward_lights_per_object) + "\n");
- state.max_ubo_reflections = MIN((int)RenderList::MAX_REFLECTIONS, max_ubo_size / sizeof(ReflectionProbeDataUBO));
+ state.max_ubo_reflections = MIN(render_list.max_reflections, max_ubo_size / (int)sizeof(ReflectionProbeDataUBO));
state.reflection_array_tmp = (uint8_t *)memalloc(sizeof(ReflectionProbeDataUBO) * state.max_ubo_reflections);
@@ -5301,7 +5310,7 @@ void RasterizerSceneGLES3::initialize() {
GLOBAL_DEF("rendering/quality/subsurface_scattering/follow_surface", false);
GLOBAL_DEF("rendering/quality/subsurface_scattering/weight_samples", true);
- GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", true);
+ GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", false);
}
exposure_shrink_size = 243;
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 910f90edc2..3d09adcfeb 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -527,8 +527,8 @@ public:
fog_transmit_enabled(true),
fog_transmit_curve(1),
fog_height_enabled(false),
- fog_height_min(0),
- fog_height_max(100),
+ fog_height_min(10),
+ fog_height_max(0),
fog_height_curve(1) {
}
};
@@ -669,8 +669,8 @@ public:
SORT_FLAG_SKELETON = 1,
SORT_FLAG_INSTANCING = 2,
MAX_DIRECTIONAL_LIGHTS = 16,
- MAX_LIGHTS = 4096,
- MAX_REFLECTIONS = 1024,
+ DEFAULT_MAX_LIGHTS = 4096,
+ DEFAULT_MAX_REFLECTIONS = 1024,
SORT_KEY_PRIORITY_SHIFT = 56,
SORT_KEY_PRIORITY_MASK = 0xFF,
@@ -701,6 +701,8 @@ public:
};
int max_elements;
+ int max_lights;
+ int max_reflections;
struct Element {
@@ -813,6 +815,8 @@ public:
RenderList() {
max_elements = DEFAULT_MAX_ELEMENTS;
+ max_lights = DEFAULT_MAX_LIGHTS;
+ max_reflections = DEFAULT_MAX_REFLECTIONS;
}
~RenderList() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 994ed25f01..a29831e3f5 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2247,7 +2247,7 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
pi.type = Variant::INT;
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
pi.hint = PROPERTY_HINT_RANGE;
- pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]);
+ pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]) + "," + rtos(u.hint_range[2]);
}
} break;
@@ -2522,8 +2522,8 @@ _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[0] = (v & 1) ? GL_TRUE : GL_FALSE;
+ gui[1] = (v & 2) ? GL_TRUE : GL_FALSE;
} break;
case ShaderLanguage::TYPE_BVEC3: {
@@ -2955,7 +2955,9 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
case ShaderLanguage::TYPE_BVEC3:
case ShaderLanguage::TYPE_IVEC3:
case ShaderLanguage::TYPE_UVEC3:
- case ShaderLanguage::TYPE_VEC3:
+ case ShaderLanguage::TYPE_VEC3: {
+ zeromem(data, 12);
+ } break;
case ShaderLanguage::TYPE_BVEC4:
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4:
@@ -3191,8 +3193,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
//must have index and bones, both.
{
uint32_t bones_weight = VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS;
- ERR_EXPLAIN("Array must have both bones and weights in format or none.");
- ERR_FAIL_COND((p_format & bones_weight) && (p_format & bones_weight) != bones_weight);
+ ERR_FAIL_COND_MSG((p_format & bones_weight) && (p_format & bones_weight) != bones_weight, "Array must have both bones and weights in format or none.");
}
//bool has_morph = p_blend_shapes.size();
@@ -5161,20 +5162,6 @@ void RasterizerStorageGLES3::skeleton_set_base_transform_2d(RID p_skeleton, cons
skeleton->base_transform_2d = p_base_transform;
}
-void RasterizerStorageGLES3::skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) {
-
- Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
-
- ERR_FAIL_COND(skeleton->use_2d);
-
- skeleton->world_transform = p_world_transform;
- skeleton->use_world_transform = p_enable;
-
- if (!skeleton->update_list.in_list()) {
- skeleton_update_list.add(&skeleton->update_list);
- }
-}
-
void RasterizerStorageGLES3::update_dirty_skeletons() {
glActiveTexture(GL_TEXTURE0);
@@ -5471,22 +5458,19 @@ AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const {
float len = light->param[VS::LIGHT_PARAM_RANGE];
float size = Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
- } break;
+ };
case VS::LIGHT_OMNI: {
float r = light->param[VS::LIGHT_PARAM_RANGE];
return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
- } break;
+ };
case VS::LIGHT_DIRECTIONAL: {
return AABB();
- } break;
- default: {
- }
+ };
}
ERR_FAIL_V(AABB());
- return AABB();
}
/* PROBE API */
@@ -8096,7 +8080,7 @@ void RasterizerStorageGLES3::initialize() {
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &config.max_texture_size);
- config.use_rgba_2d_shadows = config.framebuffer_float_supported;
+ config.use_rgba_2d_shadows = !config.framebuffer_float_supported;
//generic quadie for copying
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 0a7e47e304..84632308b4 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -892,15 +892,12 @@ public:
SelfList<Skeleton> update_list;
Set<RasterizerScene::InstanceBase *> instances; //instances using skeleton
Transform2D base_transform_2d;
- bool use_world_transform;
- Transform world_transform;
Skeleton() :
use_2d(false),
size(0),
texture(0),
- update_list(this),
- use_world_transform(false) {
+ update_list(this) {
}
};
@@ -918,7 +915,6 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
- virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
/* Light API */
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index b0f0a71d56..7499962da3 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -467,6 +467,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key());
+ if (E->get().array_size > 0) {
+ vcode += "[";
+ vcode += itos(E->get().array_size);
+ vcode += "]";
+ }
vcode += ";\n";
r_gen_code.vertex_global += interp_mode + "out " + vcode;
r_gen_code.fragment_global += interp_mode + "in " + vcode;
@@ -555,7 +560,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::Node::TYPE_VARIABLE_DECLARATION: {
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node;
- String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype);
+ String declaration;
+ if (vdnode->is_const) {
+ declaration += "const ";
+ }
+ declaration += _prestr(vdnode->precision);
+ declaration += _typestr(vdnode->datatype);
for (int i = 0; i < vdnode->declarations.size(); i++) {
if (i > 0) {
declaration += ",";
@@ -607,6 +617,93 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
} break;
+ case SL::Node::TYPE_ARRAY_DECLARATION: {
+
+ SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
+
+ String declaration;
+ if (adnode->is_const) {
+ declaration += "const ";
+ }
+ declaration += _prestr(adnode->precision);
+ declaration += _typestr(adnode->datatype);
+ for (int i = 0; i < adnode->declarations.size(); i++) {
+ if (i > 0) {
+ declaration += ",";
+ } else {
+ declaration += " ";
+ }
+ declaration += _mkid(adnode->declarations[i].name);
+ declaration += "[";
+ declaration += itos(adnode->declarations[i].size);
+ declaration += "]";
+ int sz = adnode->declarations[i].initializer.size();
+ if (sz > 0) {
+ declaration += "=";
+ declaration += _typestr(adnode->datatype);
+ declaration += "[";
+ declaration += itos(sz);
+ declaration += "]";
+ declaration += "(";
+ for (int j = 0; j < sz; j++) {
+ declaration += _dump_node_code(adnode->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 *anode = (SL::ArrayNode *)p_node;
+
+ if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) {
+ *p_actions.write_flag_pointers[anode->name] = true;
+ }
+
+ if (p_default_actions.usage_defines.has(anode->name) && !used_name_defines.has(anode->name)) {
+ String define = p_default_actions.usage_defines[anode->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(anode->name);
+ }
+
+ if (p_actions.usage_flag_pointers.has(anode->name) && !used_flag_pointers.has(anode->name)) {
+ *p_actions.usage_flag_pointers[anode->name] = true;
+ used_flag_pointers.insert(anode->name);
+ }
+
+ if (p_default_actions.renames.has(anode->name))
+ code = p_default_actions.renames[anode->name];
+ else
+ code = _mkid(anode->name);
+
+ if (anode->call_expression != NULL) {
+ code += ".";
+ code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ }
+
+ if (anode->index_expression != NULL) {
+ code += "[";
+ code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += "]";
+ }
+
+ if (anode->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);
@@ -680,11 +777,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_SELECT_IF: {
+ code += "(";
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "?";
code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += ":";
code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += ")";
} break;
@@ -707,6 +806,20 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _mktab(p_level) + "else\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
+ } else if (cfnode->flow_op == SL::FLOW_OP_SWITCH) {
+ code += _mktab(p_level) + "switch (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_CASE) {
+ code += _mktab(p_level) + "case " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_DEFAULT) {
+ code += _mktab(p_level) + "default:\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else if (cfnode->flow_op == SL::FLOW_OP_DO) {
+ code += _mktab(p_level) + "do";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");";
+
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
@@ -828,6 +941,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
@@ -836,6 +950,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index be2c34ba07..d8d49868f4 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -45,10 +45,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ShaderGLES3 {
protected:
struct Enum {
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index a46b31c92e..e83f53d648 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -345,6 +345,7 @@ void light_compute(
inout vec4 light_color,
vec2 light_uv,
inout vec4 shadow_color,
+ inout vec2 shadow_vec,
vec3 normal,
vec2 uv,
#if defined(SCREEN_UV_USED)
@@ -512,6 +513,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTING
vec2 light_vec = transformed_light_uv;
+ vec2 shadow_vec = transformed_light_uv;
if (normal_used) {
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
@@ -539,6 +541,7 @@ FRAGMENT_SHADER_CODE
real_light_color,
light_uv,
real_light_shadow_color,
+ shadow_vec,
normal,
uv,
#if defined(SCREEN_UV_USED)
@@ -557,11 +560,16 @@ FRAGMENT_SHADER_CODE
color *= light;
#ifdef USE_SHADOWS
- // Reset light_vec to compute shadows, the shadow map is created from the light origin, so it only
- // makes sense to compute shadows from there.
- light_vec = light_uv_interp.zw;
-
- float angle_to_light = -atan(light_vec.x, light_vec.y);
+#ifdef SHADOW_VEC_USED
+ mat3 inverse_light_matrix = mat3(light_matrix);
+ inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
+ inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
+ inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
+ shadow_vec = (mat3(inverse_light_matrix) * vec3(shadow_vec, 0.0)).xy;
+#else
+ shadow_vec = light_uv_interp.zw;
+#endif
+ float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/
@@ -572,18 +580,18 @@ FRAGMENT_SHADER_CODE
vec2 point;
float sh;
if (abs_angle < 45.0 * PI / 180.0) {
- point = light_vec;
+ point = shadow_vec;
sh = 0.0 + (1.0 / 8.0);
} else if (abs_angle > 135.0 * PI / 180.0) {
- point = -light_vec;
+ point = -shadow_vec;
sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light > 0.0) {
- point = vec2(light_vec.y, -light_vec.x);
+ point = vec2(shadow_vec.y, -shadow_vec.x);
sh = 0.25 + (1.0 / 8.0);
} else {
- point = vec2(-light_vec.y, light_vec.x);
+ point = vec2(-shadow_vec.y, shadow_vec.x);
sh = 0.75 + (1.0 / 8.0);
}
@@ -597,7 +605,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0))
+#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
#else
diff --git a/drivers/gles3/shaders/canvas_shadow.glsl b/drivers/gles3/shaders/canvas_shadow.glsl
index 13fff7f4d1..4f706c5505 100644
--- a/drivers/gles3/shaders/canvas_shadow.glsl
+++ b/drivers/gles3/shaders/canvas_shadow.glsl
@@ -35,8 +35,8 @@ void main() {
#ifdef USE_RGBA_SHADOWS
- highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
- comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+ highp vec4 comp = fract(depth * vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0));
+ comp -= comp.xxyz * vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
distance_buf = comp;
#else
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index 232b9ce7c0..1952e201aa 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -165,11 +165,11 @@ void main() {
#elif defined(USE_ASYM_PANO)
// When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
- // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // Asymmetrical projection means the center of projection is no longer in the center of the screen but shifted.
// The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
vec3 cube_normal;
- cube_normal.z = -1000000.0;
+ cube_normal.z = -1.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
cube_normal = mat3(sky_transform) * mat3(pano_transform) * cube_normal;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index f08d3f4d23..20e0c282e3 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -302,8 +302,6 @@ out highp float dp_clip;
#ifdef USE_SKELETON
uniform highp sampler2D skeleton_texture; // texunit:-1
-uniform highp mat4 skeleton_transform;
-uniform bool skeleton_in_world_coords;
#endif
out highp vec4 position_interp;
@@ -432,14 +430,8 @@ void main() {
vec4(0.0, 0.0, 0.0, 1.0)) *
bone_weights.w;
- if (skeleton_in_world_coords) {
- highp mat4 bone_matrix = skeleton_transform * (transpose(m) * inverse(skeleton_transform));
- world_matrix = bone_matrix * world_matrix;
-
- } else {
+ world_matrix = world_matrix * transpose(m);
- world_matrix = world_matrix * transpose(m);
- }
}
#endif
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 626968bc05..f1fe1742eb 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -164,7 +164,8 @@ vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
}
-vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color
+// inputs are LINEAR, If Linear tonemapping is selected no transform is performed else outputs are clamped [0, 1] color
+vec3 apply_tonemapping(vec3 color, float white) {
#ifdef USE_REINHARD_TONEMAPPER
return tonemap_reinhard(color, white);
#endif
@@ -177,7 +178,7 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o
return tonemap_aces(color, white);
#endif
- return clamp(color, vec3(0.0f), vec3(1.0f)); // no other selected -> linear
+ return color; // no other selected -> linear: no color transform applied
}
vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels
@@ -220,10 +221,14 @@ vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blendi
#endif
#ifdef USE_GLOW_SCREEN
+ //need color clamping
+ color = clamp(color, vec3(0.0f), vec3(1.0f));
color = max((color + glow) - (color * glow), vec3(0.0));
#endif
#ifdef USE_GLOW_SOFTLIGHT
+ //need color clamping
+ color = clamp(color, vec3(0.0f), vec3(1.0));
glow = glow * vec3(0.5f) + vec3(0.5f);
color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
@@ -265,14 +270,16 @@ void main() {
color *= exposure;
- // Early Tonemap & SRGB Conversion
+ // Early Tonemap & SRGB Conversion; note that Linear tonemapping does not clamp to [0, 1]; some operations below expect a [0, 1] range and will clamp
color = apply_tonemapping(color, white);
#ifdef KEEP_3D_LINEAR
// leave color as is (-> don't convert to SRGB)
#else
- color = linear_to_srgb(color); // regular linear -> SRGB conversion
+ //need color clamping
+ color = clamp(color, vec3(0.0f), vec3(1.0f));
+ color = linear_to_srgb(color); // regular linear -> SRGB conversion (needs clamped values)
#endif
// Glow
@@ -282,6 +289,7 @@ void main() {
// high dynamic range -> SRGB
glow = apply_tonemapping(glow, white);
+ glow = clamp(glow, vec3(0.0f), vec3(1.0f));
glow = linear_to_srgb(glow);
color = apply_glow(color, glow);
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index cc789f95d6..c910c31f1e 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderPNG : public ImageFormatLoader {
private:
static PoolVector<uint8_t> lossless_pack_png(const Ref<Image> &p_image);
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index 0e849bf2fe..7deac1d118 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -97,7 +97,7 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
break;
default:
png_image_free(&png_img); // only required when we return before finish_read
- ERR_PRINT("Unsupported png format");
+ ERR_PRINT("Unsupported png format.");
return ERR_UNAVAILABLE;
}
@@ -179,10 +179,9 @@ Error image_to_png(const Ref<Image> &p_image, PoolVector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V(check_error(png_img), FAILED);
}
if (!success) {
- if (compressed_size <= png_size_estimate) {
- // buffer was big enough, must be some other error
- ERR_FAIL_V(FAILED);
- }
+
+ // buffer was big enough, must be some other error
+ ERR_FAIL_COND_V(compressed_size <= png_size_estimate, FAILED);
// write failed due to buffer size, resize and retry
Error err = p_buffer.resize(buffer_offset + compressed_size);
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index 89e8ee32cc..3b3f1506dc 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -39,9 +39,8 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
Ref<ImageTexture> texture = p_resource;
- ERR_FAIL_COND_V(!texture.is_valid(), ERR_INVALID_PARAMETER);
- ERR_EXPLAIN("Can't save empty texture as PNG");
- ERR_FAIL_COND_V(!texture->get_width() || !texture->get_height(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG.");
+ ERR_FAIL_COND_V_MSG(!texture->get_width(), ERR_INVALID_PARAMETER, "Can't save empty texture as PNG.");
Ref<Image> img = texture->get_data();
@@ -54,9 +53,9 @@ Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img
PoolVector<uint8_t> buffer;
Error err = PNGDriverCommon::image_to_png(p_img, buffer);
- ERR_FAIL_COND_V(err, err);
+ ERR_FAIL_COND_V_MSG(err, err, "Can't convert image to PNG.");
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
- ERR_FAIL_COND_V(err, err);
+ ERR_FAIL_COND_V_MSG(err, err, vformat("Can't save PNG at path: '%s'.", p_path));
PoolVector<uint8_t>::Read reader = buffer.read();
@@ -79,7 +78,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 a61fa449f1..7ba2175652 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -227,8 +227,8 @@ Error AudioDriverPulseAudio::init_device() {
samples_out.resize(pa_buffer_size);
// Reset audio input to keep synchronisation.
- input_position = 0;
- input_size = 0;
+ capture_position = 0;
+ capture_size = 0;
return OK;
}
@@ -266,7 +266,10 @@ Error AudioDriverPulseAudio::init() {
}
while (pa_ready == 0) {
- pa_mainloop_iterate(pa_ml, 1, NULL);
+ ret = pa_mainloop_iterate(pa_ml, 1, NULL);
+ if (ret < 0) {
+ ERR_PRINT("pa_mainloop_iterate error");
+ }
}
if (pa_ready < 0) {
@@ -460,7 +463,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
size_t bytes = pa_stream_readable_size(ad->pa_rec_str);
if (bytes > 0) {
const void *ptr = NULL;
- size_t maxbytes = ad->input_buffer.size() * sizeof(int16_t);
+ size_t maxbytes = ad->capture_buffer.size() * sizeof(int16_t);
bytes = MIN(bytes, maxbytes);
ret = pa_stream_peek(ad->pa_rec_str, &ptr, &bytes);
@@ -470,11 +473,11 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
int16_t *srcptr = (int16_t *)ptr;
for (size_t i = bytes >> 1; i > 0; i--) {
int32_t sample = int32_t(*srcptr++) << 16;
- ad->input_buffer_write(sample);
+ ad->capture_buffer_write(sample);
if (ad->pa_rec_map.channels == 1) {
- // In case input device is single channel convert it to Stereo
- ad->input_buffer_write(sample);
+ // In case capture device is single channel convert it to Stereo
+ ad->capture_buffer_write(sample);
}
}
@@ -661,7 +664,7 @@ Error AudioDriverPulseAudio::capture_init_device() {
break;
default:
- WARN_PRINTS("PulseAudio: Unsupported number of input channels: " + itos(pa_rec_map.channels));
+ WARN_PRINTS("PulseAudio: Unsupported number of capture channels: " + itos(pa_rec_map.channels));
pa_channel_map_init_stereo(&pa_rec_map);
break;
}
@@ -693,10 +696,10 @@ Error AudioDriverPulseAudio::capture_init_device() {
ERR_FAIL_V(ERR_CANT_OPEN);
}
- input_buffer_init(input_buffer_frames);
+ capture_buffer_init(input_buffer_frames);
- print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
- print_verbose("PulseAudio: input buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");
+ print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " capture channels");
+ print_verbose("PulseAudio: capture buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");
return OK;
}
diff --git a/drivers/register_driver_types.h b/drivers/register_driver_types.h
index 3fdf802c9f..a3398964dd 100644
--- a/drivers/register_driver_types.h
+++ b/drivers/register_driver_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_DRIVER_TYPES_H
#define REGISTER_DRIVER_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_core_driver_types();
void unregister_core_driver_types();
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 251bab5783..6817137a94 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -126,37 +126,32 @@ String DirAccessUnix::get_next() {
if (!dir_stream)
return "";
- dirent *entry;
- entry = readdir(dir_stream);
+ dirent *entry = readdir(dir_stream);
if (entry == NULL) {
-
list_dir_end();
return "";
}
- //typedef struct stat Stat;
- struct stat flags;
-
String fname = fix_unicode_name(entry->d_name);
- String f = current_dir.plus_file(fname);
-
- if (stat(f.utf8().get_data(), &flags) == 0) {
-
- if (S_ISDIR(flags.st_mode)) {
-
- _cisdir = true;
-
+ // Look at d_type to determine if the entry is a directory, unless
+ // its type is unknown (the file system does not support it) or if
+ // the type is a link, in that case we want to resolve the link to
+ // known if it points to a directory. stat() will resolve the link
+ // for us.
+ if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) {
+ String f = current_dir.plus_file(fname);
+
+ struct stat flags;
+ if (stat(f.utf8().get_data(), &flags) == 0) {
+ _cisdir = S_ISDIR(flags.st_mode);
} else {
-
_cisdir = false;
}
-
} else {
-
- _cisdir = false;
+ _cisdir = (entry->d_type == DT_DIR);
}
_cishidden = (fname != "." && fname != ".." && fname.begins_with("."));
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 579cb0e798..88674d2769 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -40,10 +40,6 @@
#include <sys/types.h>
#include <unistd.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class DirAccessUnix : public DirAccess {
DIR *dir_stream;
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index a285b3b65f..071734eb48 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -38,6 +38,8 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <errno.h>
+
#if defined(UNIX_ENABLED)
#include <unistd.h>
#endif
@@ -112,8 +114,15 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
f = fopen(path.utf8().get_data(), mode_string);
if (f == NULL) {
- last_error = ERR_FILE_CANT_OPEN;
- return ERR_FILE_CANT_OPEN;
+ switch (errno) {
+ case ENOENT: {
+ last_error = ERR_FILE_NOT_FOUND;
+ } break;
+ default: {
+ last_error = ERR_FILE_CANT_OPEN;
+ } break;
+ }
+ return last_error;
} else {
last_error = OK;
flags = p_mode_flags;
@@ -288,8 +297,7 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
if (!err) {
return flags.st_mtime;
} else {
- ERR_EXPLAIN("Failed to get modified time for: " + p_file);
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + p_file + ".");
};
}
@@ -302,8 +310,7 @@ uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
if (!err) {
return flags.st_mode & 0x7FF; //only permissions
} else {
- ERR_EXPLAIN("Failed to get unix permissions for: " + p_file);
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Failed to get unix permissions for: " + p_file + ".");
};
}
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 2a369048a4..e26591e3e8 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -38,10 +38,6 @@
#if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED)
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*CloseNotificationFunc)(const String &p_file, int p_flags);
class FileAccessUnix : public FileAccess {
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index ce66f07a19..ac7195abc1 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -184,9 +184,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
continue; // will go back and alloc the right size
};
- ERR_EXPLAIN("Call to GetAdaptersAddresses failed with error " + itos(err));
- ERR_FAIL();
- return;
+ ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + ".");
};
IP_ADAPTER_ADDRESSES *adapter = addrs;
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index aa61cf5dcc..ab5590dba4 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -72,8 +72,7 @@ static double _clock_scale = 0;
static void _setup_clock() {
mach_timebase_info_data_t info;
kern_return_t ret = mach_timebase_info(&info);
- ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
- ERR_FAIL_COND(ret != 0);
+ ERR_FAIL_COND_MSG(ret != 0, "OS CLOCK IS NOT WORKING!");
_clock_scale = ((double)info.numer / (double)info.denom) / 1000.0;
_clock_start = mach_absolute_time() * _clock_scale;
}
@@ -85,8 +84,7 @@ static void _setup_clock() {
#endif
static void _setup_clock() {
struct timespec tv_now = { 0, 0 };
- ERR_EXPLAIN("OS CLOCK IS NOT WORKING!");
- ERR_FAIL_COND(clock_gettime(GODOT_CLOCK, &tv_now) != 0);
+ ERR_FAIL_COND_MSG(clock_gettime(GODOT_CLOCK, &tv_now) != 0, "OS CLOCK IS NOT WORKING!");
_clock_start = ((uint64_t)tv_now.tv_nsec / 1000L) + (uint64_t)tv_now.tv_sec * 1000000L;
}
#endif
@@ -420,10 +418,7 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ". Error: " + dlerror());
return OK;
}
@@ -442,12 +437,9 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S
error = dlerror();
if (error != NULL) {
- if (!p_optional) {
- ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + error);
- ERR_FAIL_V(ERR_CANT_RESOLVE);
- } else {
- return ERR_CANT_RESOLVE;
- }
+ ERR_FAIL_COND_V_MSG(!p_optional, ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ". Error: " + error + ".");
+
+ return ERR_CANT_RESOLVE;
}
return OK;
}
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 53446a6b6f..a263147e23 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -31,10 +31,6 @@
#ifndef OS_UNIX_H
#define OS_UNIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifdef UNIX_ENABLED
#include "core/os/os.h"
diff --git a/drivers/unix/semaphore_posix.h b/drivers/unix/semaphore_posix.h
index 089f088d33..83e75c9a82 100644
--- a/drivers/unix/semaphore_posix.h
+++ b/drivers/unix/semaphore_posix.h
@@ -36,9 +36,7 @@
#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
#include <semaphore.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class SemaphorePosix : public Semaphore {
mutable sem_t sem;
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index d6b6267c49..5edacd3a0c 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -31,10 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
#include "core/os/thread.h"
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index fea38ee95d..adc3cc8d65 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -296,8 +296,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
}
hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, NULL);
- ERR_EXPLAIN("WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16));
- ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16) + ".");
if (p_capture) {
hr = p_device->audio_client->GetService(IID_IAudioCaptureClient, (void **)&p_device->capture_client);
@@ -343,8 +342,8 @@ Error AudioDriverWASAPI::init_render_device(bool reinit) {
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
samples_in.resize(buffer_frames * channels);
- input_position = 0;
- input_size = 0;
+ capture_position = 0;
+ capture_size = 0;
print_verbose("WASAPI: detected " + itos(channels) + " channels");
print_verbose("WASAPI: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
@@ -363,7 +362,7 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
HRESULT hr = audio_input.audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
- input_buffer_init(max_frames);
+ capture_buffer_init(max_frames);
return OK;
}
@@ -716,8 +715,8 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
}
- ad->input_buffer_write(l);
- ad->input_buffer_write(r);
+ ad->capture_buffer_write(l);
+ ad->capture_buffer_write(r);
}
read_frames += num_frames_available;
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 646e744248..fb21c0c5a1 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -38,6 +38,7 @@
#include <shlwapi.h>
#include <windows.h>
+#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <tchar.h>
@@ -114,17 +115,25 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
path = path + ".tmp";
}
- _wfopen_s(&f, path.c_str(), mode_string);
+ errno_t errcode = _wfopen_s(&f, path.c_str(), mode_string);
if (f == NULL) {
- last_error = ERR_FILE_CANT_OPEN;
- return ERR_FILE_CANT_OPEN;
+ switch (errcode) {
+ case ENOENT: {
+ last_error = ERR_FILE_NOT_FOUND;
+ } break;
+ default: {
+ last_error = ERR_FILE_CANT_OPEN;
+ } break;
+ }
+ return last_error;
} else {
last_error = OK;
flags = p_mode_flags;
return OK;
}
}
+
void FileAccessWindows::close() {
if (!f)
@@ -167,13 +176,11 @@ void FileAccessWindows::close() {
if (close_fail_notify) {
close_fail_notify(save_path);
}
-
- ERR_EXPLAIN("Safe save failed. This may be a permissions problem, but also may happen because you are running a paranoid antivirus. If this is the case, please switch to Windows Defender or disable the 'safe save' option in editor settings. This makes it work, but increases the risk of file corruption in a crash.");
}
save_path = "";
- ERR_FAIL_COND(rename_error);
+ ERR_FAIL_COND_MSG(rename_error, "Safe save failed. This may be a permissions problem, but also may happen because you are running a paranoid antivirus. If this is the case, please switch to Windows Defender or disable the 'safe save' option in editor settings. This makes it work, but increases the risk of file corruption in a crash.");
}
}
@@ -334,8 +341,7 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
return st.st_mtime;
} else {
- ERR_EXPLAIN("Failed to get modified time for: " + file);
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + file + ".");
}
}
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 2848ed5279..e7f9fc690d 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -38,10 +38,6 @@
#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class FileAccessWindows : public FileAccess {
FILE *f;
diff --git a/drivers/windows/mutex_windows.h b/drivers/windows/mutex_windows.h
index 6d3b641a26..582d26029c 100644
--- a/drivers/windows/mutex_windows.h
+++ b/drivers/windows/mutex_windows.h
@@ -37,10 +37,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MutexWindows : public Mutex {
#ifdef WINDOWS_USE_MUTEX
diff --git a/drivers/windows/semaphore_windows.h b/drivers/windows/semaphore_windows.h
index 8adeffbb7f..cfd33d033a 100644
--- a/drivers/windows/semaphore_windows.h
+++ b/drivers/windows/semaphore_windows.h
@@ -37,10 +37,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class SemaphoreWindows : public Semaphore {
mutable HANDLE semaphore;
diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h
index a74d4e46f3..b47452838c 100644
--- a/drivers/windows/thread_windows.h
+++ b/drivers/windows/thread_windows.h
@@ -38,10 +38,6 @@
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ThreadWindows : public Thread {
ThreadCreateCallback callback;
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index 8674d24af6..6d729c50ab 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -63,15 +63,10 @@ Error AudioDriverXAudio2::init() {
HRESULT hr;
hr = XAudio2Create(&xaudio, 0, XAUDIO2_DEFAULT_PROCESSOR);
- if (hr != S_OK) {
- ERR_EXPLAIN("Error creating XAudio2 engine.");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 engine.");
+
hr = xaudio->CreateMasteringVoice(&mastering_voice);
- if (hr != S_OK) {
- ERR_EXPLAIN("Error creating XAudio2 mastering voice.");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 mastering voice.");
wave_format.nChannels = channels;
wave_format.cbSize = 0;
@@ -82,10 +77,7 @@ Error AudioDriverXAudio2::init() {
wave_format.nAvgBytesPerSec = mix_rate * wave_format.nBlockAlign;
hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback);
- if (hr != S_OK) {
- ERR_EXPLAIN("Error creating XAudio2 source voice. " + itos(hr));
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 source voice. Error code: " + itos(hr) + ".");
mutex = Mutex::create();
thread = Thread::create(AudioDriverXAudio2::thread_func, this);
@@ -140,10 +132,7 @@ void AudioDriverXAudio2::start() {
active = true;
HRESULT hr = source_voice->Start(0);
- if (hr != S_OK) {
- ERR_EXPLAIN("XAudio2 start error " + itos(hr));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
}
int AudioDriverXAudio2::get_mix_rate() const {
diff --git a/editor/SCsub b/editor/SCsub
index 7d48e47c9f..2b560f68e8 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -31,7 +31,7 @@ if env['tools']:
reg_exporters_inc = '#include "register_exporters.h"\n'
reg_exporters = 'void register_exporters() {\n'
for e in env.platform_exporters:
- env.editor_sources.append("#platform/" + e + "/export/export.cpp")
+ env.add_source_files(env.editor_sources, "#platform/" + e + "/export/export.cpp")
reg_exporters += '\tregister_' + e + '_exporter();\n'
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
reg_exporters += '}\n'
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 14ea18f885..9194da654c 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -354,10 +354,12 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
{ //guides
float min_left_scale = font->get_height() + vsep;
- float scale = 1;
+ float scale = (min_left_scale * 2) * v_zoom;
+ float step = Math::pow(10.0, Math::round(Math::log(scale / 5.0) / Math::log(10.0))) * 5.0;
+ scale = Math::stepify(scale, step);
while (scale / v_zoom < min_left_scale * 2) {
- scale *= 5;
+ scale += step;
}
bool first = true;
@@ -378,7 +380,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
draw_line(Point2(limit, i), Point2(right_limit, i), lc);
Color c = color;
c.a *= 0.5;
- draw_string(font, Point2(limit + 8, i - 2), itos((iv + 1) * scale), c);
+ draw_string(font, Point2(limit + 8, i - 2), rtos(Math::stepify((iv + 1) * scale, step)), c);
}
first = false;
@@ -628,24 +630,28 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ float v_zoom_orig = v_zoom;
if (mb->get_command()) {
timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
} else {
- if (v_zoom < 1000) {
+ if (v_zoom < 100000) {
v_zoom *= 1.2;
}
}
+ v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
update();
}
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ float v_zoom_orig = v_zoom;
if (mb->get_command()) {
timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
} else {
- if (v_zoom > 0.01) {
+ if (v_zoom > 0.000001) {
v_zoom /= 1.2;
}
}
+ v_scroll = v_scroll + (mb->get_position().y - get_size().y / 2) * (v_zoom - v_zoom_orig);
update();
}
@@ -923,13 +929,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, 1);
}
- // 6-(undo) reinsert overlapped keys
- for (List<AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
-
- AnimMoveRestore &amr = E->get();
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, 1);
- }
-
undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f5b5cfa848..fa773b17c2 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -31,6 +31,7 @@
#include "animation_track_editor.h"
#include "animation_track_editor_plugins.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "editor/animation_bezier_editor.h"
#include "editor/plugins/animation_player_editor_plugin.h"
@@ -82,22 +83,23 @@ public:
}
void _update_obj(const Ref<Animation> &p_anim) {
- if (setting)
- return;
- if (!(animation == p_anim))
+
+ if (setting || animation != p_anim)
return;
notify_change();
}
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
- if (!(animation == p_anim))
- return;
- if (from != key_ofs)
+
+ if (animation != p_anim || from != key_ofs)
return;
+
key_ofs = to;
+
if (setting)
return;
+
notify_change();
}
@@ -118,6 +120,7 @@ public:
}
new_time /= fps;
}
+
if (new_time == key_ofs)
return true;
@@ -141,12 +144,13 @@ public:
trans = animation->track_get_key_transition(track, existing);
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, new_time, v, trans);
}
-
undo_redo->commit_action();
- setting = false;
+ setting = false;
return true;
- } else if (name == "easing") {
+ }
+
+ if (name == "easing") {
float val = p_value;
float prev_val = animation->track_get_key_transition(track, key);
@@ -157,6 +161,7 @@ public:
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
undo_redo->commit_action();
+
setting = false;
return true;
}
@@ -166,7 +171,7 @@ public:
case Animation::TYPE_TRANSFORM: {
Dictionary d_old = animation->track_get_key_value(track, key);
- Dictionary d_new = d_old;
+ Dictionary d_new = d_old.duplicate();
d_new[p_name] = p_value;
setting = true;
undo_redo->create_action(TTR("Anim Change Transform"));
@@ -178,7 +183,6 @@ public:
setting = false;
return true;
-
} break;
case Animation::TYPE_VALUE: {
@@ -187,7 +191,6 @@ public:
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
-
_fix_node_path(value);
}
@@ -203,12 +206,11 @@ public:
setting = false;
return true;
}
-
} break;
case Animation::TYPE_METHOD: {
Dictionary d_old = animation->track_get_key_value(track, key);
- Dictionary d_new = d_old;
+ Dictionary d_new = d_old.duplicate();
bool change_notify_deserved = false;
bool mergeable = false;
@@ -216,17 +218,13 @@ public:
if (name == "name") {
d_new["method"] = p_value;
- }
-
- if (name == "arg_count") {
+ } else if (name == "arg_count") {
Vector<Variant> args = d_old["args"];
args.resize(p_value);
d_new["args"] = args;
change_notify_deserved = true;
- }
-
- if (name.begins_with("args/")) {
+ } else if (name.begins_with("args/")) {
Vector<Variant> args = d_old["args"];
int idx = name.get_slice("/", 1).to_int();
@@ -249,8 +247,7 @@ public:
change_notify_deserved = true;
d_new["args"] = args;
}
- }
- if (what == "value") {
+ } else if (what == "value") {
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
@@ -300,6 +297,7 @@ public:
setting = false;
return true;
}
+
if (name == "in_handle") {
const Variant &value = p_value;
@@ -316,6 +314,7 @@ public:
setting = false;
return true;
}
+
if (name == "out_handle") {
const Variant &value = p_value;
@@ -332,7 +331,6 @@ public:
setting = false;
return true;
}
-
} break;
case Animation::TYPE_AUDIO: {
@@ -352,6 +350,7 @@ public:
setting = false;
return true;
}
+
if (name == "start_offset") {
float value = p_value;
@@ -368,6 +367,7 @@ public:
setting = false;
return true;
}
+
if (name == "end_offset") {
float value = p_value;
@@ -384,7 +384,6 @@ public:
setting = false;
return true;
}
-
} break;
case Animation::TYPE_ANIMATION: {
@@ -400,10 +399,10 @@ public:
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
undo_redo->commit_action();
+
setting = false;
return true;
}
-
} break;
}
@@ -419,20 +418,24 @@ public:
if (name == "time") {
r_ret = key_ofs;
return true;
- } else if (name == "frame") {
+ }
+
+ if (name == "frame") {
+
float fps = animation->get_step();
if (fps > 0) {
fps = 1.0 / fps;
}
r_ret = key_ofs * fps;
return true;
- } else if (name == "easing") {
+ }
+
+ if (name == "easing") {
r_ret = animation->track_get_key_transition(track, key);
return true;
}
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
Dictionary d = animation->track_get_key_value(track, key);
@@ -465,7 +468,6 @@ public:
Vector<Variant> args = d["args"];
if (name == "arg_count") {
-
r_ret = args.size();
return true;
}
@@ -480,6 +482,7 @@ public:
r_ret = args[idx].get_type();
return true;
}
+
if (what == "value") {
r_ret = args[idx];
return true;
@@ -493,10 +496,12 @@ public:
r_ret = animation->bezier_track_get_key_value(track, key);
return true;
}
+
if (name == "in_handle") {
r_ret = animation->bezier_track_get_key_in_handle(track, key);
return true;
}
+
if (name == "out_handle") {
r_ret = animation->bezier_track_get_key_out_handle(track, key);
return true;
@@ -509,10 +514,12 @@ public:
r_ret = animation->audio_track_get_key_stream(track, key);
return true;
}
+
if (name == "start_offset") {
r_ret = animation->audio_track_get_key_start_offset(track, key);
return true;
}
+
if (name == "end_offset") {
r_ret = animation->audio_track_get_key_end_offset(track, key);
return true;
@@ -691,6 +698,702 @@ public:
}
};
+class AnimationMultiTrackKeyEdit : public Object {
+
+ GDCLASS(AnimationMultiTrackKeyEdit, Object);
+
+public:
+ bool setting;
+
+ bool _hide_script_from_inspector() {
+ return true;
+ }
+
+ bool _dont_undo_redo() {
+ return true;
+ }
+
+ static void _bind_methods() {
+
+ ClassDB::bind_method("_update_obj", &AnimationMultiTrackKeyEdit::_update_obj);
+ ClassDB::bind_method("_key_ofs_changed", &AnimationMultiTrackKeyEdit::_key_ofs_changed);
+ ClassDB::bind_method("_hide_script_from_inspector", &AnimationMultiTrackKeyEdit::_hide_script_from_inspector);
+ ClassDB::bind_method("get_root_path", &AnimationMultiTrackKeyEdit::get_root_path);
+ ClassDB::bind_method("_dont_undo_redo", &AnimationMultiTrackKeyEdit::_dont_undo_redo);
+ }
+
+ void _fix_node_path(Variant &value, NodePath &base) {
+
+ NodePath np = value;
+
+ if (np == NodePath())
+ return;
+
+ Node *root = EditorNode::get_singleton()->get_tree()->get_root();
+
+ Node *np_node = root->get_node(np);
+ ERR_FAIL_COND(!np_node);
+
+ Node *edited_node = root->get_node(base);
+ ERR_FAIL_COND(!edited_node);
+
+ value = edited_node->get_path_to(np_node);
+ }
+
+ void _update_obj(const Ref<Animation> &p_anim) {
+
+ if (setting || animation != p_anim)
+ return;
+
+ notify_change();
+ }
+
+ void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
+
+ if (animation != p_anim)
+ return;
+
+ for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) {
+
+ for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
+
+ float key_ofs = F->get();
+ if (from != key_ofs)
+ continue;
+
+ int track = E->key();
+ key_ofs_map[track][key_ofs] = to;
+
+ if (setting)
+ return;
+
+ notify_change();
+
+ return;
+ }
+ }
+ }
+
+ bool _set(const StringName &p_name, const Variant &p_value) {
+
+ bool update_obj = false;
+ bool change_notify_deserved = false;
+ for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) {
+
+ int track = E->key();
+ for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
+
+ float key_ofs = F->get();
+ int key = animation->track_find_key(track, key_ofs, true);
+ ERR_FAIL_COND_V(key == -1, false);
+
+ String name = p_name;
+ if (name == "time" || name == "frame") {
+
+ float new_time = p_value;
+
+ if (name == "frame") {
+ float fps = animation->get_step();
+ if (fps > 0) {
+ fps = 1.0 / fps;
+ }
+ new_time /= fps;
+ }
+
+ int existing = animation->track_find_key(track, new_time, true);
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Time"), UndoRedo::MERGE_ENDS);
+ }
+
+ Variant val = animation->track_get_key_value(track, key);
+ float trans = animation->track_get_key_transition(track, key);
+
+ undo_redo->add_do_method(animation.ptr(), "track_remove_key", track, key);
+ undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, new_time, val, trans);
+ undo_redo->add_do_method(this, "_key_ofs_changed", animation, key_ofs, new_time);
+ undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", track, new_time);
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, key_ofs, val, trans);
+ undo_redo->add_undo_method(this, "_key_ofs_changed", animation, new_time, key_ofs);
+
+ if (existing != -1) {
+ Variant v = animation->track_get_key_value(track, existing);
+ trans = animation->track_get_key_transition(track, existing);
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, new_time, v, trans);
+ }
+ } else if (name == "easing") {
+
+ float val = p_value;
+ float prev_val = animation->track_get_key_transition(track, key);
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Transition"), UndoRedo::MERGE_ENDS);
+ }
+ undo_redo->add_do_method(animation.ptr(), "track_set_key_transition", track, key, val);
+ undo_redo->add_undo_method(animation.ptr(), "track_set_key_transition", track, key, prev_val);
+ update_obj = true;
+ }
+
+ switch (animation->track_get_type(track)) {
+
+ case Animation::TYPE_TRANSFORM: {
+
+ Dictionary d_old = animation->track_get_key_value(track, key);
+ Dictionary d_new = d_old.duplicate();
+ d_new[p_name] = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Transform"));
+ }
+ undo_redo->add_do_method(animation.ptr(), "track_set_key_value", track, key, d_new);
+ undo_redo->add_undo_method(animation.ptr(), "track_set_key_value", track, key, d_old);
+ update_obj = true;
+ } break;
+ case Animation::TYPE_VALUE: {
+
+ if (name == "value") {
+
+ Variant value = p_value;
+
+ if (value.get_type() == Variant::NODE_PATH) {
+ _fix_node_path(value, base_map[track]);
+ }
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ Variant prev = animation->track_get_key_value(track, key);
+ undo_redo->add_do_method(animation.ptr(), "track_set_key_value", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "track_set_key_value", track, key, prev);
+ update_obj = true;
+ }
+ } break;
+ case Animation::TYPE_METHOD: {
+
+ Dictionary d_old = animation->track_get_key_value(track, key);
+ Dictionary d_new = d_old.duplicate();
+
+ bool mergeable = false;
+
+ if (name == "name") {
+
+ d_new["method"] = p_value;
+ } else if (name == "arg_count") {
+
+ Vector<Variant> args = d_old["args"];
+ args.resize(p_value);
+ d_new["args"] = args;
+ change_notify_deserved = true;
+ } else if (name.begins_with("args/")) {
+
+ Vector<Variant> args = d_old["args"];
+ int idx = name.get_slice("/", 1).to_int();
+ ERR_FAIL_INDEX_V(idx, args.size(), false);
+
+ String what = name.get_slice("/", 2);
+ if (what == "type") {
+ Variant::Type t = Variant::Type(int(p_value));
+
+ if (t != args[idx].get_type()) {
+ Variant::CallError err;
+ if (Variant::can_convert(args[idx].get_type(), t)) {
+ Variant old = args[idx];
+ Variant *ptrs[1] = { &old };
+ args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
+ } else {
+
+ args.write[idx] = Variant::construct(t, NULL, 0, err);
+ }
+ change_notify_deserved = true;
+ d_new["args"] = args;
+ }
+ } else if (what == "value") {
+
+ Variant value = p_value;
+ if (value.get_type() == Variant::NODE_PATH) {
+
+ _fix_node_path(value, base_map[track]);
+ }
+
+ args.write[idx] = value;
+ d_new["args"] = args;
+ mergeable = true;
+ }
+ }
+
+ Variant prev = animation->track_get_key_value(track, key);
+
+ if (!setting) {
+ if (mergeable)
+ undo_redo->create_action(TTR("Anim Multi Change Call"), UndoRedo::MERGE_ENDS);
+ else
+ undo_redo->create_action(TTR("Anim Multi Change Call"));
+
+ setting = true;
+ }
+
+ undo_redo->add_do_method(animation.ptr(), "track_set_key_value", track, key, d_new);
+ undo_redo->add_undo_method(animation.ptr(), "track_set_key_value", track, key, d_old);
+ update_obj = true;
+ } break;
+ case Animation::TYPE_BEZIER: {
+
+ if (name == "value") {
+
+ const Variant &value = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ float prev = animation->bezier_track_get_key_value(track, key);
+ undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_value", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_value", track, key, prev);
+ update_obj = true;
+ } else if (name == "in_handle") {
+
+ const Variant &value = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ Vector2 prev = animation->bezier_track_get_key_in_handle(track, key);
+ undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, prev);
+ update_obj = true;
+ } else if (name == "out_handle") {
+
+ const Variant &value = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ Vector2 prev = animation->bezier_track_get_key_out_handle(track, key);
+ undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, prev);
+ update_obj = true;
+ }
+ } break;
+ case Animation::TYPE_AUDIO: {
+
+ if (name == "stream") {
+
+ Ref<AudioStream> stream = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ RES prev = animation->audio_track_get_key_stream(track, key);
+ undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_stream", track, key, stream);
+ undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev);
+ update_obj = true;
+ } else if (name == "start_offset") {
+
+ float value = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ float prev = animation->audio_track_get_key_start_offset(track, key);
+ undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_start_offset", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_start_offset", track, key, prev);
+ update_obj = true;
+ } else if (name == "end_offset") {
+
+ float value = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ float prev = animation->audio_track_get_key_end_offset(track, key);
+ undo_redo->add_do_method(animation.ptr(), "audio_track_set_key_end_offset", track, key, value);
+ undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_end_offset", track, key, prev);
+ update_obj = true;
+ }
+ } break;
+ case Animation::TYPE_ANIMATION: {
+
+ if (name == "animation") {
+
+ StringName anim_name = p_value;
+
+ if (!setting) {
+ setting = true;
+ undo_redo->create_action(TTR("Anim Multi Change Keyframe Value"), UndoRedo::MERGE_ENDS);
+ }
+ StringName prev = animation->animation_track_get_key_animation(track, key);
+ undo_redo->add_do_method(animation.ptr(), "animation_track_set_key_animation", track, key, anim_name);
+ undo_redo->add_undo_method(animation.ptr(), "animation_track_set_key_animation", track, key, prev);
+ update_obj = true;
+ }
+ } break;
+ }
+ }
+ }
+
+ if (setting) {
+
+ if (update_obj) {
+ undo_redo->add_do_method(this, "_update_obj", animation);
+ undo_redo->add_undo_method(this, "_update_obj", animation);
+ }
+
+ undo_redo->commit_action();
+ setting = false;
+
+ if (change_notify_deserved)
+ notify_change();
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool _get(const StringName &p_name, Variant &r_ret) const {
+
+ for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) {
+
+ int track = E->key();
+ for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
+
+ float key_ofs = F->get();
+ int key = animation->track_find_key(track, key_ofs, true);
+ ERR_CONTINUE(key == -1);
+
+ String name = p_name;
+ if (name == "time") {
+ r_ret = key_ofs;
+ return true;
+ }
+
+ if (name == "frame") {
+
+ float fps = animation->get_step();
+ if (fps > 0) {
+ fps = 1.0 / fps;
+ }
+ r_ret = key_ofs * fps;
+ return true;
+ }
+
+ if (name == "easing") {
+ r_ret = animation->track_get_key_transition(track, key);
+ return true;
+ }
+
+ switch (animation->track_get_type(track)) {
+
+ case Animation::TYPE_TRANSFORM: {
+
+ Dictionary d = animation->track_get_key_value(track, key);
+ ERR_FAIL_COND_V(!d.has(name), false);
+ r_ret = d[p_name];
+ return true;
+
+ } break;
+ case Animation::TYPE_VALUE: {
+
+ if (name == "value") {
+ r_ret = animation->track_get_key_value(track, key);
+ return true;
+ }
+
+ } break;
+ case Animation::TYPE_METHOD: {
+
+ Dictionary d = animation->track_get_key_value(track, key);
+
+ if (name == "name") {
+
+ ERR_FAIL_COND_V(!d.has("method"), false);
+ r_ret = d["method"];
+ return true;
+ }
+
+ ERR_FAIL_COND_V(!d.has("args"), false);
+
+ Vector<Variant> args = d["args"];
+
+ if (name == "arg_count") {
+
+ r_ret = args.size();
+ return true;
+ }
+
+ if (name.begins_with("args/")) {
+
+ int idx = name.get_slice("/", 1).to_int();
+ ERR_FAIL_INDEX_V(idx, args.size(), false);
+
+ String what = name.get_slice("/", 2);
+ if (what == "type") {
+ r_ret = args[idx].get_type();
+ return true;
+ }
+
+ if (what == "value") {
+ r_ret = args[idx];
+ return true;
+ }
+ }
+
+ } break;
+ case Animation::TYPE_BEZIER: {
+
+ if (name == "value") {
+ r_ret = animation->bezier_track_get_key_value(track, key);
+ return true;
+ }
+
+ if (name == "in_handle") {
+ r_ret = animation->bezier_track_get_key_in_handle(track, key);
+ return true;
+ }
+
+ if (name == "out_handle") {
+ r_ret = animation->bezier_track_get_key_out_handle(track, key);
+ return true;
+ }
+
+ } break;
+ case Animation::TYPE_AUDIO: {
+
+ if (name == "stream") {
+ r_ret = animation->audio_track_get_key_stream(track, key);
+ return true;
+ }
+
+ if (name == "start_offset") {
+ r_ret = animation->audio_track_get_key_start_offset(track, key);
+ return true;
+ }
+
+ if (name == "end_offset") {
+ r_ret = animation->audio_track_get_key_end_offset(track, key);
+ return true;
+ }
+
+ } break;
+ case Animation::TYPE_ANIMATION: {
+
+ if (name == "animation") {
+ r_ret = animation->animation_track_get_key_animation(track, key);
+ return true;
+ }
+
+ } break;
+ }
+ }
+ }
+
+ return false;
+ }
+ void _get_property_list(List<PropertyInfo> *p_list) const {
+
+ if (animation.is_null())
+ return;
+
+ int first_track = -1;
+ float first_key = -1.0;
+
+ bool show_time = true;
+ bool same_track_type = true;
+ bool same_key_type = true;
+ for (Map<int, List<float> >::Element *E = key_ofs_map.front(); E; E = E->next()) {
+
+ int track = E->key();
+ ERR_FAIL_INDEX(track, animation->get_track_count());
+
+ if (first_track < 0)
+ first_track = track;
+
+ if (show_time && E->value().size() > 1)
+ show_time = false;
+
+ if (same_track_type) {
+
+ if (animation->track_get_type(first_track) != animation->track_get_type(track)) {
+ same_track_type = false;
+ same_key_type = false;
+ }
+
+ for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
+
+ int key = animation->track_find_key(track, F->get(), true);
+ ERR_FAIL_COND(key == -1);
+ if (first_key < 0)
+ first_key = key;
+
+ if (animation->track_get_key_value(first_track, first_key).get_type() != animation->track_get_key_value(track, key).get_type())
+ same_key_type = false;
+ }
+ }
+ }
+
+ if (show_time) {
+
+ if (use_fps && animation->get_step() > 0) {
+ float max_frame = animation->get_length() / animation->get_step();
+ p_list->push_back(PropertyInfo(Variant::REAL, "frame", PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",1"));
+ } else {
+ p_list->push_back(PropertyInfo(Variant::REAL, "time", PROPERTY_HINT_RANGE, "0," + rtos(animation->get_length()) + ",0.01"));
+ }
+ }
+
+ if (same_track_type) {
+ switch (animation->track_get_type(first_track)) {
+
+ case Animation::TYPE_TRANSFORM: {
+
+ p_list->push_back(PropertyInfo(Variant::VECTOR3, "location"));
+ p_list->push_back(PropertyInfo(Variant::QUAT, "rotation"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale"));
+ } break;
+ case Animation::TYPE_VALUE: {
+
+ if (!same_key_type)
+ break;
+
+ Variant v = animation->track_get_key_value(first_track, first_key);
+
+ if (hint.type != Variant::NIL) {
+
+ PropertyInfo pi = hint;
+ pi.name = "value";
+ p_list->push_back(pi);
+ } else {
+
+ PropertyHint hint = PROPERTY_HINT_NONE;
+ String hint_string;
+
+ if (v.get_type() == Variant::OBJECT) {
+ //could actually check the object property if exists..? yes i will!
+ Ref<Resource> res = v;
+ if (res.is_valid()) {
+
+ hint = PROPERTY_HINT_RESOURCE_TYPE;
+ hint_string = res->get_class();
+ }
+ }
+
+ if (v.get_type() != Variant::NIL)
+ p_list->push_back(PropertyInfo(v.get_type(), "value", hint, hint_string));
+ }
+
+ p_list->push_back(PropertyInfo(Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING));
+ } break;
+ case Animation::TYPE_METHOD: {
+
+ p_list->push_back(PropertyInfo(Variant::STRING, "name"));
+ p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,5,1"));
+
+ Dictionary d = animation->track_get_key_value(first_track, first_key);
+ ERR_FAIL_COND(!d.has("args"));
+ Vector<Variant> args = d["args"];
+ String vtypes;
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+
+ if (i > 0)
+ vtypes += ",";
+ vtypes += Variant::get_type_name(Variant::Type(i));
+ }
+
+ for (int i = 0; i < args.size(); i++) {
+
+ p_list->push_back(PropertyInfo(Variant::INT, "args/" + itos(i) + "/type", PROPERTY_HINT_ENUM, vtypes));
+ if (args[i].get_type() != Variant::NIL)
+ p_list->push_back(PropertyInfo(args[i].get_type(), "args/" + itos(i) + "/value"));
+ }
+ } break;
+ case Animation::TYPE_BEZIER: {
+
+ p_list->push_back(PropertyInfo(Variant::REAL, "value"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "in_handle"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "out_handle"));
+ } break;
+ case Animation::TYPE_AUDIO: {
+
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
+ p_list->push_back(PropertyInfo(Variant::REAL, "start_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
+ p_list->push_back(PropertyInfo(Variant::REAL, "end_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
+ } break;
+ case Animation::TYPE_ANIMATION: {
+
+ if (key_ofs_map.size() > 1)
+ break;
+
+ String animations;
+
+ if (root_path && root_path->has_node(animation->track_get_path(first_track))) {
+
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(root_path->get_node(animation->track_get_path(first_track)));
+ if (ap) {
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (List<StringName>::Element *G = anims.front(); G; G = G->next()) {
+ if (animations != String()) {
+ animations += ",";
+ }
+
+ animations += String(G->get());
+ }
+ }
+ }
+
+ if (animations != String()) {
+ animations += ",";
+ }
+ animations += "[stop]";
+
+ p_list->push_back(PropertyInfo(Variant::STRING, "animation", PROPERTY_HINT_ENUM, animations));
+ } break;
+ }
+ }
+ }
+
+ Ref<Animation> animation;
+
+ Map<int, List<float> > key_ofs_map;
+ Map<int, NodePath> base_map;
+ PropertyInfo hint;
+
+ Node *root_path;
+
+ bool use_fps;
+
+ UndoRedo *undo_redo;
+
+ void notify_change() {
+
+ _change_notify();
+ }
+
+ Node *get_root_path() {
+ return root_path;
+ }
+
+ void set_use_fps(bool p_enable) {
+ use_fps = p_enable;
+ _change_notify();
+ }
+
+ AnimationMultiTrackKeyEdit() {
+ use_fps = false;
+ setting = false;
+ root_path = NULL;
+ }
+};
+
void AnimationTimelineEdit::_zoom_changed(double) {
update();
@@ -1045,7 +1748,11 @@ void AnimationTimelineEdit::_play_position_draw() {
if (px >= get_name_limit() && px < (play_position->get_size().width - get_buttons_width())) {
Color color = get_color("accent_color", "Editor");
- play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(EDSCALE));
+ play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE));
+ play_position->draw_texture(
+ get_icon("TimelineIndicator", "EditorIcons"),
+ Point2(px - get_icon("TimelineIndicator", "EditorIcons")->get_width() * 0.5, 0),
+ color);
}
}
@@ -1092,6 +1799,13 @@ void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid()) {
+ if (hsize_rect.has_point(mm->get_position())) {
+ // Change the cursor to indicate that the track name column's width can be adjusted
+ set_default_cursor_shape(Control::CURSOR_HSIZE);
+ } else {
+ set_default_cursor_shape(Control::CURSOR_ARROW);
+ }
+
if (dragging_hsize) {
int ofs = mm->get_position().x - dragging_hsize_from;
name_limit = dragging_hsize_at + ofs;
@@ -1150,7 +1864,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
use_fps = false;
editing = false;
- name_limit = 150;
+ name_limit = 150 * EDSCALE;
zoom = NULL;
play_position_pos = 0;
@@ -1274,12 +1988,7 @@ void AnimationTrackEdit::_notification(int p_what) {
}
text_color.a *= 0.7;
} else if (node) {
- Ref<Texture> icon;
- if (has_icon(node->get_class(), "EditorIcons")) {
- icon = get_icon(node->get_class(), "EditorIcons");
- } else {
- icon = get_icon("Node", "EditorIcons");
- }
+ Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(node, "Node");
draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2));
icon_cache = icon;
@@ -1740,7 +2449,7 @@ void AnimationTrackEdit::_play_position_draw() {
if (px >= timeline->get_name_limit() && px < (get_size().width - timeline->get_buttons_width())) {
Color color = get_color("accent_color", "Editor");
- play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(EDSCALE));
+ play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE));
}
}
@@ -1757,6 +2466,7 @@ void AnimationTrackEdit::update_play_position() {
void AnimationTrackEdit::set_root(Node *p_root) {
root = p_root;
}
+
void AnimationTrackEdit::_zoom_changed() {
update();
play_position->update();
@@ -2486,7 +3196,7 @@ void AnimationTrackEditGroup::_notification(int p_what) {
if (px >= timeline->get_name_limit() && px < (get_size().width - timeline->get_buttons_width())) {
Color accent = get_color("accent_color", "Editor");
- draw_line(Point2(px, 0), Point2(px, get_size().height), accent, Math::round(EDSCALE));
+ draw_line(Point2(px, 0), Point2(px, get_size().height), accent, Math::round(2 * EDSCALE));
}
}
}
@@ -2596,6 +3306,7 @@ Ref<Animation> AnimationTrackEditor::get_current_animation() const {
return animation;
}
+
void AnimationTrackEditor::_root_removed(Node *p_root) {
root = NULL;
}
@@ -2691,15 +3402,14 @@ void AnimationTrackEditor::_track_remove_request(int p_track) {
int idx = p_track;
if (idx >= 0 && idx < animation->get_track_count()) {
- selection.clear();
- _clear_key_edit();
- //all will be updated after remove anyway, and triggering update here raises error on tracks already removed
undo_redo->create_action(TTR("Remove Anim Track"));
+ undo_redo->add_do_method(this, "_clear_selection", false);
undo_redo->add_do_method(animation.ptr(), "remove_track", idx);
undo_redo->add_undo_method(animation.ptr(), "add_track", animation->track_get_type(idx), idx);
undo_redo->add_undo_method(animation.ptr(), "track_set_path", idx, animation->track_get_path(idx));
- //todo interpolation
+
+ // TODO interpolation.
for (int i = 0; i < animation->track_get_key_count(idx); i++) {
Variant v = animation->track_get_key_value(idx, i);
@@ -2760,20 +3470,18 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
if (p_id.track_idx == -1) {
if (bool(EDITOR_DEF("editors/animation/confirm_insert_track", true))) {
//potential new key, does not exist
- if (insert_data.size() == 1)
- insert_confirm_text->set_text(vformat(TTR("Create NEW track for %s and insert key?"), p_id.query));
- else
- insert_confirm_text->set_text(vformat(TTR("Create %d NEW tracks and insert keys?"), insert_data.size()));
-
+ int num_tracks = 0;
bool all_bezier = true;
for (int i = 0; i < insert_data.size(); i++) {
- if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER) {
+ if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER)
all_bezier = false;
- }
- if (insert_data[i].type != Animation::TYPE_VALUE) {
+ if (insert_data[i].track_idx == -1)
+ ++num_tracks;
+
+ if (insert_data[i].type != Animation::TYPE_VALUE)
continue;
- }
+
switch (insert_data[i].value.get_type()) {
case Variant::INT:
case Variant::REAL:
@@ -2782,7 +3490,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
case Variant::QUAT:
case Variant::PLANE:
case Variant::COLOR: {
- //good
+ // Valid.
} break;
default: {
all_bezier = false;
@@ -2790,6 +3498,11 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
}
}
+ if (num_tracks == 1)
+ insert_confirm_text->set_text(vformat(TTR("Create NEW track for %s and insert key?"), p_id.query));
+ else
+ insert_confirm_text->set_text(vformat(TTR("Create %d NEW tracks and insert keys?"), num_tracks));
+
insert_confirm_bezier->set_visible(all_bezier);
insert_confirm->get_ok()->set_text(TTR("Create"));
insert_confirm->popup_centered_minsize();
@@ -2976,16 +3689,20 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
} else if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
Variant value;
- if (animation->track_get_path(i) == np) {
+ String track_path = animation->track_get_path(i);
+ if (track_path == np) {
value = p_value; //all good
} else {
- String tpath = animation->track_get_path(i);
- if (NodePath(tpath.get_basename()) == np) {
- String subindex = tpath.get_extension();
- value = p_value.get(subindex);
- } else {
+ int sep = track_path.find_last(":");
+ if (sep != -1) {
+ String base_path = track_path.substr(0, sep);
+ if (base_path == np) {
+ String value_name = track_path.substr(sep + 1);
+ value = p_value.get(value_name);
+ } else
+ continue;
+ } else
continue;
- }
}
InsertData id;
@@ -3245,33 +3962,30 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
bool created = false;
if (p_id.track_idx < 0) {
- if (p_create_beziers && (p_id.value.get_type() == Variant::VECTOR2 ||
- p_id.value.get_type() == Variant::VECTOR3 ||
- p_id.value.get_type() == Variant::QUAT ||
- p_id.value.get_type() == Variant::COLOR ||
- p_id.value.get_type() == Variant::PLANE)) {
-
- Vector<String> subindices = _get_bezier_subindices_for_type(p_id.value.get_type());
+ if (p_create_beziers) {
+ bool valid;
+ Vector<String> subindices = _get_bezier_subindices_for_type(p_id.value.get_type(), &valid);
+ if (valid) {
+ for (int i = 0; i < subindices.size(); i++) {
+ InsertData id = p_id;
+ id.type = Animation::TYPE_BEZIER;
+ id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
+ id.path = String(p_id.path) + subindices[i];
+ _confirm_insert(id, p_last_track + i);
+ }
- for (int i = 0; i < subindices.size(); i++) {
- InsertData id = p_id;
- id.type = Animation::TYPE_BEZIER;
- id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
- id.path = String(p_id.path) + subindices[i];
- _confirm_insert(id, p_last_track + i);
+ return p_last_track + subindices.size();
}
-
- return p_last_track + subindices.size() - 1;
}
created = true;
undo_redo->create_action(TTR("Anim Insert Track & Key"));
Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
if (p_id.type == Animation::TYPE_VALUE || p_id.type == Animation::TYPE_BEZIER) {
- //wants a new tack
+ // Wants a new track.
{
- //hack
+ // Hack.
NodePath np;
animation->add_track(p_id.type);
animation->track_set_path(animation->get_track_count() - 1, p_id.path);
@@ -3325,7 +4039,7 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
Dictionary d;
d["location"] = tr.origin;
d["scale"] = tr.basis.get_scale();
- d["rotation"] = Quat(tr.basis); //.orthonormalized();
+ d["rotation"] = Quat(tr.basis);
value = d;
} break;
case Animation::TYPE_BEZIER: {
@@ -3350,8 +4064,9 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
if (created) {
- //just remove the track
- undo_redo->add_undo_method(animation.ptr(), "remove_track", p_last_track);
+ // Just remove the track.
+ undo_redo->add_undo_method(this, "_clear_selection", false);
+ undo_redo->add_undo_method(animation.ptr(), "remove_track", animation->get_track_count());
p_last_track++;
} else {
@@ -3370,6 +4085,8 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
}
void AnimationTrackEditor::show_select_node_warning(bool p_show) {
+
+ info_message->set_visible(p_show);
}
bool AnimationTrackEditor::is_key_selected(int p_track, int p_key) const {
@@ -3385,6 +4102,10 @@ bool AnimationTrackEditor::is_selection_active() const {
return selection.size();
}
+bool AnimationTrackEditor::is_snap_enabled() const {
+ return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+}
+
void AnimationTrackEditor::_update_tracks() {
int selected = _get_track_selected();
@@ -3500,9 +4221,7 @@ void AnimationTrackEditor::_update_tracks() {
if (root && root->has_node(base_path)) {
Node *n = root->get_node(base_path);
if (n) {
- if (has_icon(n->get_class(), "EditorIcons")) {
- icon = get_icon(n->get_class(), "EditorIcons");
- }
+ icon = EditorNode::get_singleton()->get_object_icon(n, "Node");
name = n->get_name();
tooltip = root->get_path_to(n);
}
@@ -3873,7 +4592,7 @@ void AnimationTrackEditor::_new_track_property_selected(String p_name) {
for (int i = 0; i < subindices.size(); i++) {
undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type);
undo_redo->add_do_method(animation.ptr(), "track_set_path", base_track + i, full_path + subindices[i]);
- undo_redo->add_undo_method(animation.ptr(), "remove_track", base_track + i);
+ undo_redo->add_undo_method(animation.ptr(), "remove_track", base_track);
}
undo_redo->commit_action();
}
@@ -3950,6 +4669,7 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
undo_redo->create_action(TTR("Add Track Key"));
undo_redo->add_do_method(animation.ptr(), "track_insert_key", p_track, p_ofs, value);
+ undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", p_track, p_ofs);
undo_redo->commit_action();
@@ -4140,21 +4860,33 @@ void AnimationTrackEditor::_clear_key_edit() {
}
#else
//if key edit is the object being inspected, remove it first
- if (EditorNode::get_singleton()->get_inspector()->get_edited_object() == key_edit) {
+ if (EditorNode::get_singleton()->get_inspector()->get_edited_object() == key_edit ||
+ EditorNode::get_singleton()->get_inspector()->get_edited_object() == multi_key_edit) {
EditorNode::get_singleton()->push_item(NULL);
}
+
//then actually delete it
- memdelete(key_edit);
- key_edit = NULL;
+ if (key_edit) {
+ memdelete(key_edit);
+ key_edit = NULL;
+ } else if (multi_key_edit) {
+ memdelete(multi_key_edit);
+ multi_key_edit = NULL;
+ }
#endif
}
}
-void AnimationTrackEditor::_clear_selection() {
+void AnimationTrackEditor::_clear_selection(bool p_update) {
+
selection.clear();
- for (int i = 0; i < track_edits.size(); i++) {
- track_edits[i]->update();
+
+ if (p_update) {
+ for (int i = 0; i < track_edits.size(); i++) {
+ track_edits[i]->update();
+ }
}
+
_clear_key_edit();
}
@@ -4163,38 +4895,70 @@ void AnimationTrackEditor::_update_key_edit() {
_clear_key_edit();
if (!animation.is_valid())
return;
- if (selection.size() != 1) {
- return;
- }
- key_edit = memnew(AnimationTrackKeyEdit);
- key_edit->animation = animation;
- key_edit->track = selection.front()->key().track;
- key_edit->use_fps = timeline->is_using_fps();
+ if (selection.size() == 1) {
+
+ key_edit = memnew(AnimationTrackKeyEdit);
+ key_edit->animation = animation;
+ key_edit->track = selection.front()->key().track;
+ key_edit->use_fps = timeline->is_using_fps();
+
+ float ofs = animation->track_get_key_time(key_edit->track, selection.front()->key().key);
+ key_edit->key_ofs = ofs;
+ key_edit->root_path = root;
+
+ NodePath np;
+ key_edit->hint = _find_hint_for_track(key_edit->track, np);
+ key_edit->undo_redo = undo_redo;
+ key_edit->base = np;
- float ofs = animation->track_get_key_time(key_edit->track, selection.front()->key().key);
- key_edit->key_ofs = ofs;
- key_edit->root_path = root;
+ EditorNode::get_singleton()->push_item(key_edit);
+ } else if (selection.size() > 1) {
- NodePath np;
- key_edit->hint = _find_hint_for_track(key_edit->track, np);
- key_edit->undo_redo = undo_redo;
- key_edit->base = np;
+ multi_key_edit = memnew(AnimationMultiTrackKeyEdit);
+ multi_key_edit->animation = animation;
- EditorNode::get_singleton()->push_item(key_edit);
+ Map<int, List<float> > key_ofs_map;
+ Map<int, NodePath> base_map;
+ int first_track = -1;
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) {
+
+ int track = E->key().track;
+ if (first_track < 0)
+ first_track = track;
+
+ if (!key_ofs_map.has(track)) {
+ key_ofs_map[track] = List<float>();
+ base_map[track] = *memnew(NodePath);
+ }
+
+ key_ofs_map[track].push_back(animation->track_get_key_time(track, E->key().key));
+ }
+ multi_key_edit->key_ofs_map = key_ofs_map;
+ multi_key_edit->base_map = base_map;
+ multi_key_edit->hint = _find_hint_for_track(first_track, base_map[first_track]);
+
+ multi_key_edit->use_fps = timeline->is_using_fps();
+
+ multi_key_edit->root_path = root;
+
+ multi_key_edit->undo_redo = undo_redo;
+
+ EditorNode::get_singleton()->push_item(multi_key_edit);
+ }
}
void AnimationTrackEditor::_clear_selection_for_anim(const Ref<Animation> &p_anim) {
- if (!(animation == p_anim))
+ if (animation != p_anim)
return;
- //selection.clear();
+
_clear_selection();
}
void AnimationTrackEditor::_select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos) {
- if (!(animation == p_anim))
+ if (animation != p_anim)
return;
int idx = animation->track_find_key(p_track, p_pos, true);
@@ -4216,12 +4980,12 @@ void AnimationTrackEditor::_move_selection_commit() {
List<_AnimMoveRestore> to_restore;
float motion = moving_selection_offset;
- // 1-remove the keys
+ // 1 - remove the keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
}
- // 2- remove overlapped keys
+ // 2 - remove overlapped keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newtime = snap_time(E->get().pos + motion);
@@ -4245,35 +5009,27 @@ void AnimationTrackEditor::_move_selection_commit() {
to_restore.push_back(amr);
}
- // 3-move the keys (re insert them)
+ // 3 - move the keys (re insert them)
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = snap_time(E->get().pos + motion);
- /*
- if (newpos<0)
- continue; //no add at the beginning
- */
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
- // 4-(undo) remove inserted keys
+ // 4 - (undo) remove inserted keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float newpos = snap_time(E->get().pos + motion);
- /*
- if (newpos<0)
- continue; //no remove what no inserted
- */
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", E->key().track, newpos);
}
- // 5-(undo) reinsert keys
+ // 5 - (undo) reinsert keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
- // 6-(undo) reinsert overlapped keys
+ // 6 - (undo) reinsert overlapped keys
for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
_AnimMoveRestore &amr = E->get();
@@ -4283,12 +5039,12 @@ void AnimationTrackEditor::_move_selection_commit() {
undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
- // 7-reselect
+ // 7 - reselect
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
float oldpos = E->get().pos;
float newpos = snap_time(oldpos + motion);
- //if (newpos>=0)
+
undo_redo->add_do_method(this, "_select_at_anim", animation, E->key().track, newpos);
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos);
}
@@ -4319,10 +5075,9 @@ float AnimationTrackEditor::get_moving_selection_offset() const {
void AnimationTrackEditor::_box_selection_draw() {
- Color color = get_color("accent_color", "Editor");
- color.a = 0.2;
- Rect2 rect = Rect2(Point2(), box_selection->get_size());
- box_selection->draw_rect(rect, color);
+ const Rect2 selection_rect = Rect2(Point2(), box_selection->get_size());
+ box_selection->draw_rect(selection_rect, get_color("box_selection_fill_color", "Editor"));
+ box_selection->draw_rect(selection_rect, get_color("box_selection_stroke_color", "Editor"), false, Math::round(EDSCALE));
}
void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
@@ -4802,7 +5557,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
undo_redo->commit_action();
- //selection.clear();
_update_key_edit();
}
} break;
@@ -4953,7 +5707,7 @@ void AnimationTrackEditor::_selection_changed() {
float AnimationTrackEditor::snap_time(float p_value) {
- if (snap->is_pressed()) {
+ if (is_snap_enabled()) {
double snap_increment;
if (timeline->is_using_fps() && step->get_value() > 0)
@@ -5053,6 +5807,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
timeline_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
timeline_vbox->add_constant_override("separation", 0);
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ main_panel->add_child(info_message);
+
timeline = memnew(AnimationTimelineEdit);
timeline->set_undo_redo(undo_redo);
timeline_vbox->add_child(timeline);
@@ -5131,7 +5893,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
step = memnew(EditorSpinSlider);
step->set_min(0);
step->set_max(1000000);
- step->set_step(0.01);
+ step->set_step(0.001);
step->set_hide_slider(true);
step->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
step->set_tooltip(TTR("Animation step value."));
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 8dc2304a95..830d5b52d3 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -246,6 +246,7 @@ public:
};
class AnimationTrackKeyEdit;
+class AnimationMultiTrackKeyEdit;
class AnimationBezierTrackEdit;
class AnimationTrackEditGroup : public Control {
@@ -303,6 +304,8 @@ class AnimationTrackEditor : public VBoxContainer {
VBoxContainer *track_vbox;
AnimationBezierTrackEdit *bezier_edit;
+ Label *info_message;
+
AnimationTimelineEdit *timeline;
HSlider *zoom;
EditorSpinSlider *step;
@@ -384,7 +387,7 @@ class AnimationTrackEditor : public VBoxContainer {
void _insert_key_from_track(float p_ofs, int p_track);
void _add_method_key(const String &p_method);
- void _clear_selection();
+ void _clear_selection(bool p_update = false);
void _clear_selection_for_anim(const Ref<Animation> &p_anim);
void _select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos);
@@ -415,6 +418,7 @@ class AnimationTrackEditor : public VBoxContainer {
void _move_selection_cancel();
AnimationTrackKeyEdit *key_edit;
+ AnimationMultiTrackKeyEdit *multi_key_edit;
void _update_key_edit();
void _clear_key_edit();
@@ -518,8 +522,8 @@ public:
bool is_key_selected(int p_track, int p_key) const;
bool is_selection_active() const;
bool is_moving_selection() const;
+ bool is_snap_enabled() const;
float get_moving_selection_offset() const;
- bool is_snap_enabled();
float snap_time(float p_value);
bool is_grouping_tracks();
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 4862d4bb5b..b6cd69c3cd 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -152,6 +152,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
text_edit->cursor_set_line(line, false);
text_edit->cursor_set_column(col + text.length(), false);
text_edit->center_viewport_to_cursor();
+ text_edit->select(line, col, line, col + text.length());
}
text_edit->set_search_text(text);
@@ -162,16 +163,17 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
result_col = col;
_update_results_count();
- set_error(vformat(TTR("Found %d match(es)."), results_count));
} else {
+ results_count = 0;
result_line = -1;
result_col = -1;
text_edit->set_search_text("");
text_edit->set_search_flags(p_flags);
text_edit->set_current_search_result(line, col);
- set_error(text.empty() ? "" : TTR("No Matches"));
}
+ _update_matches_label();
+
return found;
}
@@ -195,7 +197,7 @@ void FindReplaceBar::_replace() {
void FindReplaceBar::_replace_all() {
text_edit->disconnect("text_changed", this, "_editor_text_changed");
- // line as x so it gets priority in comparison, column as y
+ // Line as x so it gets priority in comparison, column as y.
Point2i orig_cursor(text_edit->cursor_get_line(), text_edit->cursor_get_column());
Point2i prev_match = Point2(-1, -1);
@@ -227,7 +229,7 @@ void FindReplaceBar::_replace_all() {
Point2i match_to(result_line, result_col + search_text_len);
if (match_from < prev_match) {
- break; // done
+ break; // Done.
}
prev_match = Point2i(result_line, result_col + replace_text.length());
@@ -240,14 +242,14 @@ void FindReplaceBar::_replace_all() {
continue;
}
- // replace but adjust selection bounds
+ // Replace but adjust selection bounds.
text_edit->insert_text_at_cursor(replace_text);
if (match_to.x == selection_end.x) {
selection_end.y += replace_text.length() - search_text_len;
}
} else {
- // just replace
+ // Just replace.
text_edit->insert_text_at_cursor(replace_text);
}
@@ -259,12 +261,12 @@ void FindReplaceBar::_replace_all() {
replace_all_mode = false;
- // restore editor state (selection, cursor, scroll)
+ // Restore editor state (selection, cursor, scroll).
text_edit->cursor_set_line(orig_cursor.x);
text_edit->cursor_set_column(orig_cursor.y);
if (selection_enabled && is_selection_only()) {
- // reselect
+ // Reselect.
text_edit->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y);
} else {
text_edit->deselect();
@@ -282,20 +284,6 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
r_line = text_edit->cursor_get_line();
r_col = text_edit->cursor_get_column();
- if (text_edit->is_selection_active() && !replace_all_mode) {
-
- int selection_line = text_edit->get_selection_from_line();
-
- if (text_edit->get_selection_text() == get_search_text() && r_line == selection_line) {
-
- int selection_from_col = text_edit->get_selection_from_column();
-
- if (r_col >= selection_from_col && r_col <= text_edit->get_selection_to_column()) {
- r_col = selection_from_col;
- }
- }
- }
-
if (r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) {
r_col = result_col;
}
@@ -331,6 +319,18 @@ void FindReplaceBar::_update_results_count() {
}
}
+void FindReplaceBar::_update_matches_label() {
+
+ if (search_text->get_text().empty() || results_count == -1) {
+ matches_label->hide();
+ } else {
+ matches_label->show();
+
+ matches_label->add_color_override("font_color", results_count > 0 ? Color(1, 1, 1) : EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
+ }
+}
+
bool FindReplaceBar::search_current() {
uint32_t flags = 0;
@@ -348,6 +348,9 @@ bool FindReplaceBar::search_current() {
bool FindReplaceBar::search_prev() {
+ if (!is_visible())
+ popup_search(true);
+
uint32_t flags = 0;
String text = get_search_text();
@@ -360,6 +363,8 @@ bool FindReplaceBar::search_prev() {
int line, col;
_get_search_from(line, col);
+ if (text_edit->is_selection_active())
+ col--; // Skip currently selected word.
col -= text.length();
if (col < 0) {
@@ -374,6 +379,9 @@ bool FindReplaceBar::search_prev() {
bool FindReplaceBar::search_next() {
+ if (!is_visible())
+ popup_search(true);
+
uint32_t flags = 0;
String text;
if (replace_all_mode)
@@ -410,38 +418,54 @@ void FindReplaceBar::_hide_bar() {
text_edit->set_search_text("");
result_line = -1;
result_col = -1;
- set_error("");
hide();
}
-void FindReplaceBar::_show_search() {
+void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
show();
- search_text->call_deferred("grab_focus");
+ if (p_show_only)
+ return;
+
+ if (p_focus_replace) {
+ search_text->deselect();
+ replace_text->call_deferred("grab_focus");
+ } else {
+ replace_text->deselect();
+ search_text->call_deferred("grab_focus");
+ }
if (text_edit->is_selection_active() && !selection_only->is_pressed()) {
search_text->set_text(text_edit->get_selection_text());
}
if (!get_search_text().empty()) {
- search_text->select_all();
- search_text->set_cursor_position(search_text->get_text().length());
- search_current();
+ if (p_focus_replace) {
+ replace_text->select_all();
+ replace_text->set_cursor_position(replace_text->get_text().length());
+ } else {
+ search_text->select_all();
+ search_text->set_cursor_position(search_text->get_text().length());
+ }
+
+ results_count = -1;
+ _update_results_count();
+ _update_matches_label();
}
}
-void FindReplaceBar::popup_search() {
+void FindReplaceBar::popup_search(bool p_show_only) {
- replace_text->hide();
+ if (!is_visible())
+ replace_text->hide();
hbc_button_replace->hide();
hbc_option_replace->hide();
- _show_search();
+ _show_search(false, p_show_only);
}
void FindReplaceBar::popup_replace() {
if (!replace_text->is_visible_in_tree()) {
- replace_text->clear();
replace_text->show();
hbc_button_replace->show();
hbc_option_replace->show();
@@ -449,7 +473,7 @@ void FindReplaceBar::popup_replace() {
selection_only->set_pressed((text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()));
- _show_search();
+ _show_search(is_visible() || text_edit->is_selection_active());
}
void FindReplaceBar::_search_options_changed(bool p_pressed) {
@@ -556,6 +580,7 @@ FindReplaceBar::FindReplaceBar() {
vbc_lineedit = memnew(VBoxContainer);
add_child(vbc_lineedit);
+ vbc_lineedit->set_alignment(ALIGN_CENTER);
vbc_lineedit->set_h_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *vbc_button = memnew(VBoxContainer);
add_child(vbc_button);
@@ -564,8 +589,10 @@ FindReplaceBar::FindReplaceBar() {
HBoxContainer *hbc_button_search = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_search);
+ hbc_button_search->set_alignment(ALIGN_END);
hbc_button_replace = memnew(HBoxContainer);
vbc_button->add_child(hbc_button_replace);
+ hbc_button_replace->set_alignment(ALIGN_END);
HBoxContainer *hbc_option_search = memnew(HBoxContainer);
vbc_option->add_child(hbc_option_search);
@@ -579,6 +606,10 @@ FindReplaceBar::FindReplaceBar() {
search_text->connect("text_changed", this, "_search_text_changed");
search_text->connect("text_entered", this, "_search_text_entered");
+ matches_label = memnew(Label);
+ hbc_button_search->add_child(matches_label);
+ matches_label->hide();
+
find_prev = memnew(ToolButton);
hbc_button_search->add_child(find_prev);
find_prev->set_focus_mode(FOCUS_NONE);
@@ -719,7 +750,7 @@ void CodeTextEditor::_zoom_changed() {
}
void CodeTextEditor::_reset_zoom() {
- Ref<DynamicFont> font = text_editor->get_font("font"); // reset source font size to default
+ Ref<DynamicFont> font = text_editor->get_font("font"); // Reset source font size to default.
if (font.is_valid()) {
EditorSettings::get_singleton()->set("interface/editor/code_font_size", 14);
@@ -854,31 +885,33 @@ bool CodeTextEditor::_add_font_size(int p_delta) {
void CodeTextEditor::update_editor_settings() {
- text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
- text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
+ text_editor->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
+ text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences"));
+ text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type"));
text_editor->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
text_editor->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent"));
text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
text_editor->set_draw_spaces(EditorSettings::get_singleton()->get("text_editor/indent/draw_spaces"));
- text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
- text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded"));
- text_editor->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_length_guideline"));
- text_editor->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_length_guideline_column"));
- text_editor->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
- text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences"));
- text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
+ text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/navigation/smooth_scrolling"));
+ text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/navigation/v_scroll_speed"));
+ text_editor->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/navigation/show_minimap"));
+ text_editor->set_minimap_width(EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width"));
+ text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers"));
+ text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/appearance/line_numbers_zero_padded"));
+ text_editor->set_bookmark_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/show_bookmark_gutter"));
+ text_editor->set_breakpoint_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/show_breakpoint_gutter"));
+ text_editor->set_draw_info_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/show_info_gutter"));
+ text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
+ text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/appearance/code_folding"));
+ text_editor->set_wrap_enabled(EditorSettings::get_singleton()->get("text_editor/appearance/word_wrap"));
+ text_editor->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guideline"));
+ text_editor->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_column"));
+ text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
+ text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
- text_editor->set_bookmark_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_bookmark_gutter"));
- text_editor->set_breakpoint_gutter_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter"));
- text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
- text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
- text_editor->set_wrap_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/word_wrap"));
- text_editor->set_draw_info_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_info_gutter"));
- text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
- text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
- text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
+ text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
}
void CodeTextEditor::trim_trailing_whitespace() {
@@ -1229,7 +1262,7 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
int col_to = text_editor->get_selection_to_column();
int cursor_pos = text_editor->cursor_get_column();
- // Check if all lines in the selected block are commented
+ // Check if all lines in the selected block are commented.
bool is_commented = true;
for (int i = begin; i <= end; i++) {
if (!text_editor->get_line(i).begins_with(delimiter)) {
@@ -1424,19 +1457,19 @@ void CodeTextEditor::_on_settings_change() {
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
- // AUTO BRACE COMPLETION
+ // Auto brace completion.
text_editor->set_auto_brace_completion(
- EDITOR_DEF("text_editor/completion/auto_brace_complete", true));
+ EDITOR_GET("text_editor/completion/auto_brace_complete"));
code_complete_timer->set_wait_time(
- EDITOR_DEF("text_editor/completion/code_complete_delay", .3f));
+ EDITOR_GET("text_editor/completion/code_complete_delay"));
- // call hint settings
+ // Call hint settings.
text_editor->set_callhint_settings(
- EDITOR_DEF("text_editor/completion/put_callhint_tooltip_below_current_line", true),
- EDITOR_DEF("text_editor/completion/callhint_tooltip_offset", Vector2()));
+ EDITOR_GET("text_editor/completion/put_callhint_tooltip_below_current_line"),
+ EDITOR_GET("text_editor/completion/callhint_tooltip_offset"));
- idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay", 2.0));
+ idle->set_wait_time(EDITOR_GET("text_editor/completion/idle_parse_delay"));
}
void CodeTextEditor::_text_changed_idle_timeout() {
@@ -1622,12 +1655,12 @@ CodeTextEditor::CodeTextEditor() {
idle = memnew(Timer);
add_child(idle);
idle->set_one_shot(true);
- idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay", 2.0));
+ idle->set_wait_time(EDITOR_GET("text_editor/completion/idle_parse_delay"));
code_complete_timer = memnew(Timer);
add_child(code_complete_timer);
code_complete_timer->set_one_shot(true);
- code_complete_timer->set_wait_time(EDITOR_DEF("text_editor/completion/code_complete_delay", .3f));
+ code_complete_timer->set_wait_time(EDITOR_GET("text_editor/completion/code_complete_delay"));
error_line = 0;
error_column = 0;
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 700e72627c..f2a55cfb70 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -64,6 +64,7 @@ class FindReplaceBar : public HBoxContainer {
GDCLASS(FindReplaceBar, HBoxContainer);
LineEdit *search_text;
+ Label *matches_label;
ToolButton *find_prev;
ToolButton *find_next;
CheckBox *case_sensitive;
@@ -90,8 +91,9 @@ class FindReplaceBar : public HBoxContainer {
void _get_search_from(int &r_line, int &r_col);
void _update_results_count();
+ void _update_matches_label();
- void _show_search();
+ void _show_search(bool p_focus_replace = false, bool p_show_only = false);
void _hide_bar();
void _editor_text_changed();
@@ -123,7 +125,7 @@ public:
void set_text_edit(TextEdit *p_text_edit);
- void popup_search();
+ void popup_search(bool p_show_only = false);
void popup_replace();
bool search_current();
diff --git a/editor/collada/collada.cpp b/editor/collada/collada.cpp
index 57c00e1bef..e38171eef9 100644
--- a/editor/collada/collada.cpp
+++ b/editor/collada/collada.cpp
@@ -28,8 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef TOOLS_ENABLED
-
#include "collada.h"
#include <stdio.h>
@@ -618,7 +616,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
if (colorarr.size() >= 3) {
- // alpha strangely not allright? maybe it needs to be multiplied by value as a channel intensity
+ // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
if (what == "diffuse")
effect.diffuse.color = color;
@@ -856,7 +854,7 @@ void Collada::_parse_light(XMLParser &parser) {
COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
if (colorarr.size() >= 4) {
- // alpha strangely not allright? maybe it needs to be multiplied by value as a channel intensity
+ // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
light.color = color;
}
@@ -1696,7 +1694,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
}
- } else if (section == "node") {
+ } else {
/* Found a child node!! what to do..*/
@@ -1903,8 +1901,7 @@ void Collada::_parse_animation(XMLParser &parser) {
Vector<float> &output = float_sources[output_id];
- ERR_EXPLAIN("Wrong number of keys in output");
- ERR_CONTINUE((output.size() / stride) != key_count);
+ ERR_CONTINUE_MSG((output.size() / stride) != key_count, "Wrong number of keys in output.");
for (int j = 0; j < key_count; j++) {
track.keys.write[j].data.resize(output_len);
@@ -2300,7 +2297,7 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
//replace parent by this...
Node *parent = node->parent;
- //i wonder if this is allright.. i think it is since created skeleton (first joint) is already animated by bone..
+ //i wonder if this is alright.. i think it is since created skeleton (first joint) is already animated by bone..
node->id = parent->id;
node->name = parent->name;
node->xform_list = parent->xform_list;
@@ -2447,8 +2444,7 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
state.morph_ownership_map[base] = nj->id;
break;
} else {
- ERR_EXPLAIN("Invalid scene");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid scene.");
}
}
}
@@ -2578,5 +2574,3 @@ Error Collada::load(const String &p_path, int p_flags) {
Collada::Collada() {
}
-
-#endif
diff --git a/editor/collada/collada.h b/editor/collada/collada.h
index 9ed62b46b7..317c3f1d37 100644
--- a/editor/collada/collada.h
+++ b/editor/collada/collada.h
@@ -28,8 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef TOOLS_ENABLED
-
#ifndef COLLADA_H
#define COLLADA_H
@@ -647,5 +645,3 @@ private: // private stuff
};
#endif // COLLADA_H
-
-#endif
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 48bc409b73..cfc2ec11cf 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -529,7 +529,7 @@ void ConnectionsDock::_make_or_edit_connection() {
// Pick up args here before "it" is deleted by update_tree.
script_function_args = it->get_metadata(0).operator Dictionary()["args"];
for (int i = 0; i < cToMake.binds.size(); i++) {
- script_function_args.append("extra_arg_" + itos(i));
+ script_function_args.append("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cToMake.binds[i].get_type()));
}
}
@@ -881,7 +881,6 @@ void ConnectionsDock::update_tree() {
icon = get_icon(scr->get_class(), "EditorIcons");
}
}
-
} else {
ClassDB::get_signal_list(base, &node_signals2, true);
@@ -891,6 +890,10 @@ void ConnectionsDock::update_tree() {
name = base;
}
+ if (!icon.is_valid()) {
+ icon = get_icon("Object", "EditorIcons");
+ }
+
TreeItem *pitem = NULL;
if (node_signals2.size()) {
@@ -939,7 +942,7 @@ void ConnectionsDock::update_tree() {
item->set_metadata(0, sinfo);
item->set_icon(0, get_icon("Signal", "EditorIcons"));
- // Set tooltip with the signal's documentation
+ // Set tooltip with the signal's documentation.
{
String descr;
bool found = false;
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 8a8d52c6f1..d5f0dc01ee 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -191,34 +191,41 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
} else if (!(*to_select && (*to_select)->get_text(0) == search_box->get_text())) {
- bool current_type_prefered = _is_type_prefered(p_type);
- bool selected_type_prefered = *to_select ? _is_type_prefered((*to_select)->get_text(0).split(" ")[0]) : false;
-
String search_term = search_box->get_text().to_lower();
- bool is_subsequence_of_type = search_box->get_text().is_subsequence_ofi(p_type);
- bool is_substring_of_type = p_type.to_lower().find(search_term) >= 0;
- bool is_substring_of_selected = false;
- bool is_subsequence_of_selected = false;
- bool is_selected_equal = false;
-
- if (*to_select) {
- String name = (*to_select)->get_text(0).split(" ")[0].to_lower();
- is_substring_of_selected = name.find(search_term) >= 0;
- is_subsequence_of_selected = search_term.is_subsequence_of(name);
- is_selected_equal = name == search_term;
- }
- if (is_subsequence_of_type && !is_selected_equal) {
- if (is_substring_of_type) {
- 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 || (current_type_prefered && !selected_type_prefered)) {
+ // if the node name matches exactly as the search, the node should be selected.
+ // this also fixes when the user clicks on recent nodes.
+ if (p_type.to_lower() == search_term) {
+ *to_select = item;
+ } else {
+ bool current_type_prefered = _is_type_prefered(p_type);
+ bool selected_type_prefered = *to_select ? _is_type_prefered((*to_select)->get_text(0).split(" ")[0]) : false;
+
+ bool is_subsequence_of_type = search_box->get_text().is_subsequence_ofi(p_type);
+ bool is_substring_of_type = p_type.to_lower().find(search_term) >= 0;
+ bool is_substring_of_selected = false;
+ bool is_subsequence_of_selected = false;
+ bool is_selected_equal = false;
+
+ if (*to_select) {
+ String name = (*to_select)->get_text(0).split(" ")[0].to_lower();
+ is_substring_of_selected = name.find(search_term) >= 0;
+ is_subsequence_of_selected = search_term.is_subsequence_of(name);
+ is_selected_equal = name == search_term;
+ }
+
+ if (is_subsequence_of_type && !is_selected_equal) {
+ if (is_substring_of_type) {
+ 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 || (current_type_prefered && !selected_type_prefered)) {
+ *to_select = item;
+ }
+ }
}
}
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f6c3b57589..f3ed1d7af6 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -38,9 +38,6 @@
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CreateDialog : public ConfirmationDialog {
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index a8ba54d4f8..0f99e2ba1e 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;
@@ -720,8 +720,7 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
methods.push_back(method);
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + parser->get_node_name());
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + parser->get_node_name() + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == section)
@@ -741,10 +740,9 @@ Error DocData::load_classes(const String &p_dir) {
da->list_dir_begin();
String path;
- bool isdir;
- path = da->get_next(&isdir);
+ path = da->get_next();
while (path != String()) {
- if (!isdir && path.ends_with("xml")) {
+ if (!da->current_is_dir() && path.ends_with("xml")) {
Ref<XMLParser> parser = memnew(XMLParser);
Error err2 = parser->open(p_dir.plus_file(path));
if (err2)
@@ -752,7 +750,7 @@ Error DocData::load_classes(const String &p_dir) {
_load(parser);
}
- path = da->get_next(&isdir);
+ path = da->get_next();
}
da->list_dir_end();
@@ -771,13 +769,12 @@ Error DocData::erase_classes(const String &p_dir) {
da->list_dir_begin();
String path;
- bool isdir;
- path = da->get_next(&isdir);
+ path = da->get_next();
while (path != String()) {
- if (!isdir && path.ends_with("xml")) {
+ if (!da->current_is_dir() && path.ends_with("xml")) {
to_erase.push_back(path);
}
- path = da->get_next(&isdir);
+ path = da->get_next();
}
da->list_dir_end();
@@ -843,8 +840,7 @@ Error DocData::_load(Ref<XMLParser> parser) {
if (parser->get_node_type() == XMLParser::NODE_TEXT)
c.tutorials.push_back(parser->get_node_data().strip_edges());
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + name3);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "tutorials")
break; //end of <tutorials>
@@ -885,8 +881,7 @@ Error DocData::_load(Ref<XMLParser> parser) {
prop2.description = parser->get_node_data();
c.properties.push_back(prop2);
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + name3);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "members")
@@ -914,8 +909,7 @@ Error DocData::_load(Ref<XMLParser> parser) {
prop2.description = parser->get_node_data();
c.theme_properties.push_back(prop2);
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + name3);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "theme_items")
@@ -945,8 +939,7 @@ Error DocData::_load(Ref<XMLParser> parser) {
constant2.description = parser->get_node_data();
c.constants.push_back(constant2);
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + name3);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "constants")
@@ -955,8 +948,7 @@ Error DocData::_load(Ref<XMLParser> parser) {
} else {
- ERR_EXPLAIN("Invalid tag in doc file: " + name2);
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name2 + ".");
}
} else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "class")
@@ -993,10 +985,8 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
Error err;
String save_file = save_path.plus_file(c.name + ".xml");
FileAccessRef f = FileAccess::open(save_file, FileAccess::WRITE, &err);
- if (err) {
- ERR_EXPLAIN("Can't write doc file: " + save_file);
- ERR_CONTINUE(err);
- }
+
+ ERR_CONTINUE_MSG(err != OK, "Can't write doc file: " + save_file + ".");
_write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index bea1980b09..b2567249d8 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -181,14 +181,14 @@ EditorAbout::EditorAbout() {
// Thirdparty License
VBoxContainer *license_thirdparty = memnew(VBoxContainer);
- license_thirdparty->set_name(TTR("Thirdparty License"));
+ license_thirdparty->set_name(TTR("Third-party Licenses"));
license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL);
tc->add_child(license_thirdparty);
Label *tpl_label = memnew(Label);
tpl_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
tpl_label->set_autowrap(true);
- tpl_label->set_text(TTR("Godot Engine relies on a number of thirdparty free and open source libraries, all compatible with the terms of its MIT license. The following is an exhaustive list of all such thirdparty components with their respective copyright statements and license terms."));
+ tpl_label->set_text(TTR("Godot Engine relies on a number of third-party free and open source libraries, all compatible with the terms of its MIT license. The following is an exhaustive list of all such third-party components with their respective copyright statements and license terms."));
tpl_label->set_size(Size2(630, 1) * EDSCALE);
license_thirdparty->add_child(tpl_label);
diff --git a/editor/editor_about.h b/editor/editor_about.h
index 87e824083e..e2ba366c65 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -43,9 +43,6 @@
#include "scene/gui/tree.h"
#include "editor_scale.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class EditorAbout : public AcceptDialog {
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 12df91a501..98e670f952 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -90,7 +90,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io);
if (!pkg) {
- error->set_text(TTR("Error opening package file, not in zip format."));
+ error->set_text(TTR("Error opening package file, not in ZIP format."));
return;
}
@@ -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");
@@ -221,7 +217,7 @@ void EditorAssetInstaller::ok_pressed() {
unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io);
if (!pkg) {
- error->set_text(TTR("Error opening package file, not in zip format."));
+ error->set_text(TTR("Error opening package file, not in ZIP format."));
return;
}
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 2180742bbb..31095b1100 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -31,6 +31,7 @@
#include "editor_audio_buses.h"
#include "core/io/resource_saver.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "editor_node.h"
#include "filesystem_dock.h"
@@ -321,7 +322,13 @@ void EditorAudioBus::_volume_changed(float p_normalized) {
updating_bus = true;
- float p_db = this->_normalized_volume_to_scaled_db(p_normalized);
+ const float p_db = this->_normalized_volume_to_scaled_db(p_normalized);
+
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ // Snap the value when holding Ctrl for easier editing.
+ // To do so, it needs to be converted back to normalized volume (as the slider uses that unit).
+ slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db)));
+ }
UndoRedo *ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Audio Bus Volume"), UndoRedo::MERGE_ENDS);
@@ -376,14 +383,24 @@ float EditorAudioBus::_scaled_db_to_normalized_volume(float db) {
}
void EditorAudioBus::_show_value(float slider_value) {
- String text = vformat("%10.1f dB", _normalized_volume_to_scaled_db(slider_value));
+ float db;
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ // Display the correct (snapped) value when holding Ctrl
+ db = Math::round(_normalized_volume_to_scaled_db(slider_value));
+ } else {
+ db = _normalized_volume_to_scaled_db(slider_value);
+ }
+
+ String text = vformat("%10.1f dB", db);
+
+ slider->set_tooltip(text);
audio_value_preview_label->set_text(text);
Vector2 slider_size = slider->get_size();
Vector2 slider_position = slider->get_global_position();
float left_padding = 5.0f;
float vert_padding = 10.0f;
- Vector2 box_position = Vector2(slider_size.x + left_padding, (slider_size.y - vert_padding) * (1.0f - slider_value) - vert_padding);
+ Vector2 box_position = Vector2(slider_size.x + left_padding, (slider_size.y - vert_padding) * (1.0f - slider->get_value()) - vert_padding);
audio_value_preview_box->set_position(slider_position + box_position);
audio_value_preview_box->set_size(audio_value_preview_label->get_size());
if (slider->has_focus() && !audio_value_preview_box->is_visible()) {
@@ -773,7 +790,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
is_master = p_is_master;
hovering_drop = false;
- set_tooltip(TTR("Audio Bus, Drag and Drop to rearrange."));
+ set_tooltip(TTR("Drag & drop to rearrange."));
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
@@ -1439,7 +1456,7 @@ Size2 EditorAudioMeterNotches::get_minimum_size() const {
float width = 0;
float height = top_padding + btm_padding;
- for (uint8_t i = 0; i < notches.size(); i++) {
+ for (int i = 0; i < notches.size(); i++) {
if (notches[i].render_db_value) {
width = MAX(width, font->get_string_size(String::num(Math::abs(notches[i].db_value)) + "dB").x);
height += font_height;
@@ -1473,7 +1490,7 @@ void EditorAudioMeterNotches::_draw_audio_notches() {
Ref<Font> font = get_font("font", "Label");
float font_height = font->get_height();
- for (uint8_t i = 0; i < notches.size(); i++) {
+ for (int i = 0; i < notches.size(); i++) {
AudioNotch n = notches[i];
draw_line(Vector2(0, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding),
Vector2(line_length, (1.0f - n.relative_position) * (get_size().y - btm_padding - top_padding) + top_padding),
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 7210211d90..f44e1b7b14 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -315,8 +315,7 @@ void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
RES res = ResourceLoader::load(p_path);
- ERR_EXPLAIN("Can't autoload: " + p_path);
- ERR_FAIL_COND_V(res.is_null(), NULL);
+ ERR_FAIL_COND_V_MSG(res.is_null(), NULL, "Can't autoload: " + p_path + ".");
Node *n = NULL;
if (res->is_class("PackedScene")) {
Ref<PackedScene> ps = res;
@@ -325,20 +324,17 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
Ref<Script> s = res;
StringName ibt = s->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
- ERR_EXPLAIN("Script does not inherit a Node: " + p_path);
- ERR_FAIL_COND_V(!valid_type, NULL);
+ ERR_FAIL_COND_V_MSG(!valid_type, NULL, "Script does not inherit a Node: " + p_path + ".");
Object *obj = ClassDB::instance(ibt);
- ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
- ERR_FAIL_COND_V(obj == NULL, NULL);
+ ERR_FAIL_COND_V_MSG(obj == NULL, NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + ".");
n = Object::cast_to<Node>(obj);
n->set_script(s.get_ref_ptr());
}
- ERR_EXPLAIN("Path in autoload not a node or script: " + p_path);
- ERR_FAIL_COND_V(!n, NULL);
+ ERR_FAIL_COND_V_MSG(!n, NULL, "Path in autoload not a node or script: " + p_path + ".");
return n;
}
@@ -443,11 +439,11 @@ void EditorAutoloadSettings::update_autoload() {
}
if (info.in_editor) {
ERR_CONTINUE(!info.node);
- get_tree()->get_root()->remove_child(info.node);
+ get_tree()->get_root()->call_deferred("remove_child", info.node);
}
if (info.node) {
- memdelete(info.node);
+ info.node->queue_delete();
info.node = NULL;
}
}
diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h
index 76ce020d8a..1ea2950df4 100644
--- a/editor/editor_autoload_settings.h
+++ b/editor/editor_autoload_settings.h
@@ -56,7 +56,7 @@ class EditorAutoloadSettings : public VBoxContainer {
int order;
Node *node;
- bool operator==(const AutoLoadInfo &p_info) {
+ bool operator==(const AutoLoadInfo &p_info) const {
return order == p_info.order;
}
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_data.cpp b/editor/editor_data.cpp
index 38f30df169..c98635d16b 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -499,7 +499,6 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i
for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) {
if (get_custom_types()[p_inherits][i].name == p_type) {
- Ref<Texture> icon = get_custom_types()[p_inherits][i].icon;
Ref<Script> script = get_custom_types()[p_inherits][i].script;
Object *ob = ClassDB::instance(p_inherits);
@@ -508,8 +507,6 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i
ob->call("set_name", p_type);
}
ob->set_script(script.get_ref_ptr());
- if (icon.is_valid())
- ob->set_meta("_editor_icon", icon);
return ob;
}
}
@@ -540,6 +537,7 @@ int EditorData::add_edited_scene(int p_at_pos) {
p_at_pos = edited_scene.size();
EditedScene es;
es.root = NULL;
+ es.path = String();
es.history_current = -1;
es.version = 0;
es.live_edit_root = NodePath(String("/root"));
@@ -656,6 +654,8 @@ bool EditorData::check_and_update_scene(int p_idx) {
memdelete(edited_scene[p_idx].root);
edited_scene.write[p_idx].root = new_scene;
+ if (new_scene->get_filename() != "")
+ edited_scene.write[p_idx].path = new_scene->get_filename();
edited_scene.write[p_idx].selection = new_selection;
return true;
@@ -687,6 +687,12 @@ void EditorData::set_edited_scene_root(Node *p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
edited_scene.write[current_edited_scene].root = p_root;
+ if (p_root) {
+ if (p_root->get_filename() != "")
+ edited_scene.write[current_edited_scene].path = p_root->get_filename();
+ else
+ p_root->set_filename(edited_scene[current_edited_scene].path);
+ }
}
int EditorData::get_edited_scene_count() const {
@@ -776,6 +782,7 @@ String EditorData::get_scene_title(int p_idx) const {
void EditorData::set_scene_path(int p_idx, const String &p_path) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
+ edited_scene.write[p_idx].path = p_path;
if (!edited_scene[p_idx].root)
return;
@@ -786,9 +793,14 @@ String EditorData::get_scene_path(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
- if (!edited_scene[p_idx].root)
- return "";
- return edited_scene[p_idx].root->get_filename();
+ if (edited_scene[p_idx].root) {
+ if (edited_scene[p_idx].root->get_filename() == "")
+ edited_scene[p_idx].root->set_filename(edited_scene[p_idx].path);
+ else
+ return edited_scene[p_idx].root->get_filename();
+ }
+
+ return edited_scene[p_idx].path;
}
void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 845878e070..df83135942 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -117,6 +117,7 @@ public:
struct EditedScene {
Node *root;
+ String path;
Dictionary editor_states;
List<Node *> selection;
Vector<EditorHistory::History> history_stored;
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index ed262d9c4f..e58c7c992a 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -30,11 +30,12 @@
#include "editor_export.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/config_file.h"
#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/dir_access.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/script_language.h"
@@ -147,6 +148,12 @@ String EditorExportPreset::get_include_filter() const {
void EditorExportPreset::set_export_path(const String &p_path) {
export_path = p_path;
+ /* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path,
+ * this should be removed. */
+ if (export_path.is_abs_path()) {
+ String res_path = OS::get_singleton()->get_resource_dir();
+ export_path = res_path.path_to_file(export_path);
+ }
EditorExport::singleton->save_presets();
}
@@ -884,6 +891,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file);
ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list);
Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
+ DirAccess::remove_file_or_error(engine_cfb);
p_func(p_udata, "res://" + config_file, data, idx, total);
@@ -916,8 +924,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
memdelete(ftmp); //close tmp file
- if (err)
+ if (err != OK) {
+ DirAccess::remove_file_or_error(tmppath);
return err;
+ }
pd.file_ofs.sort(); //do sort, so we can do binary search later
@@ -926,11 +936,17 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
if (!p_embed) {
// Regular output to separate PCK file
f = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
+ if (!f) {
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V(ERR_CANT_CREATE);
+ }
} else {
// Append to executable
f = FileAccess::open(p_path, FileAccess::READ_WRITE);
- ERR_FAIL_COND_V(!f, ERR_FILE_CANT_OPEN);
+ if (!f) {
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V(ERR_FILE_CANT_OPEN);
+ }
f->seek_end();
embed_pos = f->get_position();
@@ -995,13 +1011,13 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
f->store_8(0);
}
- //save the rest of the data
+ // Save the rest of the data.
ftmp = FileAccess::open(tmppath, FileAccess::READ);
if (!ftmp) {
memdelete(f);
- ERR_EXPLAIN("Can't open file to read from path: " + String(tmppath));
- ERR_FAIL_V(ERR_CANT_CREATE);
+ DirAccess::remove_file_or_error(tmppath);
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open file to read from path: " + String(tmppath) + ".");
}
const int bufsize = 16384;
@@ -1035,6 +1051,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
}
memdelete(f);
+ DirAccess::remove_file_or_error(tmppath);
return OK;
}
@@ -1043,8 +1060,6 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
EditorProgress ep("savezip", TTR("Packing"), 102, true);
- //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE);
-
FileAccess *src_f;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io);
@@ -1694,11 +1709,18 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con
bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export");
if (!convert)
return;
- String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("file.res");
+ String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpfile.res");
Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path);
- ERR_FAIL_COND(err != OK);
+ if (err != OK) {
+ DirAccess::remove_file_or_error(tmp_path);
+ ERR_FAIL();
+ }
Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path);
- ERR_FAIL_COND(data.size() == 0);
+ if (data.size() == 0) {
+ DirAccess::remove_file_or_error(tmp_path);
+ ERR_FAIL();
+ }
+ DirAccess::remove_file_or_error(tmp_path);
add_file(p_path + ".converted.res", data, true);
}
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 24c5a788b6..80aeeef868 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "editor_file_dialog.h"
+
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -256,6 +257,7 @@ void EditorFileDialog::_post_popup() {
if (is_visible_in_tree()) {
Ref<Texture> folder = get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder_icon_modulate", "FileDialog");
recent->clear();
bool res = access == ACCESS_RESOURCES;
@@ -273,6 +275,7 @@ void EditorFileDialog::_post_popup() {
recent->add_item(name, folder);
recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
+ recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
}
local_history.clear();
@@ -679,7 +682,12 @@ void EditorFileDialog::update_file_name() {
String filter_str = filters[idx];
String file_str = file->get_text();
String base_name = file_str.get_basename();
- file_str = base_name + "." + filter_str.split(";")[1].strip_edges().to_lower();
+ Vector<String> filter_substr = filter_str.split(";");
+ if (filter_substr.size() >= 2) {
+ file_str = base_name + "." + filter_substr[1].strip_edges().to_lower();
+ } else {
+ file_str = base_name + "." + filter_str.get_extension().strip_edges().to_lower();
+ }
file->set_text(file_str);
}
}
@@ -728,22 +736,19 @@ void EditorFileDialog::update_file_list() {
dir_access->list_dir_begin();
Ref<Texture> folder = get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder_icon_modulate", "FileDialog");
List<String> files;
List<String> dirs;
- bool is_dir;
- bool is_hidden;
String item;
- while ((item = dir_access->get_next(&is_dir)) != "") {
+ while ((item = dir_access->get_next()) != "") {
if (item == "." || item == "..")
continue;
- is_hidden = dir_access->current_is_hidden();
-
- if (show_hidden_files || !is_hidden) {
- if (!is_dir)
+ if (show_hidden_files || !dir_access->current_is_hidden()) {
+ if (!dir_access->current_is_dir())
files.push_back(item);
else
dirs.push_back(item);
@@ -772,6 +777,7 @@ void EditorFileDialog::update_file_list() {
d["dir"] = true;
item_list->set_item_metadata(item_list->get_item_count() - 1, d);
+ item_list->set_item_icon_modulate(item_list->get_item_count() - 1, folder_color);
dirs.pop_front();
}
@@ -1198,6 +1204,7 @@ void EditorFileDialog::_update_favorites() {
String current = get_current_dir();
Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons");
+ const Color folder_color = get_color("folder_icon_modulate", "FileDialog");
favorites->clear();
favorite->set_pressed(false);
@@ -1228,6 +1235,7 @@ void EditorFileDialog::_update_favorites() {
}
favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]);
+ favorites->set_item_icon_modulate(favorites->get_item_count() - 1, folder_color);
if (setthis) {
favorite->set_pressed(true);
@@ -1507,9 +1515,9 @@ EditorFileDialog::EditorFileDialog() {
HBoxContainer *pathhb = memnew(HBoxContainer);
dir_prev = memnew(ToolButton);
- dir_prev->set_tooltip(TTR("Previous Folder"));
+ dir_prev->set_tooltip(TTR("Go to previous folder."));
dir_next = memnew(ToolButton);
- dir_next->set_tooltip(TTR("Next Folder"));
+ dir_next->set_tooltip(TTR("Go to next folder."));
dir_up = memnew(ToolButton);
dir_up->set_tooltip(TTR("Go to parent folder."));
@@ -1528,7 +1536,7 @@ EditorFileDialog::EditorFileDialog() {
dir->set_h_size_flags(SIZE_EXPAND_FILL);
refresh = memnew(ToolButton);
- refresh->set_tooltip(TTR("Refresh"));
+ refresh->set_tooltip(TTR("Refresh files."));
refresh->connect("pressed", this, "_update_file_list");
pathhb->add_child(refresh);
@@ -1541,7 +1549,7 @@ EditorFileDialog::EditorFileDialog() {
show_hidden = memnew(ToolButton);
show_hidden->set_toggle_mode(true);
show_hidden->set_pressed(is_showing_hidden_files());
- show_hidden->set_tooltip(TTR("Toggle visibility of hidden files."));
+ show_hidden->set_tooltip(TTR("Toggle the visibility of hidden files."));
show_hidden->connect("toggled", this, "set_show_hidden_files");
pathhb->add_child(show_hidden);
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index 86bf0f0eb3..2ecfa7db15 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -44,9 +44,6 @@
class DependencyRemoveDialog;
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class EditorFileDialog : public ConfirmationDialog {
GDCLASS(EditorFileDialog, ConfirmationDialog);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 87a37acac6..6d3377a85b 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -673,12 +673,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
da->list_dir_begin();
while (true) {
- bool isdir;
- String f = da->get_next(&isdir);
+ String f = da->get_next();
if (f == "")
break;
- if (isdir) {
+ if (da->current_is_dir()) {
if (f.begins_with(".")) //ignore hidden and . / ..
continue;
@@ -870,12 +869,11 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
da->list_dir_begin();
while (true) {
- bool isdir;
- String f = da->get_next(&isdir);
+ String f = da->get_next();
if (f == "")
break;
- if (isdir) {
+ if (da->current_is_dir()) {
if (f.begins_with(".")) //ignore hidden and . / ..
continue;
@@ -1932,8 +1930,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
Error err = da->make_dir(".import");
if (err) {
memdelete(da);
- ERR_EXPLAIN("Failed to create 'res://.import' folder.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Failed to create 'res://.import' folder.");
}
}
memdelete(da);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 40ecffbb3b..55cae35a4a 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -93,8 +93,32 @@ void editor_register_fonts(Ref<Theme> p_theme) {
/* Custom font */
- bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/main_font_antialiased");
- DynamicFontData::Hinting font_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/main_font_hinting");
+ bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/font_antialiased");
+ int font_hinting_setting = (int)EditorSettings::get_singleton()->get("interface/editor/font_hinting");
+
+ DynamicFontData::Hinting font_hinting;
+ switch (font_hinting_setting) {
+ case 0:
+ // The "Auto" setting uses the setting that best matches the OS' font rendering:
+ // - macOS doesn't use font hinting.
+ // - Windows uses ClearType, which is in between "Light" and "Normal" hinting.
+ // - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light".
+#ifdef OSX_ENABLED
+ font_hinting = DynamicFontData::HINTING_NONE;
+#else
+ font_hinting = DynamicFontData::HINTING_LIGHT;
+#endif
+ break;
+ case 1:
+ font_hinting = DynamicFontData::HINTING_NONE;
+ break;
+ case 2:
+ font_hinting = DynamicFontData::HINTING_LIGHT;
+ break;
+ default:
+ font_hinting = DynamicFontData::HINTING_NORMAL;
+ break;
+ }
String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font");
Ref<DynamicFontData> CustomFont;
@@ -125,13 +149,11 @@ void editor_register_fonts(Ref<Theme> p_theme) {
/* Custom source code font */
String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font");
- bool font_source_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/code_font_antialiased");
- DynamicFontData::Hinting font_source_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/code_font_hinting");
Ref<DynamicFontData> CustomFontSource;
if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) {
CustomFontSource.instance();
- CustomFontSource->set_antialiased(font_source_antialiased);
- CustomFontSource->set_hinting(font_source_hinting);
+ CustomFontSource->set_antialiased(font_antialiased);
+ CustomFontSource->set_hinting(font_hinting);
CustomFontSource->set_font_path(custom_font_path_source);
} else {
EditorSettings::get_singleton()->set_manually("interface/editor/code_font", "");
@@ -201,8 +223,8 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<DynamicFontData> dfmono;
dfmono.instance();
- dfmono->set_antialiased(font_source_antialiased);
- dfmono->set_hinting(font_source_hinting);
+ dfmono->set_antialiased(font_antialiased);
+ dfmono->set_hinting(font_hinting);
dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size);
int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE;
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index cd5d26e577..24ed0ecfd0 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -30,6 +30,7 @@
#include "editor_help.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "doc_data_compressed.gen.h"
#include "editor/plugins/script_editor_plugin.h"
@@ -54,6 +55,7 @@ void EditorHelp::_init_colors() {
qualifier_color = text_color * Color(1, 1, 1, 0.8);
type_color = get_color("accent_color", "Editor").linear_interpolate(text_color, 0.5);
class_desc->add_color_override("selection_color", get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
+ class_desc->add_constant_override("line_separation", Math::round(5 * EDSCALE));
}
void EditorHelp::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
@@ -164,6 +166,17 @@ void EditorHelp::_class_desc_select(const String &p_select) {
void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) {
}
+void EditorHelp::_class_desc_resized() {
+ // Add extra horizontal margins for better readability.
+ // The margins increase as the width of the editor help container increases.
+ const int display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - 900 * EDSCALE) * 0.5;
+
+ Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_stylebox("normal", "RichTextLabel")->duplicate();
+ class_desc_stylebox->set_default_margin(MARGIN_LEFT, display_margin);
+ class_desc_stylebox->set_default_margin(MARGIN_RIGHT, display_margin);
+ class_desc->add_style_override("normal", class_desc_stylebox);
+}
+
void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
String t = p_type;
@@ -444,6 +457,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 +523,7 @@ void EditorHelp::_update_doc() {
class_desc->pop(); //table
class_desc->pop();
+ class_desc->pop(); // font
class_desc->add_newline();
class_desc->add_newline();
}
@@ -1425,11 +1440,10 @@ void EditorHelp::generate_doc() {
void EditorHelp::_notification(int p_what) {
switch (p_what) {
-
case NOTIFICATION_READY:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- _update_doc();
+ _update_doc();
} break;
default: break;
}
@@ -1487,6 +1501,7 @@ void EditorHelp::_bind_methods() {
ClassDB::bind_method("_class_list_select", &EditorHelp::_class_list_select);
ClassDB::bind_method("_class_desc_select", &EditorHelp::_class_desc_select);
ClassDB::bind_method("_class_desc_input", &EditorHelp::_class_desc_input);
+ ClassDB::bind_method("_class_desc_resized", &EditorHelp::_class_desc_resized);
ClassDB::bind_method("_request_help", &EditorHelp::_request_help);
ClassDB::bind_method("_unhandled_key_input", &EditorHelp::_unhandled_key_input);
ClassDB::bind_method("_search", &EditorHelp::_search);
@@ -1505,8 +1520,11 @@ EditorHelp::EditorHelp() {
add_child(class_desc);
class_desc->set_v_size_flags(SIZE_EXPAND_FILL);
class_desc->add_color_override("selection_color", get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
+
class_desc->connect("meta_clicked", this, "_class_desc_select");
class_desc->connect("gui_input", this, "_class_desc_input");
+ class_desc->connect("resized", this, "_class_desc_resized");
+ _class_desc_resized();
// Added second so it opens at the bottom so it won't offset the entire widget.
find_bar = memnew(FindBar);
@@ -1571,7 +1589,6 @@ void EditorHelpBit::_notification(int p_what) {
rich_text->add_color_override("selection_color", get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
} break;
-
default: break;
}
}
@@ -1601,6 +1618,10 @@ FindBar::FindBar() {
search_text->connect("text_changed", this, "_search_text_changed");
search_text->connect("text_entered", this, "_search_text_entered");
+ matches_label = memnew(Label);
+ add_child(matches_label);
+ matches_label->hide();
+
find_prev = memnew(ToolButton);
add_child(find_prev);
find_prev->set_focus_mode(FOCUS_NONE);
@@ -1611,9 +1632,9 @@ FindBar::FindBar() {
find_next->set_focus_mode(FOCUS_NONE);
find_next->connect("pressed", this, "_search_next");
- error_label = memnew(Label);
- add_child(error_label);
- error_label->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ Control *space = memnew(Control);
+ add_child(space);
+ space->set_custom_minimum_size(Size2(4, 0) * EDSCALE);
hide_button = memnew(TextureButton);
add_child(hide_button);
@@ -1643,25 +1664,21 @@ void FindBar::popup_search() {
void FindBar::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
-
- find_prev->set_icon(get_icon("MoveUp", "EditorIcons"));
- find_next->set_icon(get_icon("MoveDown", "EditorIcons"));
- hide_button->set_normal_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_hover_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_pressed_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
- set_process_unhandled_input(is_visible_in_tree());
- } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
- find_prev->set_icon(get_icon("MoveUp", "EditorIcons"));
- find_next->set_icon(get_icon("MoveDown", "EditorIcons"));
- hide_button->set_normal_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_hover_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_pressed_texture(get_icon("Close", "EditorIcons"));
- hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+
+ find_prev->set_icon(get_icon("MoveUp", "EditorIcons"));
+ find_next->set_icon(get_icon("MoveDown", "EditorIcons"));
+ hide_button->set_normal_texture(get_icon("Close", "EditorIcons"));
+ hide_button->set_hover_texture(get_icon("Close", "EditorIcons"));
+ hide_button->set_pressed_texture(get_icon("Close", "EditorIcons"));
+ hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+
+ set_process_unhandled_input(is_visible_in_tree());
+ } break;
}
}
@@ -1706,17 +1723,46 @@ bool FindBar::_search(bool p_search_previous) {
prev_search = stext;
if (ret) {
- set_error("");
+ _update_results_count();
} else {
- set_error(stext.empty() ? "" : TTR("No Matches"));
+ results_count = 0;
}
+ _update_matches_label();
return ret;
}
-void FindBar::set_error(const String &p_label) {
+void FindBar::_update_results_count() {
+
+ results_count = 0;
- error_label->set_text(p_label);
+ String searched = search_text->get_text();
+ if (searched.empty()) return;
+
+ String full_text = rich_text_label->get_text();
+
+ int from_pos = 0;
+
+ while (true) {
+ int pos = full_text.find(searched, from_pos);
+ if (pos == -1)
+ break;
+
+ results_count++;
+ from_pos = pos + searched.length();
+ }
+}
+
+void FindBar::_update_matches_label() {
+
+ if (search_text->get_text().empty() || results_count == -1) {
+ matches_label->hide();
+ } else {
+ matches_label->show();
+
+ matches_label->add_color_override("font_color", results_count > 0 ? Color(1, 1, 1) : EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ matches_label->set_text(vformat(results_count == 1 ? TTR("%d match.") : TTR("%d matches."), results_count));
+ }
}
void FindBar::_hide_bar() {
@@ -1762,5 +1808,9 @@ void FindBar::_search_text_changed(const String &p_text) {
void FindBar::_search_text_entered(const String &p_text) {
- search_next();
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ search_prev();
+ } else {
+ search_next();
+ }
}
diff --git a/editor/editor_help.h b/editor/editor_help.h
index a50ab8a9f9..1019cafffc 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -49,18 +49,23 @@ class FindBar : public HBoxContainer {
LineEdit *search_text;
ToolButton *find_prev;
ToolButton *find_next;
- Label *error_label;
+ Label *matches_label;
TextureButton *hide_button;
String prev_search;
RichTextLabel *rich_text_label;
+ int results_count;
+
void _show_search();
void _hide_bar();
void _search_text_changed(const String &p_text);
void _search_text_entered(const String &p_text);
+ void _update_results_count();
+ void _update_matches_label();
+
void _update_size();
protected:
@@ -72,8 +77,6 @@ protected:
static void _bind_methods();
public:
- void set_error(const String &p_label);
-
void set_rich_text_label(RichTextLabel *p_rich_text_label);
void popup_search();
@@ -148,6 +151,7 @@ class EditorHelp : public VBoxContainer {
void _class_list_select(const String &p_select);
void _class_desc_select(const String &p_select);
void _class_desc_input(const Ref<InputEvent> &p_input);
+ void _class_desc_resized();
Error _goto_desc(const String &p_class, int p_vscr = -1);
//void _update_history_buttons();
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index fbfc999dbf..27e61362ed 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -338,10 +338,15 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
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();
- 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())) ||
- (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges()))
+ String aux_term = (search_flags & SEARCH_CASE_SENSITIVE) ? term : term.to_lower();
+
+ if (aux_term.begins_with("."))
+ aux_term = aux_term.right(1);
+
+ if (aux_term.ends_with("("))
+ aux_term = aux_term.left(aux_term.length() - 1).strip_edges();
+
+ if (aux_term.is_subsequence_of(method_name))
match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i]));
}
if (search_flags & SEARCH_SIGNALS)
@@ -354,7 +359,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i]));
if (search_flags & SEARCH_PROPERTIES)
for (int i = 0; i < class_doc.properties.size(); i++)
- if (_match_string(term, class_doc.properties[i].name))
+ if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter))
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i]));
if (search_flags & SEARCH_THEME_ITEMS)
for (int i = 0; i < class_doc.theme_properties.size(); i++)
@@ -431,9 +436,9 @@ bool EditorHelpSearch::Runner::_phase_select_match() {
bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const {
if (search_flags & SEARCH_CASE_SENSITIVE)
- return p_string.find(p_term) > -1;
+ return p_term.is_subsequence_of(p_string);
else
- return p_string.findn(p_term) > -1;
+ return p_term.is_subsequence_ofi(p_string);
}
void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index e4ddf44bc4..8d5858a10d 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -378,7 +378,7 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
node = node->get_owner();
}
- if (!found) {
+ if (!found && node) {
//if not found, try default class value
Variant attempt = ClassDB::class_get_default_property_value(node->get_class_name(), p_prop);
if (attempt.get_type() != Variant::NIL) {
@@ -504,7 +504,7 @@ bool EditorProperty::use_keying_next() const {
PropertyInfo &p = I->get();
if (p.name == property) {
- return p.hint == PROPERTY_HINT_SPRITE_FRAME;
+ return (p.usage & PROPERTY_USAGE_KEYING_INCREMENTS);
}
}
@@ -1044,15 +1044,13 @@ void EditorInspectorSection::_notification(int p_what) {
Ref<Font> font = get_font("font", "Tree");
Ref<Texture> arrow;
-#ifdef TOOLS_ENABLED
if (foldable) {
if (object->editor_is_section_unfolded(section)) {
- arrow = get_icon("arrow_up", "Tree");
- } else {
arrow = get_icon("arrow", "Tree");
+ } else {
+ arrow = get_icon("arrow_collapsed", "Tree");
}
}
-#endif
Size2 size = get_size();
Point2 offset;
@@ -1087,15 +1085,13 @@ void EditorInspectorSection::_notification(int p_what) {
Ref<Texture> arrow;
-#ifdef TOOLS_ENABLED
if (foldable) {
if (object->editor_is_section_unfolded(section)) {
- arrow = get_icon("arrow_up", "Tree");
- } else {
arrow = get_icon("arrow", "Tree");
+ } else {
+ arrow = get_icon("arrow_collapsed", "Tree");
}
}
-#endif
Ref<Font> font = get_font("font", "Tree");
@@ -1107,13 +1103,12 @@ void EditorInspectorSection::_notification(int p_what) {
draw_rect(Rect2(Vector2(), Vector2(get_size().width, h)), bg_color);
- int hs = get_constant("hseparation", "Tree");
-
+ const int arrow_margin = 3;
Color color = get_color("font_color", "Tree");
- draw_string(font, Point2(hs, font->get_ascent() + (h - font->get_height()) / 2).floor(), label, color, get_size().width);
+ draw_string(font, Point2(Math::round((16 + arrow_margin) * EDSCALE), font->get_ascent() + (h - font->get_height()) / 2).floor(), label, color, get_size().width);
if (arrow.is_valid()) {
- draw_texture(arrow, Point2(get_size().width - arrow->get_width(), (h - arrow->get_height()) / 2).floor());
+ draw_texture(arrow, Point2(Math::round(arrow_margin * EDSCALE), (h - arrow->get_height()) / 2).floor());
}
}
}
@@ -1155,7 +1150,6 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
vbox_added = true;
}
-#ifdef TOOLS_ENABLED
if (foldable) {
_test_unfold();
if (object->editor_is_section_unfolded(section)) {
@@ -1164,7 +1158,6 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
vbox->hide();
}
}
-#endif
}
void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
@@ -1172,7 +1165,6 @@ void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
if (!foldable)
return;
-#ifdef TOOLS_ENABLED
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
@@ -1191,7 +1183,6 @@ void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
vbox->hide();
}
}
-#endif
}
VBoxContainer *EditorInspectorSection::get_vbox() {
@@ -1205,11 +1196,9 @@ void EditorInspectorSection::unfold() {
_test_unfold();
-#ifdef TOOLS_ENABLED
object->editor_set_section_unfold(section, true);
vbox->show();
update();
-#endif
}
void EditorInspectorSection::fold() {
@@ -1219,11 +1208,9 @@ void EditorInspectorSection::fold() {
if (!vbox_added)
return; //kinda pointless
-#ifdef TOOLS_ENABLED
object->editor_set_section_unfold(section, false);
vbox->hide();
update();
-#endif
}
void EditorInspectorSection::_bind_methods() {
@@ -1302,6 +1289,7 @@ void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &
}
}
+ ERR_FAIL_COND(idx == -1);
for (int i = idx; i < inspector_plugin_count - 1; i++) {
inspector_plugins[i] = inspector_plugins[i + 1];
}
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index b5cdc76115..5474f86c74 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -113,6 +113,10 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
log->add_text(" ");
tool_button->set_icon(icon);
} break;
+ case MSG_TYPE_EDITOR: {
+ // Distinguish editor messages from messages printed by the project
+ log->push_color(get_color("font_color", "Editor") * Color(1, 1, 1, 0.6));
+ } break;
}
log->add_text(p_msg);
@@ -128,7 +132,7 @@ void EditorLog::set_tool_button(ToolButton *p_tool_button) {
void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) {
EditorLog *self = (EditorLog *)p_self;
- self->add_message(p_name);
+ self->add_message(p_name, EditorLog::MSG_TYPE_EDITOR);
}
void EditorLog::_bind_methods() {
diff --git a/editor/editor_log.h b/editor/editor_log.h
index bb56bd34fe..10561b9c83 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -74,7 +74,8 @@ public:
enum MessageType {
MSG_TYPE_STD,
MSG_TYPE_ERROR,
- MSG_TYPE_WARNING
+ MSG_TYPE_WARNING,
+ MSG_TYPE_EDITOR
};
void add_message(const String &p_msg, MessageType p_type = MSG_TYPE_STD);
diff --git a/editor/editor_network_profiler.cpp b/editor/editor_network_profiler.cpp
new file mode 100644
index 0000000000..8482c4e38a
--- /dev/null
+++ b/editor/editor_network_profiler.cpp
@@ -0,0 +1,211 @@
+/*************************************************************************/
+/* editor_network_profiler.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_network_profiler.h"
+
+#include "core/os/os.h"
+#include "editor_scale.h"
+#include "editor_settings.h"
+
+void EditorNetworkProfiler::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_update_frame"), &EditorNetworkProfiler::_update_frame);
+ ClassDB::bind_method(D_METHOD("_activate_pressed"), &EditorNetworkProfiler::_activate_pressed);
+ ClassDB::bind_method(D_METHOD("_clear_pressed"), &EditorNetworkProfiler::_clear_pressed);
+ ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
+}
+
+void EditorNetworkProfiler::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ activate->set_icon(get_icon("Play", "EditorIcons"));
+ clear_button->set_icon(get_icon("Clear", "EditorIcons"));
+ incoming_bandwidth_text->set_right_icon(get_icon("ArrowDown", "EditorIcons"));
+ outgoing_bandwidth_text->set_right_icon(get_icon("ArrowUp", "EditorIcons"));
+
+ // This needs to be done here to set the faded color when the profiler is first opened
+ incoming_bandwidth_text->add_color_override("font_color_uneditable", get_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
+ outgoing_bandwidth_text->add_color_override("font_color_uneditable", get_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
+ }
+}
+
+void EditorNetworkProfiler::_update_frame() {
+
+ counters_display->clear();
+
+ TreeItem *root = counters_display->create_item();
+
+ for (Map<ObjectID, MultiplayerAPI::ProfilingInfo>::Element *E = nodes_data.front(); E; E = E->next()) {
+
+ TreeItem *node = counters_display->create_item(root);
+
+ for (int j = 0; j < counters_display->get_columns(); ++j) {
+ node->set_text_align(j, j > 0 ? TreeItem::ALIGN_RIGHT : TreeItem::ALIGN_LEFT);
+ }
+
+ node->set_text(0, E->get().node_path);
+ node->set_text(1, E->get().incoming_rpc == 0 ? "-" : itos(E->get().incoming_rpc));
+ node->set_text(2, E->get().incoming_rset == 0 ? "-" : itos(E->get().incoming_rset));
+ node->set_text(3, E->get().outgoing_rpc == 0 ? "-" : itos(E->get().outgoing_rpc));
+ node->set_text(4, E->get().outgoing_rset == 0 ? "-" : itos(E->get().outgoing_rset));
+ }
+}
+
+void EditorNetworkProfiler::_activate_pressed() {
+
+ if (activate->is_pressed()) {
+ activate->set_icon(get_icon("Stop", "EditorIcons"));
+ activate->set_text(TTR("Stop"));
+ } else {
+ activate->set_icon(get_icon("Play", "EditorIcons"));
+ activate->set_text(TTR("Start"));
+ }
+ emit_signal("enable_profiling", activate->is_pressed());
+}
+
+void EditorNetworkProfiler::_clear_pressed() {
+ nodes_data.clear();
+ set_bandwidth(0, 0);
+ if (frame_delay->is_stopped()) {
+ frame_delay->set_wait_time(0.1);
+ frame_delay->start();
+ }
+}
+
+void EditorNetworkProfiler::add_node_frame_data(const MultiplayerAPI::ProfilingInfo p_frame) {
+
+ if (!nodes_data.has(p_frame.node)) {
+ nodes_data.insert(p_frame.node, p_frame);
+ } else {
+ nodes_data[p_frame.node].incoming_rpc += p_frame.incoming_rpc;
+ nodes_data[p_frame.node].incoming_rset += p_frame.incoming_rset;
+ nodes_data[p_frame.node].outgoing_rpc += p_frame.outgoing_rpc;
+ nodes_data[p_frame.node].outgoing_rset += p_frame.outgoing_rset;
+ }
+
+ if (frame_delay->is_stopped()) {
+ frame_delay->set_wait_time(0.1);
+ frame_delay->start();
+ }
+}
+
+void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) {
+
+ incoming_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_incoming)));
+ outgoing_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_outgoing)));
+
+ // Make labels more prominent when the bandwidth is greater than 0 to attract user attention
+ incoming_bandwidth_text->add_color_override(
+ "font_color_uneditable",
+ get_color("font_color", "Editor") * Color(1, 1, 1, p_incoming > 0 ? 1 : 0.5));
+ outgoing_bandwidth_text->add_color_override(
+ "font_color_uneditable",
+ get_color("font_color", "Editor") * Color(1, 1, 1, p_outgoing > 0 ? 1 : 0.5));
+}
+
+bool EditorNetworkProfiler::is_profiling() {
+ return activate->is_pressed();
+}
+
+EditorNetworkProfiler::EditorNetworkProfiler() {
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_constant_override("separation", 8 * EDSCALE);
+ add_child(hb);
+
+ activate = memnew(Button);
+ activate->set_toggle_mode(true);
+ activate->set_text(TTR("Start"));
+ activate->connect("pressed", this, "_activate_pressed");
+ hb->add_child(activate);
+
+ clear_button = memnew(Button);
+ clear_button->set_text(TTR("Clear"));
+ clear_button->connect("pressed", this, "_clear_pressed");
+ hb->add_child(clear_button);
+
+ hb->add_spacer();
+
+ Label *lb = memnew(Label);
+ lb->set_text(TTR("Down"));
+ hb->add_child(lb);
+
+ incoming_bandwidth_text = memnew(LineEdit);
+ incoming_bandwidth_text->set_editable(false);
+ incoming_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE);
+ incoming_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ hb->add_child(incoming_bandwidth_text);
+
+ Control *down_up_spacer = memnew(Control);
+ down_up_spacer->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
+ hb->add_child(down_up_spacer);
+
+ lb = memnew(Label);
+ lb->set_text(TTR("Up"));
+ hb->add_child(lb);
+
+ outgoing_bandwidth_text = memnew(LineEdit);
+ outgoing_bandwidth_text->set_editable(false);
+ outgoing_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE);
+ outgoing_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ hb->add_child(outgoing_bandwidth_text);
+
+ // Set initial texts in the incoming/outgoing bandwidth labels
+ set_bandwidth(0, 0);
+
+ counters_display = memnew(Tree);
+ counters_display->set_custom_minimum_size(Size2(300, 0) * EDSCALE);
+ counters_display->set_v_size_flags(SIZE_EXPAND_FILL);
+ counters_display->set_hide_folding(true);
+ counters_display->set_hide_root(true);
+ counters_display->set_columns(5);
+ counters_display->set_column_titles_visible(true);
+ counters_display->set_column_title(0, TTR("Node"));
+ counters_display->set_column_expand(0, true);
+ counters_display->set_column_min_width(0, 60 * EDSCALE);
+ counters_display->set_column_title(1, TTR("Incoming RPC"));
+ counters_display->set_column_expand(1, false);
+ counters_display->set_column_min_width(1, 120 * EDSCALE);
+ counters_display->set_column_title(2, TTR("Incoming RSET"));
+ counters_display->set_column_expand(2, false);
+ counters_display->set_column_min_width(2, 120 * EDSCALE);
+ counters_display->set_column_title(3, TTR("Outgoing RPC"));
+ counters_display->set_column_expand(3, false);
+ counters_display->set_column_min_width(3, 120 * EDSCALE);
+ counters_display->set_column_title(4, TTR("Outgoing RSET"));
+ counters_display->set_column_expand(4, false);
+ counters_display->set_column_min_width(4, 120 * EDSCALE);
+ add_child(counters_display);
+
+ frame_delay = memnew(Timer);
+ frame_delay->set_wait_time(0.1);
+ frame_delay->set_one_shot(true);
+ add_child(frame_delay);
+ frame_delay->connect("timeout", this, "_update_frame");
+}
diff --git a/editor/editor_network_profiler.h b/editor/editor_network_profiler.h
new file mode 100644
index 0000000000..85fec340fd
--- /dev/null
+++ b/editor/editor_network_profiler.h
@@ -0,0 +1,72 @@
+/*************************************************************************/
+/* editor_network_profiler.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 EDITORNETWORKPROFILER_H
+#define EDITORNETWORKPROFILER_H
+
+#include "scene/gui/box_container.h"
+#include "scene/gui/button.h"
+#include "scene/gui/label.h"
+#include "scene/gui/split_container.h"
+#include "scene/gui/tree.h"
+
+class EditorNetworkProfiler : public VBoxContainer {
+
+ GDCLASS(EditorNetworkProfiler, VBoxContainer)
+
+private:
+ Button *activate;
+ Button *clear_button;
+ Tree *counters_display;
+ LineEdit *incoming_bandwidth_text;
+ LineEdit *outgoing_bandwidth_text;
+
+ Timer *frame_delay;
+
+ Map<ObjectID, MultiplayerAPI::ProfilingInfo> nodes_data;
+
+ void _update_frame();
+
+ void _activate_pressed();
+ void _clear_pressed();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void add_node_frame_data(const MultiplayerAPI::ProfilingInfo p_frame);
+ void set_bandwidth(int p_incoming, int p_outgoing);
+ bool is_profiling();
+
+ EditorNetworkProfiler();
+};
+
+#endif //EDITORNETWORKPROFILER_H
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 3431930b8b..e1bbe4b923 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -60,6 +60,7 @@
#include "editor/import/editor_import_collada.h"
#include "editor/import/editor_scene_importer_gltf.h"
#include "editor/import/resource_importer_bitmask.h"
+#include "editor/import/resource_importer_csv.h"
#include "editor/import/resource_importer_csv_translation.h"
#include "editor/import/resource_importer_image.h"
#include "editor/import/resource_importer_layered_texture.h"
@@ -122,6 +123,7 @@
#include "editor/plugins/theme_editor_plugin.h"
#include "editor/plugins/tile_map_editor_plugin.h"
#include "editor/plugins/tile_set_editor_plugin.h"
+#include "editor/plugins/version_control_editor_plugin.h"
#include "editor/plugins/visual_shader_editor_plugin.h"
#include "editor/pvrtc_compress.h"
#include "editor/register_exporters.h"
@@ -135,6 +137,8 @@ void EditorNode::_update_scene_tabs() {
bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button");
+ OS::get_singleton()->global_menu_clear("_dock");
+
scene_tabs->clear_tabs();
Ref<Texture> script_icon = gui_base->get_icon("Script", "EditorIcons");
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
@@ -149,11 +153,16 @@ void EditorNode::_update_scene_tabs() {
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
scene_tabs->add_tab(editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), icon);
+ OS::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), GLOBAL_SCENE, i);
+
if (show_rb && editor_data.get_scene_root_script(i).is_valid()) {
scene_tabs->set_tab_right_button(i, script_icon);
}
}
+ OS::get_singleton()->global_menu_add_separator("_dock");
+ OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+
scene_tabs->set_current_tab(editor_data.get_edited_scene());
if (scene_tabs->get_offset_buttons_visible()) {
@@ -177,6 +186,20 @@ void EditorNode::_update_scene_tabs() {
}
}
+void EditorNode::_version_control_menu_option(int p_idx) {
+
+ switch (vcs_actions_menu->get_item_id(p_idx)) {
+ case RUN_VCS_SETTINGS: {
+
+ VersionControlEditorPlugin::get_singleton()->popup_vcs_set_up_dialog(gui_base);
+ } break;
+ case RUN_VCS_SHUT_DOWN: {
+
+ VersionControlEditorPlugin::get_singleton()->shut_down();
+ } break;
+ }
+}
+
void EditorNode::_update_title() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
@@ -238,185 +261,191 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
void EditorNode::_notification(int p_what) {
- if (p_what == NOTIFICATION_EXIT_TREE) {
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ if (opening_prev && !confirmation->is_visible())
+ opening_prev = false;
- 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 (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) {
- if (opening_prev && !confirmation->is_visible())
- opening_prev = false;
+ unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version());
+ _update_title();
+ }
- if (unsaved_cache != (saved_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();
+ }
- unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version());
- _update_title();
- }
+ // 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 (last_checked_version != editor_data.get_undo_redo().get_version()) {
- _update_scene_tabs();
- last_checked_version = editor_data.get_undo_redo().get_version();
- }
+ if (frame != update_spinner_step_frame && (tick - update_spinner_step_msec) > (1000 / 8)) {
- // 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_spinner_step++;
+ if (update_spinner_step >= 8)
+ update_spinner_step = 0;
- if (frame != update_spinner_step_frame && (tick - update_spinner_step_msec) > (1000 / 8)) {
+ update_spinner_step_msec = tick;
+ update_spinner_step_frame = frame + 1;
- update_spinner_step++;
- if (update_spinner_step >= 8)
- update_spinner_step = 0;
+ // 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_spinner_step_msec = tick;
- update_spinner_step_frame = frame + 1;
+ editor_selection->update();
- // 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"));
- }
- }
+ scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")));
- editor_selection->update();
+ ResourceImporterTexture::get_singleton()->update_imports();
+ } break;
- scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")));
+ case NOTIFICATION_ENTER_TREE: {
+ Engine::get_singleton()->set_editor_hint(true);
- ResourceImporterTexture::get_singleton()->update_imports();
- }
- if (p_what == NOTIFICATION_ENTER_TREE) {
+ 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");
+ get_tree()->connect("global_menu_action", this, "_global_menu_action");
- Engine::get_singleton()->set_editor_hint(true);
+ /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
+ } break;
- 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");
+ 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;
- /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
- }
+ case NOTIFICATION_READY: {
- if (p_what == NOTIFICATION_EXIT_TREE) {
+ 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);
- editor_data.clear_edited_scenes();
- }
- if (p_what == NOTIFICATION_READY) {
+ feature_profile_manager->notify_changed();
- 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);
+ if (!main_editor_buttons[EDITOR_3D]->is_visible()) { //may be hidden due to feature profile
+ _editor_select(EDITOR_2D);
+ } else {
+ _editor_select(EDITOR_3D);
+ }
- feature_profile_manager->notify_changed();
+ _update_debug_options();
- if (!main_editor_buttons[EDITOR_3D]->is_visible()) { //may be hidden due to feature profile
- _editor_select(EDITOR_2D);
- } else {
- _editor_select(EDITOR_3D);
- }
+ /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
+ } break;
- _update_debug_options();
+ case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
- /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
- }
+ // 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")));
- if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
+ EditorFileSystem::get_singleton()->scan_changes();
+ } break;
- // 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")));
+ case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
- EditorFileSystem::get_singleton()->scan_changes();
- }
+ // 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_FOCUS_OUT) {
+ case MainLoop::NOTIFICATION_WM_ABOUT: {
- // 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")));
- }
+ show_about();
+ } 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"));
+ bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "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;
}
}
@@ -834,7 +863,7 @@ void EditorNode::_get_scene_metadata(const String &p_file) {
for (List<String>::Element *E = esl.front(); E; E = E->next()) {
Variant st = cf->get_value("editor_states", E->get());
- if (st.get_type()) {
+ if (st.get_type() != Variant::NIL) {
md[E->get()] = st;
}
}
@@ -1576,6 +1605,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
get_inspector()->edit(NULL);
node_dock->set_node(NULL);
scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
return;
}
@@ -1664,9 +1694,10 @@ void EditorNode::_edit_current() {
Resource *current_res = Object::cast_to<Resource>(current_obj);
ERR_FAIL_COND(!current_res);
- scene_tree_dock->set_selected(NULL);
get_inspector()->edit(current_res);
+ scene_tree_dock->set_selected(NULL);
node_dock->set_node(NULL);
+ inspector_dock->update(NULL);
EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path());
int subr_idx = current_res->get_path().find("::");
@@ -1693,9 +1724,11 @@ void EditorNode::_edit_current() {
if (current_node->is_inside_tree()) {
node_dock->set_node(current_node);
scene_tree_dock->set_selected(current_node);
+ inspector_dock->update(current_node);
} else {
node_dock->set_node(NULL);
scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
}
if (get_edited_scene() && get_edited_scene()->get_filename() != String()) {
@@ -1715,6 +1748,8 @@ void EditorNode::_edit_current() {
get_inspector()->edit(current_obj);
node_dock->set_node(NULL);
+ scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
}
inspector_dock->set_warning(editable_warning);
@@ -1816,6 +1851,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
String main_scene;
String run_filename;
String args;
+ bool skip_breakpoints;
if (p_current || (editor_data.get_edited_scene_root() && p_custom == editor_data.get_edited_scene_root()->get_filename())) {
@@ -1881,8 +1917,9 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
editor_data.get_editor_breakpoints(&breakpoints);
args = ProjectSettings::get_singleton()->get("editor/main_run_args");
+ skip_breakpoints = ScriptEditor::get_singleton()->get_debugger()->is_skip_breakpoints();
- Error error = editor_run.run(run_filename, args, breakpoints);
+ Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints);
if (error != OK) {
@@ -1915,10 +1952,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
switch (p_option) {
case FILE_NEW_SCENE: {
- int idx = editor_data.add_edited_scene(-1);
- _scene_tab_changed(idx);
- editor_data.clear_editor_states();
- _update_scene_tabs();
+ new_scene();
} break;
case FILE_NEW_INHERITED_SCENE:
@@ -1965,6 +1999,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
break;
opening_prev = true;
open_request(previous_scenes.back()->get());
+ previous_scenes.pop_back();
} break;
case FILE_CLOSE_OTHERS:
@@ -2177,27 +2212,27 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case EDIT_UNDO: {
if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
- log->add_message("Can't UNDO while mouse buttons are pressed.");
+ log->add_message("Can't undo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
} else {
String action = editor_data.get_undo_redo().get_current_action_name();
if (!editor_data.get_undo_redo().undo()) {
- log->add_message("There is nothing to UNDO.");
+ log->add_message("Nothing to undo.", EditorLog::MSG_TYPE_EDITOR);
} else if (action != "") {
- log->add_message("UNDO: " + action);
+ log->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
}
}
} break;
case EDIT_REDO: {
if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
- log->add_message("Can't REDO while mouse buttons are pressed.");
+ log->add_message("Can't redo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
} else {
if (!editor_data.get_undo_redo().redo()) {
- log->add_message("There is nothing to REDO.");
+ log->add_message("Nothing to redo.", EditorLog::MSG_TYPE_EDITOR);
} else {
String action = editor_data.get_undo_redo().get_current_action_name();
- log->add_message("REDO: " + action);
+ log->add_message("Redo: " + action, EditorLog::MSG_TYPE_EDITOR);
}
}
} break;
@@ -2490,12 +2525,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
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: {
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -2543,8 +2572,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
restart_editor();
} break;
default: {
- if (p_option >= IMPORT_PLUGIN_BASE) {
- }
}
}
}
@@ -2557,7 +2584,7 @@ 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)) {
+ if (EditorSettings::get_singleton()->get("interface/editor/automatically_open_screenshots")) {
OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->globalize_path(path));
}
}
@@ -2623,11 +2650,8 @@ void EditorNode::_exit_editor() {
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);
+ // Dim the editor window while it's quitting to make it clearer that it's busy
+ dim_editor(true, true);
get_tree()->quit();
}
@@ -2644,6 +2668,14 @@ void EditorNode::_discard_changes(const String &p_str) {
case FILE_CLOSE_ALL:
case SCENE_TAB_CLOSE: {
+ Node *scene = editor_data.get_edited_scene_root(tab_closing);
+ if (scene != NULL) {
+ String scene_filename = scene->get_filename();
+ if (scene_filename != "") {
+ previous_scenes.push_back(scene_filename);
+ }
+ }
+
_remove_scene(tab_closing);
_update_scene_tabs();
@@ -2709,6 +2741,21 @@ void EditorNode::_update_debug_options() {
if (check_reload_scripts) _menu_option_confirm(RUN_RELOAD_SCRIPTS, true);
}
+void EditorNode::_update_file_menu_opened() {
+
+ Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
+ close_scene_sc->set_name(TTR("Close Scene"));
+ Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene"));
+ PopupMenu *pop = file_menu->get_popup();
+ pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty());
+}
+
+void EditorNode::_update_file_menu_closed() {
+ PopupMenu *pop = file_menu->get_popup();
+ pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), false);
+}
+
Control *EditorNode::get_viewport() {
return viewport;
@@ -2761,6 +2808,19 @@ void EditorNode::_editor_select(int p_which) {
}
}
+void EditorNode::select_editor_by_name(const String &p_name) {
+ ERR_FAIL_COND(p_name == "");
+
+ for (int i = 0; i < main_editor_buttons.size(); i++) {
+ if (main_editor_buttons[i]->get_text() == p_name) {
+ _editor_select(i);
+ return;
+ }
+ }
+
+ ERR_FAIL_MSG("The editor name '" + p_name + "' was not found.");
+}
+
void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) {
if (p_editor->has_main_screen()) {
@@ -2884,36 +2944,39 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
return;
}
- String path = cf->get_value("plugin", "script");
- path = String("res://addons").plus_file(p_addon).plus_file(path);
+ String script_path = cf->get_value("plugin", "script");
+ Ref<Script> script; // We need to save it for creating "ep" below.
- Ref<Script> script = ResourceLoader::load(path);
+ // Only try to load the script if it has a name. Else, the plugin has no init script.
+ if (script_path.length() > 0) {
+ script_path = String("res://addons").plus_file(p_addon).plus_file(script_path);
+ script = ResourceLoader::load(script_path);
- if (script.is_null()) {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), path));
- return;
- }
+ if (script.is_null()) {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), script_path));
+ return;
+ }
- //errors in the script cause the base_type to be ""
- if (String(script->get_instance_base_type()) == "") {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), path));
- return;
- }
+ // Errors in the script cause the base_type to be an empty string.
+ if (String(script->get_instance_base_type()) == "") {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), script_path));
+ return;
+ }
- //could check inheritance..
- if (String(script->get_instance_base_type()) != "EditorPlugin") {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path));
- return;
- }
+ // Plugin init scripts must inherit from EditorPlugin and be tools.
+ if (String(script->get_instance_base_type()) != "EditorPlugin") {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path));
+ return;
+ }
- if (!script->is_tool()) {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), path));
- return;
+ if (!script->is_tool()) {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path));
+ return;
+ }
}
EditorPlugin *ep = memnew(EditorPlugin);
ep->set_script(script.get_ref_ptr());
- ep->set_dir_cache(p_addon);
plugin_addons[p_addon] = ep;
add_editor_plugin(ep, p_config_changed);
@@ -3070,7 +3133,14 @@ void EditorNode::_clear_undo_history() {
void EditorNode::set_current_scene(int p_idx) {
+ //Save the folding in case the scene gets reloaded.
+ if (editor_data.get_scene_path(p_idx) != "")
+ editor_folding.save_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
+
if (editor_data.check_and_update_scene(p_idx)) {
+ if (editor_data.get_scene_path(p_idx) != "")
+ editor_folding.load_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
+
call_deferred("_clear_undo_history");
}
@@ -3121,6 +3191,14 @@ void EditorNode::fix_dependencies(const String &p_for_file) {
dependency_fixer->edit(p_for_file);
}
+int EditorNode::new_scene() {
+ int idx = editor_data.add_edited_scene(-1);
+ _scene_tab_changed(idx);
+ editor_data.clear_editor_states();
+ _update_scene_tabs();
+ return idx;
+}
+
Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) {
if (!is_inside_tree()) {
@@ -3281,6 +3359,13 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
void EditorNode::open_request(const String &p_path) {
+ if (!opening_prev) {
+ List<String>::Element *prev_scene = previous_scenes.find(p_path);
+ if (prev_scene != NULL) {
+ prev_scene->erase();
+ }
+ }
+
load_scene(p_path); // as it will be opened in separate tab
}
@@ -3463,6 +3548,7 @@ void EditorNode::register_editor_types() {
ClassDB::register_class<EditorResourcePreviewGenerator>();
ClassDB::register_virtual_class<EditorFileSystem>();
ClassDB::register_class<EditorFileSystemDirectory>();
+ ClassDB::register_class<EditorVCSInterface>();
ClassDB::register_virtual_class<ScriptEditor>();
ClassDB::register_virtual_class<EditorInterface>();
ClassDB::register_class<EditorExportPlugin>();
@@ -3490,6 +3576,69 @@ void EditorNode::stop_child_process() {
_menu_option_confirm(RUN_STOP, false);
}
+Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) const {
+ ERR_FAIL_COND_V(!p_object, NULL);
+
+ Ref<Script> script = p_object->get_script();
+
+ if (script.is_valid()) {
+ // Uncommenting would break things! Consider adding a parameter if you need it.
+ // StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path());
+ // if (name != StringName())
+ // return name;
+
+ // should probably be deprecated in 4.x
+ StringName base = script->get_instance_base_type();
+ if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) {
+ const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base];
+
+ Ref<Script> base_script = script;
+ while (base_script.is_valid()) {
+ for (int i = 0; i < types.size(); ++i) {
+ if (types[i].script == base_script) {
+ return types[i].script;
+ }
+ }
+ base_script = base_script->get_base_script();
+ }
+ }
+ }
+
+ return NULL;
+}
+
+StringName EditorNode::get_object_custom_type_name(const Object *p_object) const {
+ ERR_FAIL_COND_V(!p_object, StringName());
+
+ Ref<Script> script = p_object->get_script();
+ if (script.is_null() && p_object->is_class("Script")) {
+ script = p_object;
+ }
+
+ if (script.is_valid()) {
+ Ref<Script> base_script = script;
+ while (base_script.is_valid()) {
+ StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path());
+ if (name != StringName())
+ return name;
+
+ // should probably be deprecated in 4.x
+ StringName base = base_script->get_instance_base_type();
+ if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) {
+ const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base];
+ for (int i = 0; i < types.size(); ++i) {
+ if (types[i].script == base_script) {
+ return types[i].name;
+ }
+ }
+ }
+ base_script = base_script->get_base_script();
+ }
+ }
+
+ return StringName();
+}
+
Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const {
ERR_FAIL_COND_V(!p_object || !gui_base, NULL);
@@ -3499,23 +3648,24 @@ Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p
}
if (script.is_valid()) {
- StringName name = EditorNode::get_editor_data().script_class_get_name(script->get_path());
- String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name);
- if (icon_path.length())
- return ResourceLoader::load(icon_path);
-
- // should probably be deprecated in 4.x
- StringName base = script->get_instance_base_type();
- if (base != StringName()) {
- const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types();
- for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) {
- const Vector<EditorData::CustomType> &ct = E->value();
- for (int i = 0; i < ct.size(); ++i) {
- if (ct[i].name == base && ct[i].icon.is_valid()) {
- return ct[i].icon;
+ Ref<Script> base_script = script;
+ while (base_script.is_valid()) {
+ StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path());
+ String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name);
+ if (icon_path.length())
+ return ResourceLoader::load(icon_path);
+
+ // should probably be deprecated in 4.x
+ StringName base = base_script->get_instance_base_type();
+ if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) {
+ const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base];
+ for (int i = 0; i < types.size(); ++i) {
+ if (types[i].script == base_script && types[i].icon.is_valid()) {
+ return types[i].icon;
}
}
}
+ base_script = base_script->get_base_script();
}
}
@@ -3708,9 +3858,13 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
void EditorNode::show_warning(const String &p_text, const String &p_title) {
- warning->set_text(p_text);
- warning->set_title(p_title);
- warning->popup_centered_minsize();
+ if (warning->is_inside_tree()) {
+ warning->set_text(p_text);
+ warning->set_title(p_title);
+ warning->popup_centered_minsize();
+ } else {
+ WARN_PRINTS(p_title + " " + p_text);
+ }
}
void EditorNode::_copy_warning(const String &p_str) {
@@ -4254,6 +4408,15 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
return true;
}
+void EditorNode::run_play() {
+ _menu_option_confirm(RUN_STOP, true);
+ _run(false);
+}
+
+void EditorNode::run_stop() {
+ _menu_option_confirm(RUN_STOP, false);
+}
+
int EditorNode::get_current_tab() {
return scene_tabs->get_current_tab();
}
@@ -4417,8 +4580,17 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->add_separator();
scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), FILE_SHOW_IN_FILESYSTEM);
scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE);
+
scene_tabs_context_menu->add_separator();
- scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
+ Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene");
+ close_tab_sc->set_name(TTR("Close Tab"));
+ scene_tabs_context_menu->add_shortcut(close_tab_sc, FILE_CLOSE);
+ Ref<ShortCut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ undo_close_tab_sc->set_name(TTR("Undo Close Tab"));
+ scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV);
+ if (previous_scenes.empty()) {
+ scene_tabs_context_menu->set_item_disabled(scene_tabs_context_menu->get_item_index(FILE_OPEN_PREV), true);
+ }
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), FILE_CLOSE_OTHERS);
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), FILE_CLOSE_RIGHT);
scene_tabs_context_menu->add_item(TTR("Close All Tabs"), FILE_CLOSE_ALL);
@@ -4662,8 +4834,7 @@ void EditorNode::remove_control_from_dock(Control *p_control) {
}
}
- ERR_EXPLAIN("Control was not in dock");
- ERR_FAIL_COND(!dock);
+ ERR_FAIL_COND_MSG(!dock, "Control was not in dock.");
dock->remove_child(p_control);
_update_dock_slots_visibility();
@@ -4801,6 +4972,23 @@ void EditorNode::remove_tool_menu_item(const String &p_name) {
}
}
+void EditorNode::_global_menu_action(const Variant &p_id, const Variant &p_meta) {
+
+ int id = (int)p_id;
+ if (id == GLOBAL_NEW_WINDOW) {
+ if (OS::get_singleton()->get_main_loop()) {
+ List<String> args;
+ String exec = OS::get_singleton()->get_executable_path();
+
+ OS::ProcessID pid = 0;
+ OS::get_singleton()->execute(exec, args, false, &pid);
+ }
+ } else if (id == GLOBAL_SCENE) {
+ int idx = (int)p_meta;
+ scene_tabs->set_current_tab(idx);
+ }
+}
+
void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_selected_path());
@@ -4968,47 +5156,12 @@ void EditorNode::_open_imported() {
load_scene(open_import_request, true, false, true, true);
}
-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 && dim_count == 0) {
- _start_dimming(true);
- }
- dim_count++;
+void EditorNode::dim_editor(bool p_dimming, bool p_force_dim) {
+ // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor
+ if ((p_force_dim || EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup")) && p_dimming) {
+ gui_base->set_modulate(Color(0.5, 0.5, 0.5));
} else {
- if (dim_count == 1) {
- _start_dimming(false);
- }
- if (dim_count > 0) {
- dim_count--;
- } else {
- ERR_PRINT("Undimmed before dimming!");
- }
- }
-}
-
-void EditorNode::_start_dimming(bool p_dimming) {
- _dimming = p_dimming;
- _dim_time = 0.0f;
- _dim_timer->start();
-}
-
-void EditorNode::_dim_timeout() {
-
- _dim_time += _dim_timer->get_wait_time();
- float wait_time = EditorSettings::get_singleton()->get("interface/editor/dim_transition_time");
-
- float c = 1.0f - (float)EditorSettings::get_singleton()->get("interface/editor/dim_amount");
-
- Color base = _dimming ? Color(1, 1, 1) : Color(c, c, c);
- Color final = _dimming ? Color(c, c, c) : Color(1, 1, 1);
-
- if (_dim_time + _dim_timer->get_wait_time() >= wait_time) {
- gui_base->set_modulate(final);
- _dim_timer->stop();
- } else {
- gui_base->set_modulate(base.linear_interpolate(final, _dim_time / wait_time));
+ gui_base->set_modulate(Color(1, 1, 1));
}
}
@@ -5040,18 +5193,12 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio
void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) {
- if (p_pressed) {
- top_split->hide();
- bottom_panel_raise->set_icon(gui_base->get_icon("ShrinkBottomDock", "EditorIcons"));
- } else {
- top_split->show();
- bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
- }
+ top_split->set_visible(!p_pressed);
}
void EditorNode::_update_video_driver_color() {
- //todo probably should de-harcode this and add to editor settings
+ // TODO: Probably should de-hardcode this and add to editor settings.
if (video_driver->get_text() == "GLES2") {
video_driver->add_color_override("font_color", Color::hex(0x5586a4ff));
} else if (video_driver->get_text() == "GLES3") {
@@ -5136,6 +5283,8 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
ClassDB::bind_method("_unhandled_input", &EditorNode::_unhandled_input);
+ ClassDB::bind_method("_update_file_menu_opened", &EditorNode::_update_file_menu_opened);
+ ClassDB::bind_method("_update_file_menu_closed", &EditorNode::_update_file_menu_closed);
ClassDB::bind_method(D_METHOD("push_item", "object", "property", "inspector_only"), &EditorNode::push_item, DEFVAL(""), DEFVAL(false));
@@ -5187,7 +5336,9 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history);
ClassDB::bind_method("_dropped_files", &EditorNode::_dropped_files);
+ ClassDB::bind_method(D_METHOD("_global_menu_action"), &EditorNode::_global_menu_action, DEFVAL(Variant()));
ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode);
+ ClassDB::bind_method("_version_control_menu_option", &EditorNode::_version_control_menu_option);
ClassDB::bind_method("edit_item_resource", &EditorNode::edit_item_resource);
ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base);
@@ -5195,7 +5346,6 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_open_imported"), &EditorNode::_open_imported);
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);
@@ -5380,6 +5530,9 @@ EditorNode::EditorNode() {
}
}
+ // Define a minimum window size to prevent UI elements from overlapping or being cut off
+ OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE);
+
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -5414,6 +5567,10 @@ EditorNode::EditorNode() {
import_csv_translation.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
+ Ref<ResourceImporterCSV> import_csv;
+ import_csv.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(import_csv);
+
Ref<ResourceImporterWAV> import_wav;
import_wav.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_wav);
@@ -5503,12 +5660,16 @@ EditorNode::EditorNode() {
EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false);
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
+ EDITOR_DEF_RST("interface/inspector/default_float_step", 0.001);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::REAL, "interface/inspector/default_float_step", PROPERTY_HINT_EXP_RANGE, "0,1,0"));
EDITOR_DEF_RST("interface/inspector/disable_folding", false);
EDITOR_DEF_RST("interface/inspector/auto_unfold_foreign_scenes", true);
EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "SpatialMaterial,Script,MeshLibrary,TileSet");
+ EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
theme_base = memnew(Control);
@@ -5652,6 +5813,7 @@ EditorNode::EditorNode() {
dock_slot[i]->set_drag_to_rearrange_enabled(true);
dock_slot[i]->set_tabs_rearrange_group(1);
dock_slot[i]->connect("tab_changed", this, "_dock_tab_changed");
+ dock_slot[i]->set_use_hidden_tabs_for_min_size(true);
}
dock_drag_timer = memnew(Timer);
@@ -5810,23 +5972,25 @@ EditorNode::EditorNode() {
PopupMenu *p;
file_menu->set_tooltip(TTR("Operations with scene files."));
+
p = file_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
+ p->add_shortcut(ED_SHORTCUT("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_T), FILE_OPEN_PREV);
+ p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
- p->add_separator();
- p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
- p->add_separator();
- p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/quick_open", TTR("Quick Open..."), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT);
+
p->add_separator();
PopupMenu *pm_export = memnew(PopupMenu);
pm_export->set_name("Export");
@@ -5839,8 +6003,10 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT);
+ p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
recent_scenes = memnew(PopupMenu);
recent_scenes->set_name("RecentScenes");
@@ -5848,7 +6014,7 @@ EditorNode::EditorNode() {
recent_scenes->connect("id_pressed", this, "_open_recent_scene");
p->add_separator();
- p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/file_quit", TTR("Quit"), KEY_MASK_CMD + KEY_Q), FILE_QUIT, true);
project_menu = memnew(MenuButton);
project_menu->set_flat(false);
@@ -5860,10 +6026,22 @@ EditorNode::EditorNode() {
p = project_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings")), RUN_SETTINGS);
- p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings...")), RUN_SETTINGS);
p->connect("id_pressed", this, "_menu_option");
- p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export")), FILE_EXPORT_PROJECT);
+
+ vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
+ vcs_actions_menu->set_name("Version Control");
+ vcs_actions_menu->connect("index_pressed", this, "_version_control_menu_option");
+ p->add_separator();
+ p->add_child(vcs_actions_menu);
+ p->add_submenu_item(TTR("Version Control"), "Version Control");
+ vcs_actions_menu->add_item(TTR("Set Up Version Control"), RUN_VCS_SETTINGS);
+ vcs_actions_menu->add_item(TTR("Shut Down Version Control"), RUN_VCS_SHUT_DOWN);
+
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export...")), FILE_EXPORT_PROJECT);
+ p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
+ p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
@@ -5872,19 +6050,15 @@ EditorNode::EditorNode() {
tool_menu = memnew(PopupMenu);
tool_menu->set_name("Tools");
tool_menu->connect("index_pressed", this, "_tool_menu_option");
- p->add_separator();
p->add_child(tool_menu);
p->add_submenu_item(TTR("Tools"), "Tools");
- tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
- tool_menu->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
- p->add_separator();
- p->add_item(TTR("Install Android Build Template"), FILE_INSTALL_ANDROID_SOURCE);
- p->add_separator();
+ tool_menu->add_item(TTR("Orphan Resource Explorer..."), TOOLS_ORPHAN_RESOURCES);
+ p->add_separator();
#ifdef OSX_ENABLED
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true);
#else
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q), RUN_PROJECT_MANAGER, true);
#endif
menu_hb->add_spacer();
@@ -5932,7 +6106,7 @@ EditorNode::EditorNode() {
p = settings_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings")), SETTINGS_PREFERENCES);
+ p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES);
p->add_separator();
editor_layouts = memnew(PopupMenu);
@@ -5940,16 +6114,13 @@ EditorNode::EditorNode() {
p->add_child(editor_layouts);
editor_layouts->connect("id_pressed", this, "_layout_menu_option");
p->add_submenu_item(TTR("Editor Layout"), "Layouts");
+ p->add_separator();
#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
@@ -5970,11 +6141,8 @@ EditorNode::EditorNode() {
}
p->add_separator();
- p->add_item(TTR("Manage Editor Features"), SETTINGS_MANAGE_FEATURE_PROFILES);
-
- p->add_separator();
-
- p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
+ p->add_item(TTR("Manage Editor Features..."), SETTINGS_MANAGE_FEATURE_PROFILES);
+ p->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
// Help Menu
help_menu = memnew(MenuButton);
@@ -6202,6 +6370,13 @@ EditorNode::EditorNode() {
bottom_panel_hb_editors = memnew(HBoxContainer);
bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL);
bottom_panel_hb->add_child(bottom_panel_hb_editors);
+
+ version_label = memnew(Label);
+ version_label->set_text(VERSION_FULL_CONFIG);
+ // Fade out the version label to be less prominent, but still readable
+ version_label->set_self_modulate(Color(1, 1, 1, 0.6));
+ bottom_panel_hb->add_child(version_label);
+
bottom_panel_raise = memnew(ToolButton);
bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
@@ -6240,13 +6415,13 @@ EditorNode::EditorNode() {
gui_base->add_child(custom_build_manage_templates);
install_android_build_template = memnew(ConfirmationDialog);
- install_android_build_template->set_text(TTR("This will install the Android project for custom builds.\nNote that, in order to use it, it needs to be enabled per export preset."));
+ install_android_build_template->set_text(TTR("This will set up your project for custom Android builds by installing the source template to \"res://android/build\".\nYou can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.).\nNote that in order to make custom builds instead of using pre-built APKs, the \"Use Custom Build\" option should be enabled in the Android export preset."));
install_android_build_template->get_ok()->set_text(TTR("Install"));
install_android_build_template->connect("confirmed", this, "_menu_confirm_current");
gui_base->add_child(install_android_build_template);
remove_android_build_template = memnew(ConfirmationDialog);
- remove_android_build_template->set_text(TTR("Android build template is already installed and it won't be overwritten.\nRemove the \"build\" directory manually before attempting this operation again."));
+ remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again."));
remove_android_build_template->get_ok()->set_text(TTR("Show in File Manager"));
remove_android_build_template->connect("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
gui_base->add_child(remove_android_build_template);
@@ -6298,6 +6473,8 @@ EditorNode::EditorNode() {
file_script->connect("file_selected", this, "_dialog_action");
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+ file_menu->connect("about_to_show", this, "_update_file_menu_opened");
+ file_menu->get_popup()->connect("popup_hide", this, "_update_file_menu_closed");
settings_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -6334,6 +6511,7 @@ EditorNode::EditorNode() {
//more visually meaningful to have this later
raise_bottom_panel_item(AnimationPlayerEditor::singleton);
+ add_editor_plugin(VersionControlEditorPlugin::get_singleton());
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
add_editor_plugin(memnew(VisualShaderEditorPlugin(this)));
@@ -6514,13 +6692,6 @@ EditorNode::EditorNode() {
waiting_for_first_scan = true;
- _dimming = false;
- _dim_time = 0.0f;
- _dim_timer = memnew(Timer);
- _dim_timer->set_wait_time(0.01666f);
- _dim_timer->connect("timeout", this, "_dim_timeout");
- add_child(_dim_timer);
-
print_handler.printfunc = _print_handler;
print_handler.userdata = this;
add_print_handler(&print_handler);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 5dabe529f9..5ecb472e64 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -86,10 +86,6 @@
#include "scene/gui/tree.h"
#include "scene/gui/viewport_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
typedef bool (*EditorBuildCallback)();
@@ -182,8 +178,12 @@ private:
RUN_DEBUG_NAVIGATION,
RUN_DEPLOY_REMOTE_DEBUG,
RUN_RELOAD_SCRIPTS,
+ RUN_VCS_SETTINGS,
+ RUN_VCS_SHUT_DOWN,
SETTINGS_UPDATE_CONTINUOUSLY,
SETTINGS_UPDATE_WHEN_CHANGED,
+ SETTINGS_UPDATE_ALWAYS,
+ SETTINGS_UPDATE_CHANGES,
SETTINGS_UPDATE_SPINNER_HIDE,
SETTINGS_PREFERENCES,
SETTINGS_LAYOUT_SAVE,
@@ -211,6 +211,9 @@ private:
SET_VIDEO_DRIVER_SAVE_AND_RESTART,
+ GLOBAL_NEW_WINDOW,
+ GLOBAL_SCENE,
+
IMPORT_PLUGIN_BASE = 100,
TOOL_MENU_BASE = 1000
@@ -323,6 +326,7 @@ private:
EditorSettingsDialog *settings_config_dialog;
RunSettingsDialog *run_settings_dialog;
ProjectSettingsEditor *project_settings;
+ PopupMenu *vcs_actions_menu;
EditorFileDialog *file;
ExportTemplateManager *export_template_manager;
EditorFeatureProfileManager *feature_profile_manager;
@@ -431,6 +435,7 @@ private:
HBoxContainer *bottom_panel_hb;
HBoxContainer *bottom_panel_hb_editors;
VBoxContainer *bottom_panel_vb;
+ Label *version_label;
ToolButton *bottom_panel_raise;
void _bottom_panel_raise_toggled(bool);
@@ -460,6 +465,8 @@ private:
void _tool_menu_option(int p_idx);
void _update_debug_options();
+ void _update_file_menu_opened();
+ void _update_file_menu_closed();
void _on_plugin_ready(Object *p_script, const String &p_activate_name);
@@ -475,6 +482,7 @@ private:
void _get_scene_metadata(const String &p_file);
void _update_title();
void _update_scene_tabs();
+ void _version_control_menu_option(int p_idx);
void _close_messages();
void _show_messages();
void _vp_resized();
@@ -505,6 +513,7 @@ private:
void _add_to_recent_scenes(const String &p_scene);
void _update_recent_scenes();
void _open_recent_scene(int p_idx);
+ void _global_menu_action(const Variant &p_id, const Variant &p_meta);
void _dropped_files(const Vector<String> &p_files, int p_screen);
void _add_dropped_files_recursive(const Vector<String> &p_files, String to_path);
String _recent_scene;
@@ -630,13 +639,6 @@ private:
static int build_callback_count;
static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
- bool _dimming;
- float _dim_time;
- Timer *_dim_timer;
-
- void _start_dimming(bool p_dimming);
- void _dim_timeout();
-
void _license_tree_selected();
void _update_update_spinner();
@@ -729,6 +731,8 @@ public:
bool item_has_editor(Object *p_object);
void hide_top_editors();
+ void select_editor_by_name(const String &p_name);
+
void open_request(const String &p_path);
bool is_changing_scene() const;
@@ -744,6 +748,7 @@ public:
void fix_dependencies(const String &p_for_file);
void clear_scene() { _cleanup_scene(); }
+ int new_scene();
Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false);
Error load_resource(const String &p_resource, bool p_ignore_broken_deps = false);
@@ -776,6 +781,8 @@ public:
void stop_child_process();
Ref<Theme> get_editor_theme() const { return theme; }
+ Ref<Script> get_object_custom_type_base(const Object *p_object) const;
+ StringName get_object_custom_type_name(const Object *p_object) const;
Ref<Texture> get_object_icon(const Object *p_object, const String &p_fallback = "Object") const;
Ref<Texture> get_class_icon(const String &p_class, const String &p_fallback = "Object") const;
@@ -841,7 +848,7 @@ public:
void save_scene_list(Vector<String> p_scene_filenames);
void restart_editor();
- void dim_editor(bool p_dimming);
+ void dim_editor(bool p_dimming, bool p_force_dim = false);
void edit_current() { _edit_current(); };
@@ -862,6 +869,9 @@ public:
static void add_build_callback(EditorBuildCallback p_callback);
bool ensure_main_scene(bool p_from_native);
+
+ void run_play();
+ void run_stop();
};
struct EditorProgress {
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index c2a845653e..310a107ca9 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -149,6 +149,10 @@ Vector<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>
return textures;
}
+void EditorInterface::set_main_screen_editor(const String &p_name) {
+ EditorNode::get_singleton()->select_editor_by_name(p_name);
+}
+
Control *EditorInterface::get_editor_viewport() {
return EditorNode::get_singleton()->get_viewport();
@@ -207,6 +211,10 @@ String EditorInterface::get_selected_path() const {
return EditorNode::get_singleton()->get_filesystem_dock()->get_selected_path();
}
+String EditorInterface::get_current_path() const {
+ return EditorNode::get_singleton()->get_filesystem_dock()->get_current_path();
+}
+
void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property) {
EditorNode::get_singleton()->push_item(p_obj, p_for_property);
@@ -234,7 +242,7 @@ Control *EditorInterface::get_base_control() {
}
void EditorInterface::set_plugin_enabled(const String &p_plugin, bool p_enabled) {
- EditorNode::get_singleton()->set_addon_plugin_enabled(p_plugin, p_enabled);
+ EditorNode::get_singleton()->set_addon_plugin_enabled(p_plugin, p_enabled, true);
}
bool EditorInterface::is_plugin_enabled(const String &p_plugin) const {
@@ -260,6 +268,10 @@ void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview)
EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
}
+void EditorInterface::set_distraction_free_mode(bool p_enter) {
+ EditorNode::get_singleton()->set_distraction_free_mode(p_enter);
+}
+
EditorInterface *EditorInterface::singleton = NULL;
void EditorInterface::_bind_methods() {
@@ -280,6 +292,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file);
ClassDB::bind_method(D_METHOD("get_selected_path"), &EditorInterface::get_selected_path);
+ ClassDB::bind_method(D_METHOD("get_current_path"), &EditorInterface::get_current_path);
ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled);
ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled);
@@ -288,6 +301,9 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
+
+ ClassDB::bind_method(D_METHOD("set_main_screen_editor", "name"), &EditorInterface::set_main_screen_editor);
+ ClassDB::bind_method(D_METHOD("set_distraction_free_mode", "enter"), &EditorInterface::set_distraction_free_mode);
}
EditorInterface::EditorInterface() {
@@ -313,12 +329,6 @@ void EditorPlugin::remove_autoload_singleton(const String &p_name) {
EditorNode::get_singleton()->get_project_settings()->get_autoload_settings()->autoload_remove(p_name);
}
-Ref<ConfigFile> EditorPlugin::get_config() {
- Ref<ConfigFile> cf = memnew(ConfigFile);
- cf->load(_dir_cache.plus_file("plugin.cfg"));
- return cf;
-}
-
ToolButton *EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) {
ERR_FAIL_NULL_V(p_control, NULL);
return EditorNode::get_singleton()->add_bottom_panel_item(p_title, p_control);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 75c230adb7..63f5a4f87a 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -41,10 +41,6 @@
#include "scene/main/node.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class EditorNode;
class Spatial;
class Camera;
@@ -82,6 +78,7 @@ public:
void select_file(const String &p_file);
String get_selected_path() const;
+ String get_current_path() const;
void inspect_object(Object *p_obj, const String &p_for_property = String());
@@ -103,6 +100,9 @@ public:
Vector<Ref<Texture> > make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, Vector<Transform> *p_transforms, int p_preview_size);
+ void set_main_screen_editor(const String &p_name);
+ void set_distraction_free_mode(bool p_enter);
+
EditorInterface();
};
@@ -118,7 +118,6 @@ class EditorPlugin : public Node {
bool force_draw_over_forwarding_enabled;
String last_main_screen_name;
- String _dir_cache;
protected:
static void _bind_methods();
@@ -237,10 +236,6 @@ public:
void add_autoload_singleton(const String &p_name, const String &p_path);
void remove_autoload_singleton(const String &p_name);
- void set_dir_cache(const String &p_dir) { _dir_cache = p_dir; }
- String get_dir_cache() { return _dir_cache; }
- Ref<ConfigFile> get_config();
-
void enable_plugin();
void disable_plugin();
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index 09577e39e1..514b3ff5d2 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -96,45 +96,59 @@ void EditorPluginSettings::update_plugins() {
if (err2 != OK) {
WARN_PRINTS("Can't load plugin config: " + path);
- } else if (!cf->has_section_key("plugin", "name")) {
- WARN_PRINTS("Plugin misses plugin/name: " + path);
- } else if (!cf->has_section_key("plugin", "author")) {
- WARN_PRINTS("Plugin misses plugin/author: " + path);
- } else if (!cf->has_section_key("plugin", "version")) {
- WARN_PRINTS("Plugin misses plugin/version: " + path);
- } else if (!cf->has_section_key("plugin", "description")) {
- WARN_PRINTS("Plugin misses plugin/description: " + path);
- } else if (!cf->has_section_key("plugin", "script")) {
- WARN_PRINTS("Plugin misses plugin/script: " + path);
} else {
+ bool key_missing = false;
- String d2 = plugins[i];
- String name = cf->get_value("plugin", "name");
- String author = cf->get_value("plugin", "author");
- String version = cf->get_value("plugin", "version");
- String description = cf->get_value("plugin", "description");
- String script = cf->get_value("plugin", "script");
-
- TreeItem *item = plugin_list->create_item(root);
- item->set_text(0, name);
- item->set_tooltip(0, "Name: " + name + "\nPath: " + path + "\nMain Script: " + script + "\nDescription: " + description);
- item->set_metadata(0, d2);
- item->set_text(1, version);
- item->set_metadata(1, script);
- item->set_text(2, author);
- item->set_metadata(2, description);
- item->set_cell_mode(3, TreeItem::CELL_MODE_RANGE);
- item->set_range_config(3, 0, 1, 1);
- item->set_text(3, "Inactive,Active");
- item->set_editable(3, true);
- item->add_button(4, get_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));
-
- if (EditorNode::get_singleton()->is_addon_plugin_enabled(d2)) {
- item->set_custom_color(3, get_color("success_color", "Editor"));
- item->set_range(3, 1);
- } else {
- item->set_custom_color(3, get_color("disabled_font_color", "Editor"));
- item->set_range(3, 0);
+ if (!cf->has_section_key("plugin", "name")) {
+ WARN_PRINTS("Plugin config misses \"plugin/name\" key: " + path);
+ key_missing = true;
+ }
+ if (!cf->has_section_key("plugin", "author")) {
+ WARN_PRINTS("Plugin config misses \"plugin/author\" key: " + path);
+ key_missing = true;
+ }
+ if (!cf->has_section_key("plugin", "version")) {
+ WARN_PRINTS("Plugin config misses \"plugin/version\" key: " + path);
+ key_missing = true;
+ }
+ if (!cf->has_section_key("plugin", "description")) {
+ WARN_PRINTS("Plugin config misses \"plugin/description\" key: " + path);
+ key_missing = true;
+ }
+ if (!cf->has_section_key("plugin", "script")) {
+ WARN_PRINTS("Plugin config misses \"plugin/script\" key: " + path);
+ key_missing = true;
+ }
+
+ if (!key_missing) {
+ String d2 = plugins[i];
+ String name = cf->get_value("plugin", "name");
+ String author = cf->get_value("plugin", "author");
+ String version = cf->get_value("plugin", "version");
+ String description = cf->get_value("plugin", "description");
+ String script = cf->get_value("plugin", "script");
+
+ TreeItem *item = plugin_list->create_item(root);
+ item->set_text(0, name);
+ item->set_tooltip(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description);
+ item->set_metadata(0, d2);
+ item->set_text(1, version);
+ item->set_metadata(1, script);
+ item->set_text(2, author);
+ item->set_metadata(2, description);
+ item->set_cell_mode(3, TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(3, 0, 1, 1);
+ item->set_text(3, "Inactive,Active");
+ item->set_editable(3, true);
+ item->add_button(4, get_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));
+
+ if (EditorNode::get_singleton()->is_addon_plugin_enabled(d2)) {
+ item->set_custom_color(3, get_color("success_color", "Editor"));
+ item->set_range(3, 1);
+ } else {
+ item->set_custom_color(3, get_color("disabled_font_color", "Editor"));
+ item->set_range(3, 0);
+ }
}
}
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index a8ef563368..f456cf7233 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -112,12 +112,13 @@ void EditorPropertyMultilineText::_open_big_text() {
big_text->set_wrap_enabled(true);
big_text_dialog = memnew(AcceptDialog);
big_text_dialog->add_child(big_text);
- big_text_dialog->set_title("Edit Text:");
+ big_text_dialog->set_title(TTR("Edit Text:"));
add_child(big_text_dialog);
}
- big_text_dialog->popup_centered_ratio();
+ big_text_dialog->popup_centered_clamped(Size2(1000, 900) * EDSCALE, 0.8);
big_text->set_text(text->get_text());
+ big_text->grab_focus();
}
void EditorPropertyMultilineText::update_property() {
@@ -208,13 +209,7 @@ EditorPropertyTextEnum::EditorPropertyTextEnum() {
void EditorPropertyPath::_path_selected(const String &p_path) {
- String final_path = p_path;
- if (final_path.is_abs_path()) {
- String res_path = OS::get_singleton()->get_resource_dir() + "/";
- final_path = res_path.path_to_file(final_path);
- }
-
- emit_changed(get_edited_property(), final_path);
+ emit_changed(get_edited_property(), p_path);
update_property();
}
void EditorPropertyPath::_path_pressed() {
@@ -227,13 +222,6 @@ void EditorPropertyPath::_path_pressed() {
}
String full_path = get_edited_object()->get(get_edited_property());
- if (full_path.is_rel_path()) {
-
- if (!DirAccess::exists(full_path.get_base_dir())) {
- DirAccessRef da(DirAccess::create(DirAccess::ACCESS_FILESYSTEM));
- da->make_dir_recursive(full_path.get_base_dir());
- }
- }
dialog->clear_filters();
@@ -389,7 +377,7 @@ void EditorPropertyMember::_property_select() {
type = Variant::Type(i);
}
}
- if (type)
+ if (type != Variant::NIL)
selector->select_method_from_basic_type(type, current);
} else if (hint == MEMBER_METHOD_OF_BASE_TYPE) {
@@ -934,16 +922,29 @@ EditorPropertyFloat::EditorPropertyFloat() {
void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
- Ref<InputEventMouseButton> mb = p_ev;
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
- preset->set_global_position(easing_draw->get_global_transform().xform(mb->get_position()));
- preset->popup();
- }
- if (mb.is_valid() && mb->is_doubleclick() && mb->get_button_index() == BUTTON_LEFT) {
- _setup_spin();
+ const Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid()) {
+ if (mb->is_doubleclick() && mb->get_button_index() == BUTTON_LEFT) {
+ _setup_spin();
+ }
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
+ preset->set_global_position(easing_draw->get_global_transform().xform(mb->get_position()));
+ preset->popup();
+
+ // Ensure the easing doesn't appear as being dragged
+ dragging = false;
+ easing_draw->update();
+ }
+
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ dragging = mb->is_pressed();
+ // Update to display the correct dragging color
+ easing_draw->update();
+ }
}
- Ref<InputEventMouseMotion> mm = p_ev;
+ const Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
@@ -981,13 +982,19 @@ void EditorPropertyEasing::_draw_easing() {
Rect2 r(Point2(), s);
r = r.grow(3);
- int points = 48;
+ const int points = 48;
float prev = 1.0;
- float exp = get_edited_object()->get(get_edited_property());
+ const float exp = get_edited_object()->get(get_edited_property());
- Ref<Font> f = get_font("font", "Label");
- Color color = get_color("font_color", "Label");
+ const Ref<Font> f = get_font("font", "Label");
+ const Color font_color = get_color("font_color", "Label");
+ Color line_color;
+ if (dragging) {
+ line_color = get_color("accent_color", "Editor");
+ } else {
+ line_color = get_color("font_color", "Label") * Color(1, 1, 1, 0.9);
+ }
Vector<Point2> lines;
for (int i = 1; i <= points; i++) {
@@ -995,7 +1002,7 @@ void EditorPropertyEasing::_draw_easing() {
float ifl = i / float(points);
float iflp = (i - 1) / float(points);
- float h = 1.0 - Math::ease(ifl, exp);
+ const float h = 1.0 - Math::ease(ifl, exp);
if (flip) {
ifl = 1.0 - ifl;
@@ -1007,8 +1014,8 @@ void EditorPropertyEasing::_draw_easing() {
prev = h;
}
- easing_draw->draw_multiline(lines, color, 1.0, true);
- f->draw(ci, Point2(10, 10 + f->get_ascent()), String::num(exp, 2), color);
+ easing_draw->draw_multiline(lines, line_color, 1.0, true);
+ f->draw(ci, Point2(10, 10 + f->get_ascent()), String::num(exp, 2), font_color);
}
void EditorPropertyEasing::update_property() {
@@ -1045,6 +1052,9 @@ void EditorPropertyEasing::_spin_value_changed(double p_value) {
void EditorPropertyEasing::_spin_focus_exited() {
spin->hide();
+ // Ensure the easing doesn't appear as being dragged
+ dragging = false;
+ easing_draw->update();
}
void EditorPropertyEasing::setup(bool p_full, bool p_flip) {
@@ -1107,6 +1117,7 @@ EditorPropertyEasing::EditorPropertyEasing() {
spin->hide();
add_child(spin);
+ dragging = false;
flip = false;
full = false;
}
@@ -1854,10 +1865,20 @@ void EditorPropertyColor::_popup_closed() {
emit_changed(get_edited_property(), picker->get_pick_color(), "", false);
}
+void EditorPropertyColor::_picker_created() {
+ // get default color picker mode from editor settings
+ int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
+ if (default_color_mode == 1)
+ picker->get_picker()->set_hsv_mode(true);
+ else if (default_color_mode == 2)
+ picker->get_picker()->set_raw_mode(true);
+}
+
void EditorPropertyColor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_color_changed"), &EditorPropertyColor::_color_changed);
ClassDB::bind_method(D_METHOD("_popup_closed"), &EditorPropertyColor::_popup_closed);
+ ClassDB::bind_method(D_METHOD("_picker_created"), &EditorPropertyColor::_picker_created);
}
void EditorPropertyColor::update_property() {
@@ -1876,6 +1897,7 @@ EditorPropertyColor::EditorPropertyColor() {
picker->set_flat(true);
picker->connect("color_changed", this, "_color_changed");
picker->connect("popup_closed", this, "_popup_closed");
+ picker->connect("picker_created", this, "_picker_created");
}
////////////// NODE PATH //////////////////////
@@ -2412,7 +2434,6 @@ void EditorPropertyResource::_update_menu_items() {
menu->add_separator();
menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
}
- } else {
}
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
@@ -2553,7 +2574,7 @@ void EditorPropertyResource::update_property() {
if (res.is_valid() != assign->is_toggle_mode()) {
assign->set_toggle_mode(res.is_valid());
}
-#ifdef TOOLS_ENABLED
+
if (res.is_valid() && get_edited_object()->editor_is_section_unfolded(get_edited_property())) {
if (!sub_inspector) {
@@ -2622,7 +2643,6 @@ void EditorPropertyResource::update_property() {
}
}
}
-#endif
}
preview->set_texture(Ref<Texture>());
@@ -2904,6 +2924,8 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) {
bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) {
+ float default_float_step = EDITOR_GET("interface/inspector/default_float_step");
+
switch (p_type) {
// atomic types
@@ -3010,7 +3032,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} else {
EditorPropertyFloat *editor = memnew(EditorPropertyFloat);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
bool exp_range = false;
bool greater = true, lesser = true;
@@ -3107,7 +3129,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
case Variant::VECTOR2: {
EditorPropertyVector2 *editor = memnew(EditorPropertyVector2);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3125,7 +3147,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break; // 5
case Variant::RECT2: {
EditorPropertyRect2 *editor = memnew(EditorPropertyRect2);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3142,7 +3164,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::VECTOR3: {
EditorPropertyVector3 *editor = memnew(EditorPropertyVector3);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3160,7 +3182,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::TRANSFORM2D: {
EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3178,7 +3200,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::PLANE: {
EditorPropertyPlane *editor = memnew(EditorPropertyPlane);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3195,7 +3217,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::QUAT: {
EditorPropertyQuat *editor = memnew(EditorPropertyQuat);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3212,7 +3234,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break; // 10
case Variant::AABB: {
EditorPropertyAABB *editor = memnew(EditorPropertyAABB);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3229,7 +3251,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::BASIS: {
EditorPropertyBasis *editor = memnew(EditorPropertyBasis);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
@@ -3246,7 +3268,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
} break;
case Variant::TRANSFORM: {
EditorPropertyTransform *editor = memnew(EditorPropertyTransform);
- double min = -65535, max = 65535, step = 0.001;
+ double min = -65535, max = 65535, step = default_float_step;
bool hide_slider = true;
if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 0a4a07cdc0..b8d6aa00c2 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -311,6 +311,7 @@ class EditorPropertyEasing : public EditorProperty {
EditorSpinSlider *spin;
bool setting;
+ bool dragging;
bool full;
bool flip;
@@ -493,6 +494,7 @@ class EditorPropertyColor : public EditorProperty {
ColorPickerButton *picker;
void _color_changed(const Color &p_color);
void _popup_closed();
+ void _picker_created();
protected:
static void _bind_methods();
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 347699c632..8abe91bdc1 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -264,15 +264,15 @@ void EditorPropertyArray::update_property() {
edit->set_text(String("(Nil) ") + arrtype);
edit->set_pressed(false);
if (vbox) {
+ set_bottom_editor(NULL);
memdelete(vbox);
+ vbox = NULL;
}
return;
}
edit->set_text(arrtype + " (size " + itos(array.call("size")) + ")");
-#ifdef TOOLS_ENABLED
-
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
edit->set_pressed(unfolded);
@@ -312,7 +312,8 @@ void EditorPropertyArray::update_property() {
} else {
//bye bye children of the box
while (vbox->get_child_count() > 2) {
- memdelete(vbox->get_child(2));
+ vbox->get_child(2)->queue_delete(); // button still needed after pressed is called
+ vbox->remove_child(vbox->get_child(2));
}
}
@@ -396,7 +397,6 @@ void EditorPropertyArray::update_property() {
vbox = NULL;
}
}
-#endif
}
void EditorPropertyArray::_remove_pressed(int p_index) {
@@ -414,8 +414,6 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
}
void EditorPropertyArray::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- }
}
void EditorPropertyArray::_edit_pressed() {
@@ -635,7 +633,9 @@ void EditorPropertyDictionary::update_property() {
edit->set_text("Dictionary (Nil)"); //This provides symmetry with the array property.
edit->set_pressed(false);
if (vbox) {
+ set_bottom_editor(NULL);
memdelete(vbox);
+ vbox = NULL;
}
return;
}
@@ -644,8 +644,6 @@ void EditorPropertyDictionary::update_property() {
edit->set_text("Dictionary (size " + itos(dict.size()) + ")");
-#ifdef TOOLS_ENABLED
-
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
edit->set_pressed(unfolded);
@@ -960,7 +958,6 @@ void EditorPropertyDictionary::update_property() {
vbox = NULL;
}
}
-#endif
}
void EditorPropertyDictionary::_object_id_selected(const String &p_property, ObjectID p_id) {
@@ -968,9 +965,6 @@ void EditorPropertyDictionary::_object_id_selected(const String &p_property, Obj
}
void EditorPropertyDictionary::_notification(int p_what) {
-
- if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
- }
}
void EditorPropertyDictionary::_edit_pressed() {
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 327e61cea3..77e9220b6d 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -46,8 +46,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
if (get_script_instance() && get_script_instance()->has_method("handles")) {
return get_script_instance()->call("handles", p_type);
}
- ERR_EXPLAIN("EditorResourcePreviewGenerator::handles needs to be overridden");
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "EditorResourcePreviewGenerator::handles needs to be overridden.");
}
Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 &p_size) const {
@@ -55,8 +54,7 @@ Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const S
if (get_script_instance() && get_script_instance()->has_method("generate")) {
return get_script_instance()->call("generate", p_from, p_size);
}
- ERR_EXPLAIN("EditorResourcePreviewGenerator::generate needs to be overridden");
- ERR_FAIL_V(Ref<Texture>());
+ ERR_FAIL_V_MSG(Ref<Texture>(), "EditorResourcePreviewGenerator::generate needs to be overridden.");
}
Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 &p_size) const {
@@ -118,7 +116,7 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
uint64_t modified_time = 0;
if (p_str.begins_with("ID:")) {
- hash = p_str.get_slicec(':', 2).to_int();
+ hash = uint32_t(p_str.get_slicec(':', 2).to_int64());
path = "ID:" + p_str.get_slicec(':', 1);
} else {
modified_time = FileAccess::get_modified_time(path);
@@ -297,8 +295,9 @@ void EditorResourcePreview::_thread() {
//update modified time
f = FileAccess::open(file, FileAccess::WRITE);
- f->store_line(itos(modtime));
+ f->store_line(itos(thumbnail_size));
f->store_line(itos(has_small_texture));
+ f->store_line(itos(modtime));
f->store_line(md5);
memdelete(f);
}
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index e4e32b2ce0..7b5ec9e772 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -37,7 +37,8 @@ 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, const bool &p_skip_breakpoints) {
List<String> args;
@@ -162,6 +163,10 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
args.push_back(bpoints);
}
+ if (p_skip_breakpoints) {
+ args.push_back("--skip-breakpoints");
+ }
+
if (p_scene != "") {
args.push_back(p_scene);
}
diff --git a/editor/editor_run.h b/editor/editor_run.h
index 9127c62030..42724630b5 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, const bool &p_skip_breakpoints = false);
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..abff8190af 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++) {
@@ -307,7 +316,7 @@ SectionedInspector::SectionedInspector() :
add_constant_override("autohide", 1); // Fixes the dragger always showing up
VBoxContainer *left_vb = memnew(VBoxContainer);
- left_vb->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
+ left_vb->set_custom_minimum_size(Size2(190, 0) * EDSCALE);
add_child(left_vb);
sections->set_v_size_flags(SIZE_EXPAND_FILL);
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 2c0449398e..479fe5f0cb 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -321,30 +321,24 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::REAL, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/main_font_size", 14);
hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- _initial_set("interface/editor/main_font_antialiased", true);
- _initial_set("interface/editor/main_font_hinting", 2);
- hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT);
+ _initial_set("interface/editor/code_font_size", 14);
+ hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT);
+ _initial_set("interface/editor/font_antialiased", true);
+ _initial_set("interface/editor/font_hinting", 0);
+ hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto,None,Light,Normal", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font", "");
hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font_bold", "");
hints["interface/editor/main_font_bold"] = PropertyInfo(Variant::STRING, "interface/editor/main_font_bold", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
- _initial_set("interface/editor/code_font_size", 14);
- hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT);
- _initial_set("interface/editor/code_font_antialiased", true);
- _initial_set("interface/editor/code_font_hinting", 2);
- hints["interface/editor/code_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/code_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/code_font", "");
hints["interface/editor/code_font"] = PropertyInfo(Variant::STRING, "interface/editor/code_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/dim_editor_on_dialog_popup", true);
- _initial_set("interface/editor/dim_amount", 0.6f);
- hints["interface/editor/dim_amount"] = PropertyInfo(Variant::REAL, "interface/editor/dim_amount", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
- _initial_set("interface/editor/dim_transition_time", 0.08f);
- hints["interface/editor/dim_transition_time"] = PropertyInfo(Variant::REAL, "interface/editor/dim_transition_time", PROPERTY_HINT_RANGE, "0,1,0.001", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/low_processor_mode_sleep_usec", 6900); // ~144 FPS
- hints["interface/editor/low_processor_mode_sleep_usec"] = PropertyInfo(Variant::REAL, "interface/editor/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "1,100000,1", PROPERTY_USAGE_DEFAULT);
+ hints["interface/editor/low_processor_mode_sleep_usec"] = PropertyInfo(Variant::REAL, "interface/editor/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "1,100000,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/unfocused_low_processor_mode_sleep_usec", 50000); // 20 FPS
- hints["interface/editor/unfocused_low_processor_mode_sleep_usec"] = PropertyInfo(Variant::REAL, "interface/editor/unfocused_low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "1,100000,1", PROPERTY_USAGE_DEFAULT);
+ hints["interface/editor/unfocused_low_processor_mode_sleep_usec"] = PropertyInfo(Variant::REAL, "interface/editor/unfocused_low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "1,100000,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/separate_distraction_mode", false);
+ _initial_set("interface/editor/automatically_open_screenshots", true);
_initial_set("interface/editor/hide_console_window", false);
_initial_set("interface/editor/save_each_scene_on_quit", true); // Regression
_initial_set("interface/editor/quit_confirmation", true);
@@ -446,22 +440,27 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/indent/draw_tabs", true);
_initial_set("text_editor/indent/draw_spaces", false);
- // Line numbers
- _initial_set("text_editor/line_numbers/show_line_numbers", true);
- _initial_set("text_editor/line_numbers/line_numbers_zero_padded", false);
- _initial_set("text_editor/line_numbers/show_bookmark_gutter", true);
- _initial_set("text_editor/line_numbers/show_breakpoint_gutter", true);
- _initial_set("text_editor/line_numbers/show_info_gutter", true);
- _initial_set("text_editor/line_numbers/code_folding", true);
- _initial_set("text_editor/line_numbers/word_wrap", false);
- _initial_set("text_editor/line_numbers/show_line_length_guideline", false);
- _initial_set("text_editor/line_numbers/line_length_guideline_column", 80);
- hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 1");
-
- // Open scripts
- _initial_set("text_editor/open_scripts/smooth_scrolling", true);
- _initial_set("text_editor/open_scripts/v_scroll_speed", 80);
- _initial_set("text_editor/open_scripts/show_members_overview", true);
+ // Navigation
+ _initial_set("text_editor/navigation/smooth_scrolling", true);
+ _initial_set("text_editor/navigation/v_scroll_speed", 80);
+ _initial_set("text_editor/navigation/show_minimap", true);
+ _initial_set("text_editor/navigation/minimap_width", 80);
+ hints["text_editor/navigation/minimap_width"] = PropertyInfo(Variant::INT, "text_editor/navigation/minimap_width", PROPERTY_HINT_RANGE, "50,250,1");
+
+ // Appearance
+ _initial_set("text_editor/appearance/show_line_numbers", true);
+ _initial_set("text_editor/appearance/line_numbers_zero_padded", false);
+ _initial_set("text_editor/appearance/show_bookmark_gutter", true);
+ _initial_set("text_editor/appearance/show_breakpoint_gutter", true);
+ _initial_set("text_editor/appearance/show_info_gutter", true);
+ _initial_set("text_editor/appearance/code_folding", true);
+ _initial_set("text_editor/appearance/word_wrap", false);
+ _initial_set("text_editor/appearance/show_line_length_guideline", false);
+ _initial_set("text_editor/appearance/line_length_guideline_column", 80);
+ hints["text_editor/appearance/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/appearance/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 1");
+
+ // Script list
+ _initial_set("text_editor/script_list/show_members_overview", true);
// Files
_initial_set("text_editor/files/trim_trailing_whitespace_on_save", false);
@@ -483,7 +482,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Completion
_initial_set("text_editor/completion/idle_parse_delay", 2.0);
hints["text_editor/completion/idle_parse_delay"] = PropertyInfo(Variant::REAL, "text_editor/completion/idle_parse_delay", PROPERTY_HINT_RANGE, "0.1, 10, 0.01");
- _initial_set("text_editor/completion/auto_brace_complete", false);
+ _initial_set("text_editor/completion/auto_brace_complete", true);
+ _initial_set("text_editor/completion/code_complete_delay", 0.3);
+ hints["text_editor/completion/code_complete_delay"] = PropertyInfo(Variant::REAL, "text_editor/completion/code_complete_delay", PROPERTY_HINT_RANGE, "0.01, 5, 0.01");
_initial_set("text_editor/completion/put_callhint_tooltip_below_current_line", true);
_initial_set("text_editor/completion/callhint_tooltip_offset", Vector2());
_initial_set("text_editor/completion/complete_file_paths", true);
@@ -565,6 +566,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// 2D
_initial_set("editors/2d/grid_color", Color(1.0, 1.0, 1.0, 0.07));
_initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8));
+ _initial_set("editors/2d/smart_snapping_line_color", Color(0.9, 0.1, 0.1));
_initial_set("editors/2d/bone_width", 5);
_initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9));
_initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.9));
@@ -612,10 +614,22 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("run/output/always_open_output_on_play", true);
_initial_set("run/output/always_close_output_on_stop", false);
+ /* Network */
+
+ // Debug
+ _initial_set("network/debug/remote_host", "127.0.0.1"); // Hints provided in setup_network
+
+ _initial_set("network/debug/remote_port", 6007);
+ hints["network/debug/remote_port"] = PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1");
+
+ // SSL
+ _initial_set("network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH);
+ hints["network/ssl/editor_ssl_certificates"] = PropertyInfo(Variant::STRING, "network/ssl/editor_ssl_certificates", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem");
+
/* Extra config */
_initial_set("project_manager/sorting_order", 0);
- hints["project_manager/sorting_order"] = PropertyInfo(Variant::INT, "project_manager/sorting_order", PROPERTY_HINT_ENUM, "Name,Last Modified");
+ hints["project_manager/sorting_order"] = PropertyInfo(Variant::INT, "project_manager/sorting_order", PROPERTY_HINT_ENUM, "Name,Path,Last Modified");
if (p_extra_config.is_valid()) {
@@ -777,10 +791,16 @@ void EditorSettings::create() {
if (d->file_exists(exe_path + "/._sc_")) {
self_contained = true;
- extra_config->load(exe_path + "/._sc_");
+ Error err = extra_config->load(exe_path + "/._sc_");
+ if (err != OK) {
+ ERR_PRINTS("Can't load config from path: " + exe_path + "/._sc_");
+ }
} else if (d->file_exists(exe_path + "/_sc_")) {
self_contained = true;
- extra_config->load(exe_path + "/_sc_");
+ Error err = extra_config->load(exe_path + "/_sc_");
+ if (err != OK) {
+ ERR_PRINTS("Can't load config from path: " + exe_path + "/_sc_");
+ }
}
memdelete(d);
@@ -991,11 +1011,11 @@ void EditorSettings::setup_network() {
List<IP_Address> local_ip;
IP::get_singleton()->get_local_addresses(&local_ip);
- String lip = "127.0.0.1";
String hint;
String current = has_setting("network/debug/remote_host") ? get("network/debug/remote_host") : "";
- int port = has_setting("network/debug/remote_port") ? (int)get("network/debug/remote_port") : 6007;
+ String selected = "127.0.0.1";
+ // Check that current remote_host is a valid interface address and populate hints.
for (List<IP_Address>::Element *E = local_ip.front(); E; E = E->next()) {
String ip = E->get();
@@ -1006,22 +1026,18 @@ void EditorSettings::setup_network() {
// Same goes for IPv4 link-local (APIPA) addresses.
if (ip.begins_with("169.254.")) // 169.254.0.0/16
continue;
+ // Select current IP (found)
if (ip == current)
- lip = current; //so it saves
+ selected = ip;
if (hint != "")
hint += ",";
hint += ip;
}
- _initial_set("network/debug/remote_host", lip);
+ // Add hints with valid IP addresses to remote_host property.
add_property_hint(PropertyInfo(Variant::STRING, "network/debug/remote_host", PROPERTY_HINT_ENUM, hint));
-
- _initial_set("network/debug/remote_port", port);
- add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1"));
-
- // Editor SSL certificates override
- _initial_set("network/ssl/editor_ssl_certificates", _SYSTEM_CERTS_PATH);
- add_property_hint(PropertyInfo(Variant::STRING, "network/ssl/editor_ssl_certificates", PROPERTY_HINT_GLOBAL_FILE, "*.crt,*.pem"));
+ // Fix potentially invalid remote_host due to network change.
+ set("network/debug/remote_host", selected);
}
void EditorSettings::save() {
@@ -1195,6 +1211,11 @@ String EditorSettings::get_script_templates_dir() const {
return get_settings_dir().plus_file("script_templates");
}
+String EditorSettings::get_project_script_templates_dir() const {
+
+ return ProjectSettings::get_singleton()->get("editor/script_templates_search_path");
+}
+
// Cache directory
String EditorSettings::get_cache_dir() const {
@@ -1212,9 +1233,12 @@ String EditorSettings::get_feature_profiles_dir() const {
void EditorSettings::set_project_metadata(const String &p_section, const String &p_key, Variant p_data) {
Ref<ConfigFile> cf = memnew(ConfigFile);
String path = get_project_settings_dir().plus_file("project_metadata.cfg");
- cf->load(path);
+ Error err;
+ err = cf->load(path);
+ ERR_FAIL_COND(err != OK && err != ERR_FILE_NOT_FOUND);
cf->set_value(p_section, p_key, p_data);
- cf->save(path);
+ err = cf->save(path);
+ ERR_FAIL_COND(err != OK);
}
Variant EditorSettings::get_project_metadata(const String &p_section, const String &p_key, Variant p_default) const {
@@ -1412,10 +1436,14 @@ bool EditorSettings::is_default_text_editor_theme() {
return _is_default_text_editor_theme(p_file.get_file().to_lower());
}
-Vector<String> EditorSettings::get_script_templates(const String &p_extension) {
+Vector<String> EditorSettings::get_script_templates(const String &p_extension, const String &p_custom_path) {
Vector<String> templates;
- DirAccess *d = DirAccess::open(get_script_templates_dir());
+ String template_dir = get_script_templates_dir();
+ if (!p_custom_path.empty()) {
+ template_dir = p_custom_path;
+ }
+ DirAccess *d = DirAccess::open(template_dir);
if (d) {
d->list_dir_begin();
String file = d->get_next();
@@ -1446,10 +1474,7 @@ void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcu
bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const {
const Map<String, Ref<ShortCut> >::Element *E = shortcuts.find(p_name);
- if (!E) {
- ERR_EXPLAIN("Unknown Shortcut: " + p_name);
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + ".");
return E->get()->is_shortcut(p_event);
}
@@ -1478,10 +1503,8 @@ Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) {
}
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
- if (!sc.is_valid()) {
- ERR_EXPLAIN("Used ED_GET_SHORTCUT with invalid shortcut: " + p_path);
- ERR_FAIL_COND_V(!sc.is_valid(), sc);
- }
+
+ ERR_FAIL_COND_V_MSG(!sc.is_valid(), sc, "Used ED_GET_SHORTCUT with invalid shortcut: " + p_path + ".");
return sc;
}
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 890850629e..0738185e95 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -166,6 +166,7 @@ public:
String get_project_settings_dir() const;
String get_text_editor_themes_dir() const;
String get_script_templates_dir() const;
+ String get_project_script_templates_dir() const;
String get_cache_dir() const;
String get_feature_profiles_dir() const;
@@ -187,7 +188,7 @@ public:
bool save_text_editor_theme_as(String p_file);
bool is_default_text_editor_theme();
- Vector<String> get_script_templates(const String &p_extension);
+ Vector<String> get_script_templates(const String &p_extension, const String &p_custom_path = String());
String get_editor_layouts_config() const;
void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index dcb106899e..35fe366526 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -38,51 +38,57 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
}
String EditorSpinSlider::get_text_value() const {
- int zeros = Math::step_decimals(get_step());
- return String::num(get_value(), zeros);
+ return String::num(get_value(), Math::range_step_decimals(get_step()));
}
+
void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
if (read_only)
return;
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid()) {
- if (mb->is_pressed()) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- if (updown_offset != -1 && mb->get_position().x > updown_offset) {
- //there is an updown, so use it.
- if (mb->get_position().y < get_size().height / 2) {
- set_value(get_value() + get_step());
+ if (updown_offset != -1 && mb->get_position().x > updown_offset) {
+ //there is an updown, so use it.
+ if (mb->get_position().y < get_size().height / 2) {
+ set_value(get_value() + get_step());
+ } else {
+ set_value(get_value() - get_step());
+ }
+ return;
} else {
- set_value(get_value() - get_step());
+
+ grabbing_spinner_attempt = true;
+ grabbing_spinner_dist_cache = 0;
+ pre_grab_value = get_value();
+ grabbing_spinner = false;
+ grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position();
}
- return;
} else {
- grabbing_spinner_attempt = true;
- grabbing_spinner_dist_cache = 0;
- pre_grab_value = get_value();
- grabbing_spinner = false;
- grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position();
- }
- } else {
+ if (grabbing_spinner_attempt) {
- if (grabbing_spinner_attempt) {
+ if (grabbing_spinner) {
- if (grabbing_spinner) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
+ update();
+ } else {
+ _focus_entered();
+ }
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
- update();
- } else {
- _focus_entered();
+ grabbing_spinner = false;
+ grabbing_spinner_attempt = false;
}
-
- grabbing_spinner = false;
- grabbing_spinner_attempt = false;
}
+ } else if (mb->get_button_index() == BUTTON_WHEEL_UP || mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+
+ if (grabber->is_visible())
+ call_deferred("update");
}
}
@@ -132,20 +138,39 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
+
+ if (grabbing_grabber) {
+ if (mb.is_valid()) {
+
+ if (mb->get_button_index() == BUTTON_WHEEL_UP) {
+ set_value(get_value() + get_step());
+ mousewheel_over_grabber = true;
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ set_value(get_value() - get_step());
+ mousewheel_over_grabber = true;
+ }
+ }
+ }
+
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
grabbing_grabber = true;
- grabbing_ratio = get_as_ratio();
- grabbing_from = grabber->get_transform().xform(mb->get_position()).x;
+ if (!mousewheel_over_grabber) {
+ grabbing_ratio = get_as_ratio();
+ grabbing_from = grabber->get_transform().xform(mb->get_position()).x;
+ }
} else {
grabbing_grabber = false;
+ mousewheel_over_grabber = false;
}
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && grabbing_grabber) {
+ if (mousewheel_over_grabber)
+ return;
float grabbing_ofs = (grabber->get_transform().xform(mm->get_position()).x - grabbing_from) / float(grabber_range);
set_as_ratio(grabbing_ratio + grabbing_ofs);
@@ -261,6 +286,11 @@ void EditorSpinSlider::_notification(int p_what) {
grabber->set_size(Size2(0, 0));
grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5);
+
+ if (mousewheel_over_grabber) {
+ Input::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size);
+ }
+
grabber_range = width;
}
}
@@ -347,6 +377,11 @@ void EditorSpinSlider::_value_input_closed() {
//focus_exited signal
void EditorSpinSlider::_value_focus_exited() {
+
+ // discontinue because the focus_exit was caused by right-click context menu
+ if (value_input->get_menu()->is_visible())
+ return;
+
_evaluate_input_text();
// focus is not on the same element after the vlalue_input was exited
// -> focus is on next element
@@ -451,6 +486,7 @@ EditorSpinSlider::EditorSpinSlider() {
grabber->connect("gui_input", this, "_grabber_gui_input");
mouse_over_spin = false;
mouse_over_grabber = false;
+ mousewheel_over_grabber = false;
grabbing_grabber = false;
grabber_range = 1;
value_input = memnew(LineEdit);
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index d91380e175..2dc6e2c2f2 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -48,6 +48,7 @@ class EditorSpinSlider : public Range {
bool mouse_over_spin;
bool mouse_over_grabber;
+ bool mousewheel_over_grabber;
bool grabbing_grabber;
int grabbing_from;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 4eceb09792..42c55681ae 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -108,16 +108,17 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
#ifdef SVG_ENABLED
Dictionary dark_icon_color_dictionary;
if (!p_dark_theme) {
- //convert color: FROM TO
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#4f4f4f"); // common icon color
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#000000"); // white
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#000000"); // script darker color
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#bb6dff"); // animation
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#ff5f5f"); // spatial
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#6d90ff"); // 2d
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#0843ff"); // 2d dark
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#29d739"); // control
+ // convert color: FROM TO
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // common icon color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // white
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#363636"); // script darker color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f9f9f9", "#606060"); // scrollbar grabber highlight color
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#a85de9"); // animation
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#cd3838"); // spatial
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#3d64dd"); // 2d
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#1a3eac"); // 2d dark
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#2fa139"); // control
// rainbow
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff7070", "#ff2929"); // red
@@ -140,7 +141,18 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00db50"); // add (green)
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84c2ff", "#5caeff"); // selection (blue)
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#e3383d"); // key xform (red)
+ // Animation editor tracks
+ // The property track icon color is set by the common icon color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea9568", "#bd5e2c"); // 3D Transform track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#66f376", "#16a827"); // Call Method track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5792f6", "#236be6"); // Bezier Curve track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eae668", "#9f9722"); // Audio Playback track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b76ef0", "#9853ce"); // Animation Playback track
+
+ // TileSet editor icons
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fce844", "#aa8d24"); // New Single Tile
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4490fc", "#0350bd"); // New Autotile
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c9cfd4", "#828f9b"); // New Atlas
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#69ecbd", "#25e3a0"); // VS variant
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8da6f0", "#6d8eeb"); // VS bool
@@ -333,6 +345,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color color_disabled = mono_color.inverted().linear_interpolate(base_color, 0.7);
const Color color_disabled_bg = mono_color.inverted().linear_interpolate(base_color, 0.9);
+ Color icon_color_hover = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45);
+ icon_color_hover.a = 1.0;
+ // Make the pressed icon color overbright because icons are not completely white on a dark theme.
+ // On a light theme, icons are dark, so we need to modulate them with an even brighter color.
+ Color icon_color_pressed = accent_color * (dark_theme ? 1.15 : 3.5);
+ icon_color_pressed.a = 1.0;
+
const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1);
const Color highlight_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.2);
@@ -345,6 +364,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("dark_color_3", "Editor", dark_color_3);
theme->set_color("contrast_color_1", "Editor", contrast_color_1);
theme->set_color("contrast_color_2", "Editor", contrast_color_2);
+ theme->set_color("box_selection_fill_color", "Editor", accent_color * Color(1, 1, 1, 0.3));
+ theme->set_color("box_selection_stroke_color", "Editor", accent_color * Color(1, 1, 1, 0.8));
theme->set_color("font_color", "Editor", font_color);
theme->set_color("highlighted_font_color", "Editor", font_color_hl);
@@ -557,9 +578,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color_hover", "Button", font_color_hl);
theme->set_color("font_color_pressed", "Button", accent_color);
theme->set_color("font_color_disabled", "Button", font_color_disabled);
- theme->set_color("icon_color_hover", "Button", font_color_hl);
- // make icon color value bigger because icon image is not complete white
- theme->set_color("icon_color_pressed", "Button", Color(accent_color.r * 1.15, accent_color.g * 1.15, accent_color.b * 1.15, accent_color.a));
+ theme->set_color("icon_color_hover", "Button", icon_color_hover);
+ theme->set_color("icon_color_pressed", "Button", icon_color_pressed);
// OptionButton
theme->set_stylebox("normal", "OptionButton", style_widget);
@@ -572,7 +592,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color_hover", "OptionButton", font_color_hl);
theme->set_color("font_color_pressed", "OptionButton", accent_color);
theme->set_color("font_color_disabled", "OptionButton", font_color_disabled);
- theme->set_color("icon_color_hover", "OptionButton", font_color_hl);
+ theme->set_color("icon_color_hover", "OptionButton", icon_color_hover);
theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons"));
theme->set_constant("arrow_margin", "OptionButton", default_margin_size * EDSCALE);
theme->set_constant("modulate_arrow", "OptionButton", true);
@@ -593,7 +613,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color_hover", "CheckButton", font_color_hl);
theme->set_color("font_color_pressed", "CheckButton", accent_color);
theme->set_color("font_color_disabled", "CheckButton", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckButton", font_color_hl);
+ theme->set_color("icon_color_hover", "CheckButton", icon_color_hover);
theme->set_constant("hseparation", "CheckButton", 4 * EDSCALE);
theme->set_constant("check_vadjust", "CheckButton", 0 * EDSCALE);
@@ -618,7 +638,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color_hover", "CheckBox", font_color_hl);
theme->set_color("font_color_pressed", "CheckBox", accent_color);
theme->set_color("font_color_disabled", "CheckBox", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckBox", font_color_hl);
+ theme->set_color("icon_color_hover", "CheckBox", icon_color_hover);
theme->set_constant("hseparation", "CheckBox", 4 * EDSCALE);
theme->set_constant("check_vadjust", "CheckBox", 0 * EDSCALE);
@@ -665,12 +685,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Tree
theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons"));
- theme->set_icon("arrow_up", "Tree", theme->get_icon("GuiTreeArrowUp", "EditorIcons"));
theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
theme->set_icon("updown", "Tree", theme->get_icon("GuiTreeUpdown", "EditorIcons"));
theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons"));
- theme->set_icon("select_option", "Tree", theme->get_icon("GuiTreeOption", "EditorIcons"));
theme->set_stylebox("bg_focus", "Tree", style_focus);
theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
@@ -684,7 +702,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("drop_position_color", "Tree", accent_color);
theme->set_constant("vseparation", "Tree", (extra_spacing + default_margin_size) * EDSCALE);
theme->set_constant("hseparation", "Tree", (extra_spacing + default_margin_size) * EDSCALE);
- theme->set_constant("guide_width", "Tree", border_width);
theme->set_constant("item_margin", "Tree", 3 * default_margin_size * EDSCALE);
theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE);
theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01);
@@ -697,6 +714,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_tree_btn->set_border_width_all(0);
theme->set_stylebox("button_pressed", "Tree", style_tree_btn);
+ Ref<StyleBoxFlat> style_tree_hover = style_default->duplicate();
+ style_tree_hover->set_bg_color(highlight_color * Color(1, 1, 1, 0.4));
+ style_tree_hover->set_border_width_all(0);
+ theme->set_stylebox("hover", "Tree", style_tree_hover);
+
Ref<StyleBoxFlat> style_tree_focus = style_default->duplicate();
style_tree_focus->set_bg_color(highlight_color);
style_tree_focus->set_border_width_all(0);
@@ -975,8 +997,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// GraphEdit
theme->set_stylebox("bg", "GraphEdit", style_tree_bg);
- theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.15));
- theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.07));
+ if (dark_theme) {
+ theme->set_color("grid_major", "GraphEdit", Color(1.0, 1.0, 1.0, 0.15));
+ theme->set_color("grid_minor", "GraphEdit", Color(1.0, 1.0, 1.0, 0.07));
+ } else {
+ theme->set_color("grid_major", "GraphEdit", Color(0.0, 0.0, 0.0, 0.15));
+ theme->set_color("grid_minor", "GraphEdit", Color(0.0, 0.0, 0.0, 0.07));
+ }
theme->set_color("activity", "GraphEdit", accent_color);
theme->set_icon("minus", "GraphEdit", theme->get_icon("ZoomLess", "EditorIcons"));
theme->set_icon("more", "GraphEdit", theme->get_icon("ZoomMore", "EditorIcons"));
@@ -1041,6 +1068,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("title_color", "GraphNode", default_node_color);
default_node_color.a = 0.7;
theme->set_color("close_color", "GraphNode", default_node_color);
+ theme->set_color("resizer_color", "GraphNode", default_node_color);
theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE);
theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE);
@@ -1058,6 +1086,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// FileDialog
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
+ // Use a different color for folder icons to make them easier to distinguish from files.
+ // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color.
+ theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).linear_interpolate(accent_color, 0.7));
theme->set_color("files_disabled", "FileDialog", font_color_disabled);
// color picker
diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp
new file mode 100644
index 0000000000..4df2a06736
--- /dev/null
+++ b/editor/editor_vcs_interface.cpp
@@ -0,0 +1,194 @@
+/*************************************************************************/
+/* editor_vcs_interface.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_vcs_interface.h"
+
+EditorVCSInterface *EditorVCSInterface::singleton = NULL;
+
+void EditorVCSInterface::_bind_methods() {
+
+ // Proxy end points that act as fallbacks to unavailability of a function in the VCS addon
+ ClassDB::bind_method(D_METHOD("_initialize", "project_root_path"), &EditorVCSInterface::_initialize);
+ ClassDB::bind_method(D_METHOD("_get_is_vcs_intialized"), &EditorVCSInterface::_get_is_vcs_intialized);
+ ClassDB::bind_method(D_METHOD("_get_vcs_name"), &EditorVCSInterface::_get_vcs_name);
+ ClassDB::bind_method(D_METHOD("_shut_down"), &EditorVCSInterface::_shut_down);
+ ClassDB::bind_method(D_METHOD("_get_project_name"), &EditorVCSInterface::_get_project_name);
+ ClassDB::bind_method(D_METHOD("_get_modified_files_data"), &EditorVCSInterface::_get_modified_files_data);
+ ClassDB::bind_method(D_METHOD("_commit", "msg"), &EditorVCSInterface::_commit);
+ ClassDB::bind_method(D_METHOD("_get_file_diff", "file_path"), &EditorVCSInterface::_get_file_diff);
+ ClassDB::bind_method(D_METHOD("_stage_file", "file_path"), &EditorVCSInterface::_stage_file);
+ ClassDB::bind_method(D_METHOD("_unstage_file", "file_path"), &EditorVCSInterface::_unstage_file);
+
+ ClassDB::bind_method(D_METHOD("is_addon_ready"), &EditorVCSInterface::is_addon_ready);
+
+ // API methods that redirect calls to the proxy end points
+ ClassDB::bind_method(D_METHOD("initialize", "project_root_path"), &EditorVCSInterface::initialize);
+ ClassDB::bind_method(D_METHOD("get_is_vcs_intialized"), &EditorVCSInterface::get_is_vcs_intialized);
+ ClassDB::bind_method(D_METHOD("get_modified_files_data"), &EditorVCSInterface::get_modified_files_data);
+ ClassDB::bind_method(D_METHOD("stage_file", "file_path"), &EditorVCSInterface::stage_file);
+ ClassDB::bind_method(D_METHOD("unstage_file", "file_path"), &EditorVCSInterface::unstage_file);
+ ClassDB::bind_method(D_METHOD("commit", "msg"), &EditorVCSInterface::commit);
+ ClassDB::bind_method(D_METHOD("get_file_diff", "file_path"), &EditorVCSInterface::get_file_diff);
+ ClassDB::bind_method(D_METHOD("shut_down"), &EditorVCSInterface::shut_down);
+ ClassDB::bind_method(D_METHOD("get_project_name"), &EditorVCSInterface::get_project_name);
+ ClassDB::bind_method(D_METHOD("get_vcs_name"), &EditorVCSInterface::get_vcs_name);
+}
+
+bool EditorVCSInterface::_initialize(String p_project_root_path) {
+
+ WARN_PRINT("Selected VCS addon does not implement an initialization function. This warning will be suppressed.")
+ return true;
+}
+
+bool EditorVCSInterface::_get_is_vcs_intialized() {
+
+ return false;
+}
+
+Dictionary EditorVCSInterface::_get_modified_files_data() {
+
+ return Dictionary();
+}
+
+void EditorVCSInterface::_stage_file(String p_file_path) {
+}
+
+void EditorVCSInterface::_unstage_file(String p_file_path) {
+}
+
+void EditorVCSInterface::_commit(String p_msg) {
+}
+
+Array EditorVCSInterface::_get_file_diff(String p_file_path) {
+
+ return Array();
+}
+
+bool EditorVCSInterface::_shut_down() {
+
+ return false;
+}
+
+String EditorVCSInterface::_get_project_name() {
+
+ return String();
+}
+
+String EditorVCSInterface::_get_vcs_name() {
+
+ return "";
+}
+
+bool EditorVCSInterface::initialize(String p_project_root_path) {
+
+ is_initialized = call("_initialize", p_project_root_path);
+ return is_initialized;
+}
+
+bool EditorVCSInterface::get_is_vcs_intialized() {
+
+ return call("_get_is_vcs_intialized");
+}
+
+Dictionary EditorVCSInterface::get_modified_files_data() {
+
+ return call("_get_modified_files_data");
+}
+
+void EditorVCSInterface::stage_file(String p_file_path) {
+
+ if (is_addon_ready()) {
+
+ call("_stage_file", p_file_path);
+ }
+}
+
+void EditorVCSInterface::unstage_file(String p_file_path) {
+
+ if (is_addon_ready()) {
+
+ call("_unstage_file", p_file_path);
+ }
+}
+
+bool EditorVCSInterface::is_addon_ready() {
+
+ return is_initialized;
+}
+
+void EditorVCSInterface::commit(String p_msg) {
+
+ if (is_addon_ready()) {
+
+ call("_commit", p_msg);
+ }
+}
+
+Array EditorVCSInterface::get_file_diff(String p_file_path) {
+
+ if (is_addon_ready()) {
+
+ return call("_get_file_diff", p_file_path);
+ }
+ return Array();
+}
+
+bool EditorVCSInterface::shut_down() {
+
+ return call("_shut_down");
+}
+
+String EditorVCSInterface::get_project_name() {
+
+ return call("_get_project_name");
+}
+
+String EditorVCSInterface::get_vcs_name() {
+
+ return call("_get_vcs_name");
+}
+
+EditorVCSInterface::EditorVCSInterface() {
+
+ is_initialized = false;
+}
+
+EditorVCSInterface::~EditorVCSInterface() {
+}
+
+EditorVCSInterface *EditorVCSInterface::get_singleton() {
+
+ return singleton;
+}
+
+void EditorVCSInterface::set_singleton(EditorVCSInterface *p_singleton) {
+
+ singleton = p_singleton;
+}
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
new file mode 100644
index 0000000000..896193ed92
--- /dev/null
+++ b/editor/editor_vcs_interface.h
@@ -0,0 +1,83 @@
+/*************************************************************************/
+/* editor_vcs_interface.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 EDITOR_VCS_INTERFACE_H
+#define EDITOR_VCS_INTERFACE_H
+
+#include "core/object.h"
+#include "core/ustring.h"
+#include "scene/gui/panel_container.h"
+
+class EditorVCSInterface : public Object {
+
+ GDCLASS(EditorVCSInterface, Object)
+
+ bool is_initialized;
+
+protected:
+ static EditorVCSInterface *singleton;
+
+ static void _bind_methods();
+
+ // Implemented by addons as end points for the proxy functions
+ bool _initialize(String p_project_root_path);
+ bool _get_is_vcs_intialized();
+ Dictionary _get_modified_files_data();
+ void _stage_file(String p_file_path);
+ void _unstage_file(String p_file_path);
+ void _commit(String p_msg);
+ Array _get_file_diff(String p_file_path);
+ bool _shut_down();
+ String _get_project_name();
+ String _get_vcs_name();
+
+public:
+ static EditorVCSInterface *get_singleton();
+ static void set_singleton(EditorVCSInterface *p_singleton);
+
+ bool is_addon_ready();
+
+ // Proxy functions to the editor for use
+ bool initialize(String p_project_root_path);
+ bool get_is_vcs_intialized();
+ Dictionary get_modified_files_data();
+ void stage_file(String p_file_path);
+ void unstage_file(String p_file_path);
+ void commit(String p_msg);
+ Array get_file_diff(String p_file_path);
+ bool shut_down();
+ String get_project_name();
+ String get_vcs_name();
+
+ EditorVCSInterface();
+ virtual ~EditorVCSInterface();
+};
+
+#endif // !EDITOR_VCS_INTERFACE_H
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index bd61e6182c..202b554be4 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -52,18 +52,16 @@ void ExportTemplateManager::_update_template_list() {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = d->change_dir(EditorSettings::get_singleton()->get_templates_dir());
- d->list_dir_begin();
Set<String> templates;
-
+ d->list_dir_begin();
if (err == OK) {
- bool isdir;
- String c = d->get_next(&isdir);
+ String c = d->get_next();
while (c != String()) {
- if (isdir && !c.begins_with(".")) {
+ if (d->current_is_dir() && !c.begins_with(".")) {
templates.insert(c);
}
- c = d->get_next(&isdir);
+ c = d->get_next();
}
}
d->list_dir_end();
@@ -71,6 +69,9 @@ void ExportTemplateManager::_update_template_list() {
memdelete(d);
String current_version = VERSION_FULL_CONFIG;
+ // Downloadable export templates are only available for stable, alpha, beta and RC versions.
+ // Therefore, don't display download-related features when using a development version
+ const bool downloads_available = String(VERSION_STATUS) != String("dev");
Label *current = memnew(Label);
current->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -78,10 +79,14 @@ void ExportTemplateManager::_update_template_list() {
if (templates.has(current_version)) {
current->add_color_override("font_color", get_color("success_color", "Editor"));
- Button *redownload = memnew(Button);
- redownload->set_text(TTR("Re-Download"));
- current_hb->add_child(redownload);
- redownload->connect("pressed", this, "_download_template", varray(current_version));
+
+ // Only display a redownload button if it can be downloaded in the first place
+ if (downloads_available) {
+ Button *redownload = memnew(Button);
+ redownload->set_text(TTR("Redownload"));
+ current_hb->add_child(redownload);
+ redownload->connect("pressed", this, "_download_template", varray(current_version));
+ }
Button *uninstall = memnew(Button);
uninstall->set_text(TTR("Uninstall"));
@@ -93,6 +98,12 @@ void ExportTemplateManager::_update_template_list() {
current->add_color_override("font_color", get_color("error_color", "Editor"));
Button *redownload = memnew(Button);
redownload->set_text(TTR("Download"));
+
+ if (!downloads_available) {
+ redownload->set_disabled(true);
+ redownload->set_tooltip(TTR("Official export templates aren't available for development builds."));
+ }
+
redownload->connect("pressed", this, "_download_template", varray(current_version));
current_hb->add_child(redownload);
current->set_text(current_version + " " + TTR("(Missing)"));
@@ -154,18 +165,14 @@ void ExportTemplateManager::_uninstall_template_confirm() {
ERR_FAIL_COND(err != OK);
Vector<String> files;
-
d->list_dir_begin();
-
- bool isdir;
- String c = d->get_next(&isdir);
+ String c = d->get_next();
while (c != String()) {
- if (!isdir) {
+ if (!d->current_is_dir()) {
files.push_back(c);
}
- c = d->get_next(&isdir);
+ c = d->get_next();
}
-
d->list_dir_end();
for (int i = 0; i < files.size(); i++) {
@@ -314,8 +321,7 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
if (!f) {
ret = unzGoToNextFile(pkg);
fc++;
- ERR_EXPLAIN("Can't open file from path: " + String(to_write));
- ERR_CONTINUE(true);
+ ERR_CONTINUE_MSG(true, "Can't open file from path: " + String(to_write) + ".");
}
f->store_buffer(data.ptr(), data.size());
@@ -428,14 +434,16 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int
String path = download_templates->get_download_file();
template_list_state->set_text(TTR("Download Complete."));
template_downloader->hide();
- int ret = _install_from_file(path, false);
+ bool ret = _install_from_file(path, false);
if (ret) {
- Error err = OS::get_singleton()->move_to_trash(path);
+ // Clean up downloaded file.
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error err = da->remove(path);
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + path + "\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove temporary file:") + "\n" + path + "\n");
}
} else {
- WARN_PRINTS(vformat(TTR("Templates installation failed. The problematic templates archives can be found at '%s'."), path));
+ EditorNode::get_singleton()->add_io_error(vformat(TTR("Templates installation failed.\nThe problematic templates archives can be found at '%s'."), path));
}
}
} break;
@@ -464,7 +472,7 @@ void ExportTemplateManager::_begin_template_download(const String &p_url) {
Error err = download_templates->request(p_url);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Error requesting url: ") + p_url);
+ EditorNode::get_singleton()->show_warning(TTR("Error requesting URL:") + " " + p_url);
return;
}
@@ -534,7 +542,6 @@ void ExportTemplateManager::_notification(int p_what) {
template_list_state->set_text(status);
if (errored) {
set_process(false);
- ;
}
}
@@ -547,25 +554,31 @@ void ExportTemplateManager::_notification(int p_what) {
bool ExportTemplateManager::can_install_android_template() {
- return FileAccess::exists(EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip"));
+ const String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ return FileAccess::exists(templates_dir.plus_file("android_source.zip")) &&
+ FileAccess::exists(templates_dir.plus_file("android_release.apk")) &&
+ FileAccess::exists(templates_dir.plus_file("android_debug.apk"));
}
Error ExportTemplateManager::install_android_template() {
+ // To support custom Android builds, we install the Java source code and buildsystem
+ // from android_source.zip to the project's res://android folder.
+
DirAccessRef da = DirAccess::open("res://");
ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
- //make android dir (if it does not exist)
+ // Make res://android dir (if it does not exist).
da->make_dir("android");
{
- //add an empty .gdignore file to avoid scan
+ // Add an empty .gdignore file to avoid scan.
FileAccessRef f = FileAccess::open("res://android/.gdignore", FileAccess::WRITE);
ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
f->store_line("");
f->close();
}
{
- //add version, to ensure building won't work if template and Godot version don't match
+ // Add version, to ensure building won't work if template and Godot version don't match.
FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::WRITE);
ERR_FAIL_COND_V(!f, ERR_CANT_CREATE);
f->store_line(VERSION_FULL_CONFIG);
@@ -575,48 +588,46 @@ Error ExportTemplateManager::install_android_template() {
Error err = da->make_dir_recursive("android/build");
ERR_FAIL_COND_V(err != OK, err);
- String source_zip = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip");
+ // Uncompress source template.
+
+ const String &templates_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ const String &source_zip = templates_path.plus_file("android_source.zip");
ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN);
FileAccess *src_f = NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
unzFile pkg = unzOpen2(source_zip.utf8().get_data(), &io);
- ERR_EXPLAIN("Android sources not in zip format");
- ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(!pkg, ERR_CANT_OPEN, "Android sources not in ZIP format.");
int ret = unzGoToFirstFile(pkg);
-
int total_files = 0;
- //count files
+ // Count files to unzip.
while (ret == UNZ_OK) {
total_files++;
ret = unzGoToNextFile(pkg);
}
-
ret = unzGoToFirstFile(pkg);
- //decompress files
- ProgressDialog::get_singleton()->add_task("uncompress", TTR("Uncompressing Android Build Sources"), total_files);
- Set<String> dirs_tested;
+ ProgressDialog::get_singleton()->add_task("uncompress_src", TTR("Uncompressing Android Build Sources"), total_files);
+ Set<String> dirs_tested;
int idx = 0;
while (ret == UNZ_OK) {
- //get filename
+ // Get file path.
unz_file_info info;
- char fname[16384];
- ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
-
- String name = fname;
+ char fpath[16384];
+ ret = unzGetCurrentFileInfo(pkg, &info, fpath, 16384, NULL, 0, NULL, 0);
- String base_dir = name.get_base_dir();
+ String path = fpath;
+ String base_dir = path.get_base_dir();
- if (!name.ends_with("/")) {
+ if (!path.ends_with("/")) {
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
- //read
+ // Read.
unzOpenCurrentFile(pkg);
unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
@@ -626,7 +637,7 @@ Error ExportTemplateManager::install_android_template() {
dirs_tested.insert(base_dir);
}
- String to_write = String("res://android/build").plus_file(name);
+ String to_write = String("res://android/build").plus_file(path);
FileAccess *f = FileAccess::open(to_write, FileAccess::WRITE);
if (f) {
f->store_buffer(data.ptr(), data.size());
@@ -639,13 +650,13 @@ Error ExportTemplateManager::install_android_template() {
}
}
- ProgressDialog::get_singleton()->task_step("uncompress", name, idx);
+ ProgressDialog::get_singleton()->task_step("uncompress_src", path, idx);
idx++;
ret = unzGoToNextFile(pkg);
}
- ProgressDialog::get_singleton()->end_task("uncompress");
+ ProgressDialog::get_singleton()->end_task("uncompress_src");
unzClose(pkg);
return OK;
diff --git a/editor/file_type_cache.cpp b/editor/file_type_cache.cpp
index 1bcbc45d3b..746d38f2b5 100644
--- a/editor/file_type_cache.cpp
+++ b/editor/file_type_cache.cpp
@@ -83,11 +83,8 @@ void FileTypeCache::save() {
GLOBAL_LOCK_FUNCTION
String project = ProjectSettings::get_singleton()->get_resource_path();
FileAccess *f = FileAccess::open(project + "/file_type_cache.cch", FileAccess::WRITE);
- if (!f) {
- ERR_EXPLAIN(TTR("Can't open file_type_cache.cch for writing, not saving file type cache!"));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!f, "Can't open file_type_cache.cch for writing, not saving file type cache!");
const String *K = NULL;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 947d96f897..a729befe8e 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -39,6 +39,7 @@
#include "editor_node.h"
#include "editor_settings.h"
#include "scene/main/viewport.h"
+#include "scene/resources/packed_scene.h"
Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx) {
Ref<Texture> file_icon;
@@ -52,10 +53,9 @@ Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_di
}
bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites) {
-
bool parent_should_expand = false;
- // Create a tree item for the subdirectory
+ // Create a tree item for the subdirectory.
TreeItem *subdirectory_item = tree->create_item(p_parent);
String dname = p_dir->get_name();
if (dname == "")
@@ -63,6 +63,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
subdirectory_item->set_text(0, dname);
subdirectory_item->set_icon(0, get_icon("Folder", "EditorIcons"));
+ subdirectory_item->set_icon_modulate(0, get_color("folder_icon_modulate", "FileDialog"));
subdirectory_item->set_selectable(0, true);
String lpath = p_dir->get_path();
subdirectory_item->set_metadata(0, lpath);
@@ -79,28 +80,28 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
parent_should_expand = true;
}
- // Create items for all subdirectories
+ // Create items for all subdirectories.
for (int i = 0; i < p_dir->get_subdir_count(); i++)
parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites) || parent_should_expand);
- // Create all items for the files in the subdirectory
+ // Create all items for the files in the subdirectory.
if (display_mode == DISPLAY_MODE_TREE_ONLY) {
for (int i = 0; i < p_dir->get_file_count(); i++) {
String file_type = p_dir->get_file_type(i);
if (_is_file_type_disabled_by_feature_profile(file_type)) {
- //if type is disabled, file won't be displayed.
+ // If type is disabled, file won't be displayed.
continue;
}
String file_name = p_dir->get_file(i);
if (searched_string.length() > 0) {
if (file_name.to_lower().find(searched_string) < 0) {
- // The searched string is not in the file name, we skip it
+ // The searched string is not in the file name, we skip it.
continue;
} else {
- // We expand all parents
+ // We expand all parents.
parent_should_expand = true;
}
}
@@ -133,7 +134,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
}
Vector<String> FileSystemDock::_compute_uncollapsed_paths() {
- // Register currently collapsed paths
+ // Register currently collapsed paths.
Vector<String> uncollapsed_paths;
TreeItem *root = tree->get_root();
if (root) {
@@ -164,14 +165,13 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() {
}
void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) {
-
- // Recreate the tree
+ // Recreate the tree.
tree->clear();
tree_update_id++;
updating_tree = true;
TreeItem *root = tree->create_item();
- // Handles the favorites
+ // Handles the favorites.
TreeItem *favorites = tree->create_item(root);
favorites->set_icon(0, get_icon("Favorites", "EditorIcons"));
favorites->set_text(0, TTR("Favorites:"));
@@ -185,15 +185,19 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
continue;
Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons");
+ const Color folder_color = get_color("folder_icon_modulate", "FileDialog");
String text;
Ref<Texture> icon;
+ Color color;
if (fave == "res://") {
text = "/";
icon = folder_icon;
+ color = folder_color;
} else if (fave.ends_with("/")) {
text = fave.substr(0, fave.length() - 1).get_file();
icon = folder_icon;
+ color = folder_color;
} else {
text = fave.get_file();
int index;
@@ -203,12 +207,14 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
} else {
icon = get_icon("File", "EditorIcons");
}
+ color = Color(1, 1, 1);
}
if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) {
TreeItem *ti = tree->create_item(favorites);
ti->set_text(0, text);
ti->set_icon(0, icon);
+ ti->set_icon_modulate(0, color);
ti->set_tooltip(0, fave);
ti->set_selectable(0, true);
ti->set_metadata(0, fave);
@@ -230,7 +236,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
uncollapsed_paths.push_back("res://");
}
- // Create the remaining of the tree
+ // Create the remaining of the tree.
_create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites);
tree->ensure_cursor_is_visible();
updating_tree = false;
@@ -242,7 +248,7 @@ void FileSystemDock::set_display_mode(DisplayMode p_display_mode) {
}
void FileSystemDock::_update_display_mode(bool p_force) {
- // Compute the new display mode
+ // Compute the new display mode.
if (p_force || old_display_mode != display_mode) {
button_toggle_display_mode->set_pressed(display_mode == DISPLAY_MODE_SPLIT);
switch (display_mode) {
@@ -275,11 +281,8 @@ void FileSystemDock::_update_display_mode(bool p_force) {
}
void FileSystemDock::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
if (initialized)
return;
initialized = true;
@@ -319,18 +322,15 @@ void FileSystemDock::_notification(int p_what) {
} else {
_update_tree(Vector<String>(), true);
}
-
} break;
+
case NOTIFICATION_PROCESS: {
if (EditorFileSystem::get_singleton()->is_scanning()) {
scanning_progress->set_value(EditorFileSystem::get_singleton()->get_scanning_progress() * 100);
}
} break;
- case NOTIFICATION_EXIT_TREE: {
- } break;
case NOTIFICATION_DRAG_BEGIN: {
-
Dictionary dd = get_viewport()->gui_get_drag_data();
if (tree->is_visible_in_tree() && dd.has("type")) {
if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) {
@@ -339,20 +339,20 @@ void FileSystemDock::_notification(int p_what) {
tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
}
}
-
} break;
- case NOTIFICATION_DRAG_END: {
+ case NOTIFICATION_DRAG_END: {
tree->set_drop_mode_flags(0);
-
} break;
+
case NOTIFICATION_THEME_CHANGED: {
if (is_visible_in_tree()) {
_update_display_mode(true);
}
} break;
+
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- // Update icons
+ // Update icons.
String ei = "EditorIcons";
button_reload->set_icon(get_icon("Reload", ei));
button_toggle_display_mode->set_icon(get_icon("Panels2", ei));
@@ -369,48 +369,47 @@ void FileSystemDock::_notification(int p_what) {
file_list_search_box->set_right_icon(get_icon("Search", ei));
file_list_search_box->set_clear_button_enabled(true);
- // Update always showfolders
+ // Update always show folders.
bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders"));
if (new_always_show_folders != always_show_folders) {
always_show_folders = new_always_show_folders;
_update_file_list(true);
}
- // Change full tree mode
+ // Change full tree mode.
_update_display_mode();
-
} break;
}
}
void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_selected) {
- // Update the import dock
+ // Update the import dock.
import_dock_needs_update = true;
call_deferred("_update_import_dock");
- // Return if we don't select something new
+ // Return if we don't select something new.
if (!p_selected)
return;
- // Tree item selected
+ // Tree item selected.
TreeItem *selected = tree->get_selected();
if (!selected)
return;
TreeItem *favorites_item = tree->get_root()->get_children();
if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) {
- // Go to the favorites if we click in the favorites and the path has changed
+ // Go to the favorites if we click in the favorites and the path has changed.
path = "Favorites";
} else {
path = selected->get_metadata(0);
- // Note: the "Favorites" item also leads to this path
+ // Note: the "Favorites" item also leads to this path.
}
- // Set the current path
+ // Set the current path.
_set_current_path_text(path);
_push_to_history();
- // Update the file list
+ // Update the file list.
if (!updating_tree && display_mode == DISPLAY_MODE_SPLIT) {
_update_file_list(false);
}
@@ -424,7 +423,6 @@ String FileSystemDock::get_selected_path() const {
}
String FileSystemDock::get_current_path() const {
-
return path;
}
@@ -452,8 +450,7 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa
path = target_path + "/";
} else {
memdelete(dirAccess);
- ERR_EXPLAIN(vformat(TTR("Cannot navigate to '%s' as it has not been found in the file system!"), p_path));
- ERR_FAIL();
+ ERR_FAIL_MSG(vformat("Cannot navigate to '%s' as it has not been found in the file system!", p_path));
}
memdelete(dirAccess);
}
@@ -484,7 +481,6 @@ void FileSystemDock::navigate_to_path(const String &p_path) {
}
void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) {
-
if ((file_list_vb->is_visible_in_tree() || path == p_path.get_base_dir()) && p_preview.is_valid()) {
Array uarr = p_udata;
int idx = uarr[0];
@@ -532,7 +528,6 @@ void FileSystemDock::_set_file_display(bool p_active) {
}
bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName &p_class) {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_null()) {
return false;
@@ -552,7 +547,6 @@ bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName
}
void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items) {
-
if (matches->size() > p_max_items)
return;
@@ -570,10 +564,9 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *
fi.type = p_path->get_file_type(i);
fi.path = p_path->get_file_path(i);
fi.import_broken = !p_path->get_file_import_is_valid(i);
- fi.import_status = 0;
if (_is_file_type_disabled_by_feature_profile(fi.type)) {
- //this type is disabled, will not appear here
+ // This type is disabled, will not appear here.
continue;
}
@@ -585,8 +578,7 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *
}
void FileSystemDock::_update_file_list(bool p_keep_selection) {
-
- // Register the previously selected items
+ // Register the previously selected items.
Set<String> cselection;
if (p_keep_selection) {
for (int i = 0; i < files->get_item_count(); i++) {
@@ -612,7 +604,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
bool use_thumbnails = (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS);
if (use_thumbnails) {
- // Thumbnails mode
+ // Thumbnails mode.
files->set_max_columns(0);
files->set_icon_mode(ItemList::ICON_MODE_TOP);
files->set_fixed_column_width(thumbnail_size * 3 / 2);
@@ -629,8 +621,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
file_thumbnail_broken = get_icon("FileDeadBigThumb", ei);
}
} else {
-
- // No thumbnails
+ // No thumbnails.
files->set_icon_mode(ItemList::ICON_MODE_LEFT);
files->set_max_columns(1);
files->set_max_text_lines(1);
@@ -639,11 +630,12 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog");
+ const Color folder_color = get_color("folder_icon_modulate", "FileDialog");
- // Build the FileInfo list
+ // Build the FileInfo list.
List<FileInfo> filelist;
if (path == "Favorites") {
- // Display the favorites
+ // Display the favorites.
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < favorites.size(); i++) {
String favorite = favorites[i];
@@ -677,7 +669,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
fi.type = "";
fi.import_broken = true;
}
- fi.import_status = 0;
if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) {
filelist.push_back(fi);
@@ -685,8 +676,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
}
} else {
-
- // Get infos on the directory + file
+ // Get infos on the directory + file.
if (directory.ends_with("/") && directory != "res://") {
directory = directory.substr(0, directory.length() - 1);
}
@@ -700,13 +690,11 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
return;
if (searched_string.length() > 0) {
- // Display the search results
+ // Display the search results.
_search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128);
} else {
-
if (display_mode == DISPLAY_MODE_TREE_ONLY || always_show_folders) {
- // Display folders in the list
-
+ // Display folders in the list.
if (directory != "res://") {
files->add_item("..", folder_icon, true);
@@ -716,14 +704,15 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_item_metadata(files->get_item_count() - 1, bd);
files->set_item_selectable(files->get_item_count() - 1, false);
+ files->set_item_icon_modulate(files->get_item_count() - 1, folder_color);
}
for (int i = 0; i < efd->get_subdir_count(); i++) {
-
String dname = efd->get_subdir(i)->get_name();
files->add_item(dname, folder_icon, true);
files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/");
+ files->set_item_icon_modulate(files->get_item_count() - 1, folder_color);
if (cselection.has(dname)) {
files->select(files->get_item_count() - 1, false);
@@ -731,15 +720,13 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
}
- // Display the folder content
+ // Display the folder content.
for (int i = 0; i < efd->get_file_count(); i++) {
-
FileInfo fi;
fi.name = efd->get_file(i);
fi.path = directory.plus_file(fi.name);
fi.type = efd->get_file_type(i);
fi.import_broken = !efd->get_file_import_is_valid(i);
- fi.import_status = 0;
filelist.push_back(fi);
}
@@ -747,7 +734,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
filelist.sort();
}
- // Fills the ItemList control node from the FileInfos
+ // Fills the ItemList control node from the FileInfos.
String oi = "Object";
for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) {
FileInfo *finfo = &(E->get());
@@ -760,7 +747,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
String tooltip = fpath;
- // Select the icons
+ // Select the icons.
if (!finfo->import_broken) {
type_icon = (has_icon(ftype, ei)) ? get_icon(ftype, ei) : get_icon(oi, ei);
big_icon = file_thumbnail;
@@ -770,7 +757,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually.");
}
- // Add the item to the ItemList
+ // Add the item to the ItemList.
int item_index;
if (use_thumbnails) {
files->add_item(fname, big_icon, true);
@@ -784,7 +771,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_item_metadata(item_index, fpath);
}
- // Generate the preview
+ // Generate the preview.
if (!finfo->import_broken) {
Array udata;
udata.resize(2);
@@ -793,7 +780,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
EditorResourcePreview::get_singleton()->queue_resource_preview(fpath, this, "_file_list_thumbnail_done", udata);
}
- // Select the items
+ // Select the items.
if (cselection.has(fname))
files->select(item_index, false);
@@ -802,7 +789,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->ensure_current_is_visible();
}
- // Tooltip
+ // Tooltip.
if (finfo->sources.size()) {
for (int j = 0; j < finfo->sources.size(); j++) {
tooltip += "\nSource: " + finfo->sources[j];
@@ -849,13 +836,12 @@ void FileSystemDock::_file_list_activate_file(int p_idx) {
}
void FileSystemDock::_preview_invalidated(const String &p_path) {
-
if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && searched_string.length() == 0 && file_list_vb->is_visible_in_tree()) {
for (int i = 0; i < files->get_item_count(); i++) {
if (files->get_item_metadata(i) == p_path) {
- //re-request preview
+ // Re-request preview.
Array udata;
udata.resize(2);
udata[0] = i;
@@ -868,7 +854,6 @@ void FileSystemDock::_preview_invalidated(const String &p_path) {
}
void FileSystemDock::_fs_changed() {
-
button_hist_prev->set_disabled(history_pos == 0);
button_hist_next->set_disabled(history_pos == history.size() - 1);
scanning_vb->hide();
@@ -886,7 +871,6 @@ void FileSystemDock::_fs_changed() {
}
void FileSystemDock::_set_scanning_mode() {
-
button_hist_prev->set_disabled(true);
button_hist_next->set_disabled(true);
split_box->hide();
@@ -900,7 +884,6 @@ void FileSystemDock::_set_scanning_mode() {
}
void FileSystemDock::_fw_history() {
-
if (history_pos < history.size() - 1)
history_pos++;
@@ -978,7 +961,7 @@ void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const Map<Str
void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_new_path,
Map<String, String> &p_file_renames, Map<String, String> &p_folder_renames) {
- //Ensure folder paths end with "/"
+ // Ensure folder paths end with "/".
String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/");
String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/");
@@ -988,12 +971,12 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root."));
return;
} else if (!p_item.is_file && new_path.begins_with(old_path)) {
- //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/"
+ // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/".
EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n");
return;
}
- //Build a list of files which will have new paths as a result of this operation
+ // Build a list of files which will have new paths as a result of this operation.
Vector<String> file_changed_paths;
Vector<String> folder_changed_paths;
if (p_item.is_file) {
@@ -1007,8 +990,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
print_verbose("Moving " + old_path + " -> " + new_path);
Error err = da->rename(old_path, new_path);
if (err == OK) {
-
- //Move/Rename any corresponding import settings too
+ // Move/Rename any corresponding import settings too.
if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
err = da->rename(old_path + ".import", new_path + ".import");
if (err != OK) {
@@ -1016,7 +998,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
}
}
- // update scene if it is open
+ // Update scene if it is open.
for (int i = 0; i < file_changed_paths.size(); ++i) {
String new_item_path = p_item.is_file ? new_path : file_changed_paths[i].replace_first(old_path, new_path);
if (ResourceLoader::get_resource_type(new_item_path) == "PackedScene" && editor->is_scene_open(file_changed_paths[i])) {
@@ -1031,7 +1013,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
}
}
- //Only treat as a changed dependency if it was successfully moved
+ // Only treat as a changed dependency if it was successfully moved.
for (int i = 0; i < file_changed_paths.size(); ++i) {
p_file_renames[file_changed_paths[i]] = file_changed_paths[i].replace_first(old_path, new_path);
print_verbose(" Remap: " + file_changed_paths[i] + " -> " + p_file_renames[file_changed_paths[i]]);
@@ -1048,7 +1030,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_
}
void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const {
- //Ensure folder paths end with "/"
+ // Ensure folder paths end with "/".
String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/");
String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/");
@@ -1058,7 +1040,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root."));
return;
} else if (!p_item.is_file && new_path.begins_with(old_path)) {
- //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/"
+ // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/".
EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n");
return;
}
@@ -1067,7 +1049,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
print_verbose("Duplicating " + old_path + " -> " + new_path);
Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path);
if (err == OK) {
- //Move/Rename any corresponding import settings too
+ // Move/Rename any corresponding import settings too.
if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
err = da->copy(old_path + ".import", new_path + ".import");
if (err != OK) {
@@ -1081,13 +1063,11 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
}
void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const {
-
- //Rename all resources loaded, be it subresources or actual resources
+ // Rename all resources loaded, be it subresources or actual resources.
List<Ref<Resource> > cached;
ResourceCache::get_cached_resources(&cached);
for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) {
-
Ref<Resource> r = E->get();
String base_path = r->get_path();
@@ -1106,7 +1086,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String>
}
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
-
String path;
if (i == EditorNode::get_editor_data().get_edited_scene()) {
if (!get_tree()->get_edited_scene_root())
@@ -1114,7 +1093,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String>
path = get_tree()->get_edited_scene_root()->get_filename();
} else {
-
path = EditorNode::get_editor_data().get_scene_path(i);
}
@@ -1123,23 +1101,21 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String>
}
if (i == EditorNode::get_editor_data().get_edited_scene()) {
-
get_tree()->get_edited_scene_root()->set_filename(path);
} else {
-
EditorNode::get_editor_data().set_scene_path(i, path);
}
}
}
void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const {
- //The following code assumes that the following holds:
+ // The following code assumes that the following holds:
// 1) EditorFileSystem contains the old paths/folder structure from before the rename/move.
// 2) ResourceLoader can use the new paths without needing to call rescan.
Vector<String> remaps;
_find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps);
for (int i = 0; i < remaps.size(); ++i) {
- //Because we haven't called a rescan yet the found remap might still be an old path itself.
+ // Because we haven't called a rescan yet the found remap might still be an old path itself.
String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i];
print_verbose("Remapping dependencies for: " + file);
Error err = ResourceLoader::rename_dependencies(file, p_renames);
@@ -1153,8 +1129,7 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &
}
void FileSystemDock::_update_project_settings_after_move(const Map<String, String> &p_renames) const {
-
- // Find all project settings of type FILE and replace them if needed
+ // Find all project settings of type FILE and replace them if needed.
const Map<StringName, PropertyInfo> prop_info = ProjectSettings::get_singleton()->get_custom_property_info();
for (const Map<StringName, PropertyInfo>::Element *E = prop_info.front(); E; E = E->next()) {
if (E->get().hint == PROPERTY_HINT_FILE) {
@@ -1185,7 +1160,6 @@ void FileSystemDock::_update_project_settings_after_move(const Map<String, Strin
}
void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const {
-
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
Vector<String> new_favorites;
@@ -1250,6 +1224,48 @@ void FileSystemDock::_make_dir_confirm() {
}
}
+void FileSystemDock::_make_scene_confirm() {
+ String scene_name = make_scene_dialog_text->get_text().strip_edges();
+
+ if (scene_name.length() == 0) {
+ EditorNode::get_singleton()->show_warning(TTR("No name provided."));
+ return;
+ }
+
+ String directory = path;
+ if (!directory.ends_with("/")) {
+ directory = directory.get_base_dir();
+ }
+
+ String extension = scene_name.get_extension();
+ List<String> extensions;
+ Ref<PackedScene> sd = memnew(PackedScene);
+ ResourceSaver::get_recognized_extensions(sd, &extensions);
+
+ bool extension_correct = false;
+ for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
+ if (E->get() == extension) {
+ extension_correct = true;
+ break;
+ }
+ }
+ if (!extension_correct)
+ scene_name = scene_name.get_basename() + ".tscn";
+
+ scene_name = directory.plus_file(scene_name);
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (da->file_exists(scene_name)) {
+ EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists."));
+ memdelete(da);
+ return;
+ }
+ memdelete(da);
+
+ int idx = editor->new_scene();
+ editor->get_editor_data().set_scene_path(idx, scene_name);
+}
+
void FileSystemDock::_file_deleted(String p_file) {
emit_signal("file_deleted", p_file);
}
@@ -1259,7 +1275,6 @@ void FileSystemDock::_folder_deleted(String p_folder) {
}
void FileSystemDock::_rename_operation_confirm() {
-
String new_name = rename_dialog_text->get_text().strip_edges();
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
@@ -1279,10 +1294,10 @@ void FileSystemDock::_rename_operation_confirm() {
EditorFileSystem::get_singleton()->move_group_file(old_path, new_path);
}
- //Present a more user friendly warning for name conflict
+ // Present a more user friendly warning for name conflict.
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
- // Workaround case insensitivity on Windows
+ // Workaround case insensitivity on Windows.
if ((da->file_exists(new_path) || da->dir_exists(new_path)) && new_path.to_lower() != old_path.to_lower()) {
#else
if (da->file_exists(new_path) || da->dir_exists(new_path)) {
@@ -1298,7 +1313,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);
@@ -1314,7 +1329,6 @@ void FileSystemDock::_rename_operation_confirm() {
}
void FileSystemDock::_duplicate_operation_confirm() {
-
String new_name = duplicate_dialog_text->get_text().strip_edges();
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
@@ -1332,7 +1346,7 @@ void FileSystemDock::_duplicate_operation_confirm() {
String new_path = base_dir.plus_file(new_name);
- //Present a more user friendly warning for name conflict
+ // 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)) {
EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists."));
@@ -1343,7 +1357,7 @@ void FileSystemDock::_duplicate_operation_confirm() {
_try_duplicate_item(to_duplicate, new_path);
- //Rescan everything
+ // Rescan everything.
print_verbose("FileSystem: calling rescan.");
_rescan();
}
@@ -1376,14 +1390,14 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw
to_move_path = p_to_path;
bool can_move = _check_existing();
if (!can_move) {
- //ask to do something
+ // Ask to do something.
overwrite_dialog->popup_centered_minsize();
overwrite_dialog->grab_focus();
return;
}
}
- //check groups
+ // Check groups.
for (int i = 0; i < to_move.size(); i++) {
print_line("is group: " + to_move[i].path + ": " + itos(EditorFileSystem::get_singleton()->is_group_file(to_move[i].path)));
@@ -1407,7 +1421,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);
@@ -1424,7 +1438,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw
}
Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) {
- // Build a list of selected items with the active one at the first position
+ // Build a list of selected items with the active one at the first position.
Vector<String> selected_strings;
TreeItem *favorites_item = tree->get_root()->get_children();
@@ -1442,8 +1456,15 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) {
selected = tree->get_next_selected(selected);
}
- // Remove paths or files that are included into another
- if (remove_self_inclusion && selected_strings.size() > 1) {
+ if (remove_self_inclusion) {
+ selected_strings = _remove_self_included_paths(selected_strings);
+ }
+ return selected_strings;
+}
+
+Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> selected_strings) {
+ // Remove paths or files that are included into another.
+ if (selected_strings.size() > 1) {
selected_strings.sort_custom<NaturalNoCaseComparator>();
String last_path = "";
for (int i = 0; i < selected_strings.size(); i++) {
@@ -1460,10 +1481,9 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) {
}
void FileSystemDock::_tree_rmb_option(int p_option) {
+ Vector<String> selected_strings = _tree_get_selected(false);
- Vector<String> selected_strings = _tree_get_selected();
-
- // Execute the current option
+ // Execute the current option.
switch (p_option) {
case FOLDER_EXPAND_ALL:
case FOLDER_COLLAPSE_ALL: {
@@ -1503,11 +1523,11 @@ void FileSystemDock::_file_list_rmb_option(int p_option) {
}
void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected) {
- // The first one should be the active item
+ // The first one should be the active item.
switch (p_option) {
case FILE_SHOW_IN_EXPLORER: {
- // Show the file / folder in the OS explorer
+ // Show the file/folder in the OS explorer.
String fpath = path;
if (path == "Favorites") {
fpath = p_selected[0];
@@ -1521,7 +1541,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_OPEN: {
- // Open folders
+ // Open folders.
TreeItem *selected = tree->get_root();
selected = tree->get_next_selected(selected);
while (selected) {
@@ -1530,21 +1550,21 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
}
selected = tree->get_next_selected(selected);
}
- // Open the file
+ // Open the file.
for (int i = 0; i < p_selected.size(); i++) {
_select_file(p_selected[i]);
}
} break;
case FILE_INHERIT: {
- // Create a new scene inherited from the selected one
+ // Create a new scene inherited from the selected one.
if (p_selected.size() == 1) {
emit_signal("inherit", p_selected[0]);
}
} break;
case FILE_INSTANCE: {
- // Instance all selected scenes
+ // Instance all selected scenes.
Vector<String> paths;
for (int i = 0; i < p_selected.size(); i++) {
String fpath = p_selected[i];
@@ -1558,7 +1578,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_ADD_FAVORITE: {
- // Add the files from favorites
+ // Add the files from favorites.
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < p_selected.size(); i++) {
if (favorites.find(p_selected[i]) == -1) {
@@ -1570,7 +1590,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_REMOVE_FAVORITE: {
- // Remove the files from favorites
+ // Remove the files from favorites.
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < p_selected.size(); i++) {
favorites.erase(p_selected[i]);
@@ -1582,7 +1602,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_DEPENDENCIES: {
- // Checkout the file dependencies
+ // Checkout the file dependencies.
if (!p_selected.empty()) {
String fpath = p_selected[0];
deps_editor->edit(fpath);
@@ -1590,7 +1610,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_OWNERS: {
- // Checkout the file owners
+ // Checkout the file owners.
if (!p_selected.empty()) {
String fpath = p_selected[0];
owners_editor->show(fpath);
@@ -1598,10 +1618,11 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_MOVE: {
- // Move the files to a given location
+ // Move the files to a given location.
to_move.clear();
- for (int i = 0; i < p_selected.size(); i++) {
- String fpath = p_selected[i];
+ Vector<String> collapsed_paths = _remove_self_included_paths(p_selected);
+ for (int i = collapsed_paths.size() - 1; i >= 0; i--) {
+ String fpath = collapsed_paths[i];
if (fpath != "res://") {
to_move.push_back(FileOrFolder(fpath, !fpath.ends_with("/")));
}
@@ -1612,7 +1633,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_RENAME: {
- // Rename the active file
+ // Rename the active file.
if (!p_selected.empty()) {
to_rename.path = p_selected[0];
if (to_rename.path != "res://") {
@@ -1635,12 +1656,13 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_REMOVE: {
- // Remove the selected files
+ // Remove the selected files.
Vector<String> remove_files;
Vector<String> remove_folders;
+ Vector<String> collapsed_paths = _remove_self_included_paths(p_selected);
- for (int i = 0; i < p_selected.size(); i++) {
- String fpath = p_selected[i];
+ for (int i = 0; i < collapsed_paths.size(); i++) {
+ String fpath = collapsed_paths[i];
if (fpath != "res://") {
if (fpath.ends_with("/")) {
remove_folders.push_back(fpath);
@@ -1656,7 +1678,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_DUPLICATE: {
- // Duplicate the selected files
+ // Duplicate the selected files.
for (int i = 0; i < p_selected.size(); i++) {
to_duplicate.path = p_selected[i];
to_duplicate.is_file = !to_duplicate.path.ends_with("/");
@@ -1681,7 +1703,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_REIMPORT: {
- // Reimport all selected files
+ // Reimport all selected files.
Vector<String> reimport;
for (int i = 0; i < p_selected.size(); i++) {
reimport.push_back(p_selected[i]);
@@ -1691,15 +1713,20 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_NEW_FOLDER: {
- // Create a new folder
make_dir_dialog_text->set_text("new folder");
make_dir_dialog_text->select_all();
make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
make_dir_dialog_text->grab_focus();
} break;
+ case FILE_NEW_SCENE: {
+ make_scene_dialog_text->set_text("new scene");
+ make_scene_dialog_text->select_all();
+ make_scene_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
+ make_scene_dialog_text->grab_focus();
+ } break;
+
case FILE_NEW_SCRIPT: {
- // Create a new script
String fpath = path;
if (!fpath.ends_with("/")) {
fpath = fpath.get_base_dir();
@@ -1709,7 +1736,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_COPY_PATH: {
- // Copy the file path
if (!p_selected.empty()) {
String fpath = p_selected[0];
OS::get_singleton()->set_clipboard(fpath);
@@ -1717,7 +1743,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_NEW_RESOURCE: {
- // Create a new resource
new_resource_dialog->popup_create(true);
} break;
}
@@ -1745,7 +1770,7 @@ void FileSystemDock::_resource_created() const {
void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) {
if (searched_string.length() == 0 && p_text.length() > 0) {
- // Register the uncollapsed paths before they change
+ // Register the uncollapsed paths before they change.
uncollapsed_paths_before_search = _compute_uncollapsed_paths();
}
@@ -1753,7 +1778,7 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from
if (p_from == tree_search_box)
file_list_search_box->set_text(searched_string);
- else // file_list_search_box
+ else // File_list_search_box.
tree_search_box->set_text(searched_string);
switch (display_mode) {
@@ -1768,7 +1793,6 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from
}
void FileSystemDock::_rescan() {
-
_set_scanning_mode();
EditorFileSystem::get_singleton()->scan();
}
@@ -1783,12 +1807,10 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) {
}
void FileSystemDock::focus_on_filter() {
-
file_list_search_box->grab_focus();
}
void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) {
-
if (p_mode == file_list_display_mode)
return;
@@ -1802,12 +1824,12 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from)
Vector<String> paths;
if (p_from == tree) {
- // Check if the first selected is in favorite
+ // Check if the first selected is in favorite.
TreeItem *selected = tree->get_next_selected(tree->get_root());
while (selected) {
TreeItem *favorites_item = tree->get_root()->get_children();
if (selected == favorites_item) {
- // The "Favorites" item is not draggable
+ // The "Favorites" item is not draggable.
return Variant();
}
@@ -1845,12 +1867,11 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from)
}
bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary drag_data = p_data;
if (drag_data.has("type") && String(drag_data["type"]) == "favorite") {
- // Moving favorite around
+ // Moving favorite around.
TreeItem *ti = tree->get_item_at_position(p_point);
if (!ti)
return false;
@@ -1861,20 +1882,20 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
TreeItem *resources_item = favorites_item->get_next();
if (ti == favorites_item) {
- return (drop_section == 1); // The parent, first fav
+ return (drop_section == 1); // The parent, first fav.
}
if (ti->get_parent() && favorites_item == ti->get_parent()) {
return true; // A favorite
}
if (ti == resources_item) {
- return (drop_section == -1); // The tree, last fav
+ return (drop_section == -1); // The tree, last fav.
}
return false;
}
if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
- // Move resources
+ // Move resources.
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
@@ -1882,7 +1903,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) {
- // Move files or dir
+ // Move files or dir.
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
@@ -1893,8 +1914,8 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
if (to_dir.empty())
return false;
- //Attempting to move a folder into itself will fail later
- //Rather than bring up a message don't try to do it in the first place
+ // Attempting to move a folder into itself will fail later,
+ // rather than bring up a message don't try to do it in the first place
to_dir = to_dir.ends_with("/") ? to_dir : (to_dir + "/");
Vector<String> fnames = drag_data["files"];
for (int i = 0; i < fnames.size(); ++i) {
@@ -1909,7 +1930,6 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
if (!can_drop_data_fw(p_point, p_data, p_from))
return;
Dictionary drag_data = p_data;
@@ -1917,7 +1937,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
Vector<String> dirs = EditorSettings::get_singleton()->get_favorites();
if (drag_data.has("type") && String(drag_data["type"]) == "favorite") {
- // Moving favorite around
+ // Moving favorite around.
TreeItem *ti = tree->get_item_at_position(p_point);
if (!ti)
return;
@@ -1929,20 +1949,20 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
TreeItem *resources_item = favorites_item->get_next();
if (ti == favorites_item) {
- // Drop on the favorite folder
+ // Drop on the favorite folder.
drop_position = 0;
} else if (ti == resources_item) {
- // Drop on the resource item
+ // Drop on the resource item.
drop_position = dirs.size();
} else {
- // Drop in the list
+ // Drop in the list.
drop_position = dirs.find(ti->get_metadata(0));
if (drop_section == 1) {
drop_position++;
}
}
- // Remove dragged favorites
+ // Remove dragged favorites.
Vector<int> to_remove;
int offset = 0;
for (int i = 0; i < files.size(); i++) {
@@ -1958,7 +1978,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
dirs.remove(to_remove[i] - i);
}
- // Re-add them at the right position
+ // Re-add them at the right position.
for (int i = 0; i < files.size(); i++) {
dirs.insert(drop_position, files[i]);
drop_position++;
@@ -1973,7 +1993,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
- // Moving resource
+ // Moving resource.
Ref<Resource> res = drag_data["resource"];
String to_dir;
bool favorite;
@@ -1985,7 +2005,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) {
- // Move files or add to favorites
+ // Move files or add to favorites.
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
@@ -2015,7 +2035,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
target = String();
target_favorites = false;
- // In the file list
+ // In the file list.
if (p_from == files) {
int pos = files->get_item_at_position(p_point, true);
if (pos == -1) {
@@ -2027,12 +2047,12 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
return;
}
- // In the tree
+ // In the tree.
if (p_from == tree) {
TreeItem *ti = tree->get_item_at_position(p_point);
int section = tree->get_drop_section_at_position(p_point);
if (ti) {
- // Check the favorites first
+ // Check the favorites first.
if (ti == tree->get_root()->get_children() && section >= 0) {
target_favorites = true;
return;
@@ -2043,13 +2063,13 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
String fpath = ti->get_metadata(0);
if (section == 0) {
if (fpath.ends_with("/")) {
- // We drop on a folder
+ // We drop on a folder.
target = fpath;
return;
}
} else {
if (ti->get_parent() != tree->get_root()->get_children()) {
- // Not in the favorite section
+ // Not in the favorite section.
if (fpath != "res://") {
// We drop between two files
if (fpath.ends_with("/")) {
@@ -2066,7 +2086,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
}
void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths, bool p_display_path_dependent_options) {
- // Add options for files and folders
+ // Add options for files and folders.
ERR_FAIL_COND(p_paths.empty());
Vector<String> filenames;
@@ -2090,7 +2110,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(fpath) == "PackedScene");
}
- // Check if in favorites
+ // Check if in favorites.
bool found = false;
for (int j = 0; j < favorites.size(); j++) {
if (favorites[j] == fpath) {
@@ -2106,7 +2126,6 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
}
if (all_files) {
-
if (all_files_scenes) {
if (filenames.size() == 1) {
p_popup->add_item(TTR("Open Scene"), FILE_OPEN);
@@ -2146,19 +2165,25 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
if (p_paths.size() == 1) {
p_popup->add_item(TTR("Copy Path"), FILE_COPY_PATH);
- p_popup->add_item(TTR("Rename..."), FILE_RENAME);
- p_popup->add_item(TTR("Duplicate..."), FILE_DUPLICATE);
+ if (p_paths[0] != "res://") {
+ p_popup->add_item(TTR("Rename..."), FILE_RENAME);
+ p_popup->add_item(TTR("Duplicate..."), FILE_DUPLICATE);
+ }
}
- p_popup->add_item(TTR("Move To..."), FILE_MOVE);
- p_popup->add_item(TTR("Delete"), FILE_REMOVE);
+ if (p_paths.size() > 1 || p_paths[0] != "res://") {
+ p_popup->add_item(TTR("Move To..."), FILE_MOVE);
+ p_popup->add_item(TTR("Delete"), FILE_REMOVE);
+ }
if (p_paths.size() == 1) {
p_popup->add_separator();
if (p_display_path_dependent_options) {
p_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
+ p_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE);
p_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
p_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
+ p_popup->add_separator();
}
String fpath = p_paths[0];
@@ -2168,8 +2193,8 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str
}
void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
- // Right click is pressed in the tree
- Vector<String> paths = _tree_get_selected();
+ // Right click is pressed in the tree.
+ Vector<String> paths = _tree_get_selected(false);
if (paths.size() == 1) {
if (paths[0].ends_with("/")) {
@@ -2179,7 +2204,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
}
}
- // Popup
+ // Popup.
if (!paths.empty()) {
tree_popup->clear();
tree_popup->set_size(Size2(1, 1));
@@ -2190,11 +2215,12 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
}
void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) {
- // Right click is pressed in the empty space of the tree
+ // Right click is pressed in the empty space of the tree.
path = "res://";
tree_popup->clear();
tree_popup->set_size(Size2(1, 1));
tree_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
+ tree_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE);
tree_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
tree_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
tree_popup->set_position(tree->get_global_position() + p_pos);
@@ -2206,7 +2232,7 @@ void FileSystemDock::_tree_empty_selected() {
}
void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
- // Right click is pressed in the file list
+ // Right click is pressed in the file list.
Vector<String> paths;
for (int i = 0; i < files->get_item_count(); i++) {
if (!files->is_selected(i))
@@ -2218,7 +2244,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
paths.push_back(files->get_item_metadata(i));
}
- // Popup
+ // Popup.
if (!paths.empty()) {
file_list_popup->clear();
file_list_popup->set_size(Size2(1, 1));
@@ -2229,7 +2255,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
}
void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
- // Right click on empty space for file list
+ // Right click on empty space for file list.
if (searched_string.length() > 0)
return;
@@ -2237,21 +2263,21 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
file_list_popup->set_size(Size2(1, 1));
file_list_popup->add_item(TTR("New Folder..."), FILE_NEW_FOLDER);
+ file_list_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE);
file_list_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT);
file_list_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE);
- file_list_popup->add_item(TTR("Show in File Manager"), FILE_SHOW_IN_EXPLORER);
+ file_list_popup->add_separator();
+ file_list_popup->add_item(TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER);
file_list_popup->set_position(files->get_global_position() + p_pos);
file_list_popup->popup();
}
void FileSystemDock::select_file(const String &p_file) {
-
_navigate_to_path(p_file);
}
void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) {
-
- // Set the path to the current focused item
+ // Set the path to the current focused item.
int current = files->get_current();
if (current == p_index) {
String fpath = files->get_item_metadata(current);
@@ -2263,15 +2289,14 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) {
}
}
- // Update the import dock
+ // Update the import dock.
import_dock_needs_update = true;
call_deferred("_update_import_dock");
}
void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
-
if (get_viewport()->get_modal_stack_top())
- return; //ignore because of modal window
+ return; // Ignore because of modal window.
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
@@ -2288,9 +2313,8 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
}
void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
-
if (get_viewport()->get_modal_stack_top())
- return; //ignore because of modal window
+ return; // Ignore because of modal window.
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
@@ -2307,18 +2331,17 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
}
void FileSystemDock::_update_import_dock() {
-
if (!import_dock_needs_update)
return;
- // List selected
+ // List selected.
Vector<String> selected;
if (display_mode == DISPLAY_MODE_TREE_ONLY) {
// Use the tree
selected = _tree_get_selected();
} else {
- // Use the file list
+ // Use the file list.
for (int i = 0; i < files->get_item_count(); i++) {
if (!files->is_selected(i))
continue;
@@ -2327,7 +2350,7 @@ void FileSystemDock::_update_import_dock() {
}
}
- // Check import
+ // Check import.
Vector<String> imports;
String import_type;
for (int i = 0; i < selected.size(); i++) {
@@ -2354,7 +2377,7 @@ void FileSystemDock::_update_import_dock() {
if (import_type == "") {
import_type = type;
} else if (import_type != type) {
- //all should be the same type
+ // All should be the same type.
imports.clear();
break;
}
@@ -2373,12 +2396,10 @@ void FileSystemDock::_update_import_dock() {
}
void FileSystemDock::_feature_profile_changed() {
-
_update_display_mode(true);
}
void FileSystemDock::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_file_list_gui_input"), &FileSystemDock::_file_list_gui_input);
ClassDB::bind_method(D_METHOD("_tree_gui_input"), &FileSystemDock::_tree_gui_input);
@@ -2411,6 +2432,7 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_fs_changed"), &FileSystemDock::_fs_changed);
ClassDB::bind_method(D_METHOD("_tree_multi_selected"), &FileSystemDock::_tree_multi_selected);
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);
+ ClassDB::bind_method(D_METHOD("_make_scene_confirm"), &FileSystemDock::_make_scene_confirm);
ClassDB::bind_method(D_METHOD("_resource_created"), &FileSystemDock::_resource_created);
ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false));
ClassDB::bind_method(D_METHOD("_move_with_overwrite"), &FileSystemDock::_move_with_overwrite);
@@ -2442,7 +2464,6 @@ void FileSystemDock::_bind_methods() {
}
FileSystemDock::FileSystemDock(EditorNode *p_editor) {
-
set_name("FileSystem");
editor = p_editor;
path = "res://";
@@ -2523,7 +2544,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE));
split_box->add_child(tree);
- tree->connect("item_edited", this, "_favorite_toggled");
tree->connect("item_activated", this, "_tree_activate_file");
tree->connect("multi_selected", this, "_tree_multi_selected");
tree->connect("item_rmb_selected", this, "_tree_rmb_select");
@@ -2626,6 +2646,17 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
make_dir_dialog->register_text_enter(make_dir_dialog_text);
make_dir_dialog->connect("confirmed", this, "_make_dir_confirm");
+ make_scene_dialog = memnew(ConfirmationDialog);
+ make_scene_dialog->set_title(TTR("Create Scene"));
+ VBoxContainer *make_scene_dialog_vb = memnew(VBoxContainer);
+ make_scene_dialog->add_child(make_scene_dialog_vb);
+
+ make_scene_dialog_text = memnew(LineEdit);
+ make_scene_dialog_vb->add_margin_child(TTR("Name:"), make_scene_dialog_text);
+ add_child(make_scene_dialog);
+ make_scene_dialog->register_text_enter(make_scene_dialog_text);
+ make_scene_dialog->connect("confirmed", this, "_make_scene_confirm");
+
make_script_dialog_text = memnew(ScriptCreateDialog);
make_script_dialog_text->set_title(TTR("Create Script"));
add_child(make_script_dialog_text);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 6de370ad29..49eb31e330 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -87,6 +87,7 @@ private:
FILE_INFO,
FILE_NEW_FOLDER,
FILE_NEW_SCRIPT,
+ FILE_NEW_SCENE,
FILE_SHOW_IN_EXPLORER,
FILE_COPY_PATH,
FILE_NEW_RESOURCE,
@@ -135,6 +136,8 @@ private:
LineEdit *duplicate_dialog_text;
ConfirmationDialog *make_dir_dialog;
LineEdit *make_dir_dialog_text;
+ ConfirmationDialog *make_scene_dialog;
+ LineEdit *make_scene_dialog_text;
ConfirmationDialog *overwrite_dialog;
ScriptCreateDialog *make_script_dialog_text;
CreateDialog *new_resource_dialog;
@@ -168,7 +171,7 @@ private:
bool updating_tree;
int tree_update_id;
- Tree *tree; //directories
+ Tree *tree;
ItemList *files;
bool import_dock_needs_update;
@@ -213,6 +216,7 @@ private:
void _resource_created() const;
void _make_dir_confirm();
+ void _make_scene_confirm();
void _rename_operation_confirm();
void _duplicate_operation_confirm();
void _move_with_overwrite();
@@ -246,7 +250,6 @@ private:
String name;
String path;
StringName type;
- int import_status; //0 not imported, 1 - ok, 2- must reimport, 3- broken
Vector<String> sources;
bool import_broken;
@@ -275,6 +278,7 @@ private:
bool _is_file_type_disabled_by_feature_profile(const StringName &p_class);
void _feature_profile_changed();
+ Vector<String> _remove_self_included_paths(Vector<String> selected_strings);
protected:
void _notification(int p_what);
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index e1ab5c62a7..def22d07de 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -221,8 +221,8 @@ float FindInFiles::get_progress() const {
void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) {
- DirAccess *dir = DirAccess::open(path);
- if (dir == NULL) {
+ DirAccessRef dir = DirAccess::open(path);
+ if (!dir) {
print_verbose("Cannot open directory! " + path);
return;
}
@@ -253,8 +253,8 @@ void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) {
void FindInFiles::_scan_file(String fpath) {
- FileAccess *f = FileAccess::open(fpath, FileAccess::READ);
- if (f == NULL) {
+ FileAccessRef f = FileAccess::open(fpath, FileAccess::READ);
+ if (!f) {
print_verbose(String("Cannot open file ") + fpath);
return;
}
@@ -524,6 +524,7 @@ FindInFilesPanel::FindInFilesPanel() {
_progress_bar = memnew(ProgressBar);
_progress_bar->set_h_size_flags(SIZE_EXPAND_FILL);
+ _progress_bar->set_v_size_flags(SIZE_SHRINK_CENTER);
hbc->add_child(_progress_bar);
set_progress_visible(false);
@@ -546,6 +547,7 @@ FindInFilesPanel::FindInFilesPanel() {
_results_display->connect("item_edited", this, "_on_item_edited");
_results_display->set_hide_root(true);
_results_display->set_select_mode(Tree::SELECT_ROW);
+ _results_display->set_allow_rmb_select(true);
_results_display->create_item(); // Root
vbc->add_child(_results_display);
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 5a8dc205c2..4cefb53617 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -35,12 +35,6 @@
#include "scene/gui/label.h"
#include "scene/resources/packed_scene.h"
-void GroupDialog::ok_pressed() {
-}
-
-void GroupDialog::_cancel_pressed() {
-}
-
void GroupDialog::_group_selected() {
nodes_to_add->clear();
add_node_root = nodes_to_add->create_item();
@@ -49,11 +43,14 @@ void GroupDialog::_group_selected() {
remove_node_root = nodes_to_remove->create_item();
if (!groups->is_anything_selected()) {
+ group_empty->hide();
return;
}
selected_group = groups->get_selected()->get_text(0);
_load_nodes(scene_tree->get_edited_scene_root());
+
+ group_empty->set_visible(!remove_node_root->get_children());
}
void GroupDialog::_load_nodes(Node *p_current) {
@@ -129,15 +126,26 @@ void GroupDialog::_add_pressed() {
return;
}
+ undo_redo->create_action(TTR("Add to Group"));
+
while (selected) {
Node *node = scene_tree->get_edited_scene_root()->get_node(selected->get_metadata(0));
- node->add_to_group(selected_group, true);
+ undo_redo->add_do_method(node, "add_to_group", selected_group, true);
+ undo_redo->add_undo_method(node, "remove_from_group", selected_group);
selected = nodes_to_add->get_next_selected(selected);
}
- _group_selected();
- EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree();
+ undo_redo->add_do_method(this, "_group_selected");
+ undo_redo->add_undo_method(this, "_group_selected");
+ undo_redo->add_do_method(this, "emit_signal", "group_edited");
+ undo_redo->add_undo_method(this, "emit_signal", "group_edited");
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+
+ undo_redo->commit_action();
}
void GroupDialog::_removed_pressed() {
@@ -147,15 +155,26 @@ void GroupDialog::_removed_pressed() {
return;
}
+ undo_redo->create_action(TTR("Remove from Group"));
+
while (selected) {
Node *node = scene_tree->get_edited_scene_root()->get_node(selected->get_metadata(0));
- node->remove_from_group(selected_group);
+ undo_redo->add_do_method(node, "remove_from_group", selected_group);
+ undo_redo->add_undo_method(node, "add_to_group", selected_group, true);
selected = nodes_to_add->get_next_selected(selected);
}
- _group_selected();
- EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree();
+ undo_redo->add_do_method(this, "_group_selected");
+ undo_redo->add_undo_method(this, "_group_selected");
+ undo_redo->add_do_method(this, "emit_signal", "group_edited");
+ undo_redo->add_undo_method(this, "emit_signal", "group_edited");
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+
+ undo_redo->commit_action();
}
void GroupDialog::_remove_filter_changed(const String &p_filter) {
@@ -166,11 +185,29 @@ void GroupDialog::_add_filter_changed(const String &p_filter) {
_group_selected();
}
-void GroupDialog::_add_group_pressed() {
+void GroupDialog::_add_group_pressed(const String &p_name) {
_add_group(add_group_text->get_text());
add_group_text->clear();
}
+void GroupDialog::_add_group(String p_name) {
+ if (!is_visible()) {
+ return; // No need to edit the dialog if it's not being used.
+ }
+
+ String name = p_name.strip_edges();
+ if (name == "" || groups->search_item_text(name)) {
+ return;
+ }
+
+ TreeItem *new_group = groups->create_item(groups_root);
+ new_group->set_text(0, name);
+ new_group->add_button(0, get_icon("Remove", "EditorIcons"), 0);
+ new_group->set_editable(0, true);
+ new_group->select(0);
+ groups->ensure_cursor_is_visible();
+}
+
void GroupDialog::_group_renamed() {
TreeItem *renamed_group = groups->get_edited();
if (!renamed_group) {
@@ -194,38 +231,51 @@ void GroupDialog::_group_renamed() {
return;
}
+ undo_redo->create_action(TTR("Rename Group"));
+
List<Node *> nodes;
scene_tree->get_nodes_in_group(selected_group, &nodes);
bool removed_all = true;
for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
Node *node = E->get();
if (_can_edit(node, selected_group)) {
- node->remove_from_group(selected_group);
- node->add_to_group(name, true);
+ undo_redo->add_do_method(node, "remove_from_group", selected_group);
+ undo_redo->add_undo_method(node, "remove_from_group", name);
+ undo_redo->add_do_method(node, "add_to_group", name, true);
+ undo_redo->add_undo_method(node, "add_to_group", selected_group, true);
} else {
removed_all = false;
}
}
if (!removed_all) {
- _add_group(selected_group);
+ undo_redo->add_do_method(this, "_add_group", selected_group);
+ undo_redo->add_undo_method(this, "_delete_group_item", selected_group);
}
- selected_group = renamed_group->get_text(0);
- _group_selected();
-}
+ undo_redo->add_do_method(this, "_rename_group_item", selected_group, renamed_group->get_text(0));
+ undo_redo->add_undo_method(this, "_rename_group_item", renamed_group->get_text(0), selected_group);
+ undo_redo->add_do_method(this, "_group_selected");
+ undo_redo->add_undo_method(this, "_group_selected");
+ undo_redo->add_do_method(this, "emit_signal", "group_edited");
+ undo_redo->add_undo_method(this, "emit_signal", "group_edited");
-void GroupDialog::_add_group(String p_name) {
+ undo_redo->commit_action();
+}
- String name = p_name.strip_edges();
- if (name == "" || groups->search_item_text(name)) {
- return;
+void GroupDialog::_rename_group_item(const String &p_old_name, const String &p_new_name) {
+ if (!is_visible()) {
+ return; // No need to edit the dialog if it's not being used.
}
- TreeItem *new_group = groups->create_item(groups_root);
- new_group->set_text(0, name);
- new_group->add_button(0, get_icon("Remove", "EditorIcons"), 0);
- new_group->set_editable(0, true);
+ selected_group = p_new_name;
+
+ for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) {
+ if (E->get_text(0) == p_old_name) {
+ E->set_text(0, p_new_name);
+ return;
+ }
+ }
}
void GroupDialog::_load_groups(Node *p_current) {
@@ -251,29 +301,57 @@ void GroupDialog::_delete_group_pressed(Object *p_item, int p_column, int p_id)
String name = ti->get_text(0);
+ undo_redo->create_action(TTR("Delete Group"));
+
List<Node *> nodes;
scene_tree->get_nodes_in_group(name, &nodes);
bool removed_all = true;
for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
if (_can_edit(E->get(), name)) {
- E->get()->remove_from_group(name);
+ undo_redo->add_do_method(E->get(), "remove_from_group", name);
+ undo_redo->add_undo_method(E->get(), "add_to_group", name, true);
} else {
removed_all = false;
}
}
if (removed_all) {
- if (selected_group == name) {
- add_filter->clear();
- remove_filter->clear();
- nodes_to_remove->clear();
- nodes_to_add->clear();
- groups->deselect_all();
- selected_group = "";
+ undo_redo->add_do_method(this, "_delete_group_item", name);
+ undo_redo->add_undo_method(this, "_add_group", name);
+ }
+
+ undo_redo->add_do_method(this, "_group_selected");
+ undo_redo->add_undo_method(this, "_group_selected");
+ undo_redo->add_do_method(this, "emit_signal", "group_edited");
+ undo_redo->add_undo_method(this, "emit_signal", "group_edited");
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+
+ undo_redo->commit_action();
+}
+
+void GroupDialog::_delete_group_item(const String &p_name) {
+ if (!is_visible()) {
+ return; // No need to edit the dialog if it's not being used.
+ }
+
+ if (selected_group == p_name) {
+ add_filter->clear();
+ remove_filter->clear();
+ nodes_to_remove->clear();
+ nodes_to_add->clear();
+ groups->deselect_all();
+ selected_group = "";
+ }
+
+ for (TreeItem *E = groups_root->get_children(); E; E = E->get_next()) {
+ if (E->get_text(0) == p_name) {
+ groups_root->remove_child(E);
+ return;
}
- groups_root->remove_child(ti);
}
- EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree();
}
void GroupDialog::_notification(int p_what) {
@@ -291,8 +369,7 @@ void GroupDialog::_notification(int p_what) {
}
void GroupDialog::edit() {
-
- popup_centered(Size2(600, 400));
+ popup_centered();
groups->clear();
groups_root = groups->create_item();
@@ -308,27 +385,32 @@ void GroupDialog::edit() {
}
void GroupDialog::_bind_methods() {
- ClassDB::bind_method("_cancel", &GroupDialog::_cancel_pressed);
-
ClassDB::bind_method("_add_pressed", &GroupDialog::_add_pressed);
ClassDB::bind_method("_removed_pressed", &GroupDialog::_removed_pressed);
ClassDB::bind_method("_delete_group_pressed", &GroupDialog::_delete_group_pressed);
+ ClassDB::bind_method("_delete_group_item", &GroupDialog::_delete_group_item);
ClassDB::bind_method("_group_selected", &GroupDialog::_group_selected);
ClassDB::bind_method("_add_group_pressed", &GroupDialog::_add_group_pressed);
+ ClassDB::bind_method("_add_group", &GroupDialog::_add_group);
ClassDB::bind_method("_add_filter_changed", &GroupDialog::_add_filter_changed);
ClassDB::bind_method("_remove_filter_changed", &GroupDialog::_remove_filter_changed);
ClassDB::bind_method("_group_renamed", &GroupDialog::_group_renamed);
+ ClassDB::bind_method("_rename_group_item", &GroupDialog::_rename_group_item);
+
+ ADD_SIGNAL(MethodInfo("group_edited"));
}
GroupDialog::GroupDialog() {
+ set_custom_minimum_size(Size2(600, 400));
scene_tree = SceneTree::get_singleton();
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
+ vbc->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
HBoxContainer *hbc = memnew(HBoxContainer);
vbc->add_child(hbc);
@@ -345,10 +427,11 @@ GroupDialog::GroupDialog() {
groups = memnew(Tree);
vbc_left->add_child(groups);
groups->set_hide_root(true);
- groups->set_v_size_flags(SIZE_EXPAND_FILL);
groups->set_select_mode(Tree::SELECT_SINGLE);
groups->set_allow_reselect(true);
groups->set_allow_rmb_select(true);
+ groups->set_v_size_flags(SIZE_EXPAND_FILL);
+ groups->add_constant_override("draw_guides", 1);
groups->connect("item_selected", this, "_group_selected");
groups->connect("button_pressed", this, "_delete_group_pressed");
groups->connect("item_edited", this, "_group_renamed");
@@ -360,26 +443,28 @@ GroupDialog::GroupDialog() {
add_group_text = memnew(LineEdit);
chbc->add_child(add_group_text);
add_group_text->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_group_text->connect("text_entered", this, "_add_group_pressed");
Button *add_group_button = memnew(Button);
add_group_button->set_text("Add");
chbc->add_child(add_group_button);
- add_group_button->connect("pressed", this, "_add_group_pressed");
+ add_group_button->connect("pressed", this, "_add_group_pressed", varray(String()));
VBoxContainer *vbc_add = memnew(VBoxContainer);
hbc->add_child(vbc_add);
vbc_add->set_h_size_flags(SIZE_EXPAND_FILL);
Label *out_of_group_title = memnew(Label);
- out_of_group_title->set_text(TTR("Nodes not in Group"));
+ out_of_group_title->set_text(TTR("Nodes Not in Group"));
vbc_add->add_child(out_of_group_title);
nodes_to_add = memnew(Tree);
vbc_add->add_child(nodes_to_add);
nodes_to_add->set_hide_root(true);
nodes_to_add->set_hide_folding(true);
- nodes_to_add->set_v_size_flags(SIZE_EXPAND_FILL);
nodes_to_add->set_select_mode(Tree::SELECT_MULTI);
+ nodes_to_add->set_v_size_flags(SIZE_EXPAND_FILL);
+ nodes_to_add->add_constant_override("draw_guides", 1);
nodes_to_add->connect("item_selected", this, "_nodes_to_add_selected");
HBoxContainer *add_filter_hbc = memnew(HBoxContainer);
@@ -426,6 +511,7 @@ GroupDialog::GroupDialog() {
nodes_to_remove->set_hide_root(true);
nodes_to_remove->set_hide_folding(true);
nodes_to_remove->set_select_mode(Tree::SELECT_MULTI);
+ nodes_to_remove->add_constant_override("draw_guides", 1);
nodes_to_remove->connect("item_selected", this, "_node_to_remove_selected");
HBoxContainer *remove_filter_hbc = memnew(HBoxContainer);
@@ -438,8 +524,15 @@ GroupDialog::GroupDialog() {
remove_filter_hbc->add_child(remove_filter);
remove_filter->connect("text_changed", this, "_remove_filter_changed");
- set_title("Group Editor");
- get_cancel()->hide();
+ group_empty = memnew(Label());
+ group_empty->set_text(TTR("Empty groups will be automatically removed."));
+ group_empty->set_valign(Label::VALIGN_CENTER);
+ group_empty->set_align(Label::ALIGN_CENTER);
+ group_empty->set_autowrap(true);
+ nodes_to_remove->add_child(group_empty);
+ group_empty->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+
+ set_title(TTR("Group Editor"));
set_as_toplevel(true);
set_resizable(true);
@@ -465,11 +558,13 @@ void GroupsEditor::_add_group(const String &p_group) {
undo_redo->create_action(TTR("Add to Group"));
undo_redo->add_do_method(node, "add_to_group", name, true);
- undo_redo->add_do_method(this, "update_tree");
undo_redo->add_undo_method(node, "remove_from_group", name);
+ undo_redo->add_do_method(this, "update_tree");
undo_redo->add_undo_method(this, "update_tree");
- undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
- undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
undo_redo->commit_action();
@@ -490,11 +585,13 @@ void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) {
undo_redo->create_action(TTR("Remove from Group"));
undo_redo->add_do_method(node, "remove_from_group", name);
- undo_redo->add_do_method(this, "update_tree");
undo_redo->add_undo_method(node, "add_to_group", name, true);
+ undo_redo->add_do_method(this, "update_tree");
undo_redo->add_undo_method(this, "update_tree");
- undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
- undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
+
+ // To force redraw of scene tree.
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree");
undo_redo->commit_action();
}
@@ -562,11 +659,9 @@ void GroupsEditor::set_current(Node *p_node) {
}
void GroupsEditor::_show_group_dialog() {
- group_dialog->edit();
-}
-void GroupsEditor::_group_dialog_closed() {
- update_tree();
+ group_dialog->edit();
+ group_dialog->set_undo_redo(undo_redo);
}
void GroupsEditor::_bind_methods() {
@@ -576,7 +671,6 @@ void GroupsEditor::_bind_methods() {
ClassDB::bind_method("update_tree", &GroupsEditor::update_tree);
ClassDB::bind_method("_show_group_dialog", &GroupsEditor::_show_group_dialog);
- ClassDB::bind_method("_group_dialog_closed", &GroupsEditor::_group_dialog_closed);
}
GroupsEditor::GroupsEditor() {
@@ -588,7 +682,7 @@ GroupsEditor::GroupsEditor() {
group_dialog = memnew(GroupDialog);
group_dialog->set_as_toplevel(true);
add_child(group_dialog);
- group_dialog->connect("popup_hide", this, "_group_dialog_closed");
+ group_dialog->connect("group_edited", this, "update_tree");
Button *group_dialog_button = memnew(Button);
group_dialog_button->set_text(TTR("Manage Groups"));
@@ -613,6 +707,7 @@ GroupsEditor::GroupsEditor() {
tree->set_v_size_flags(SIZE_EXPAND_FILL);
vbc->add_child(tree);
tree->connect("button_pressed", this, "_remove_group");
+ tree->add_constant_override("draw_guides", 1);
add_constant_override("separation", 3 * EDSCALE);
}
diff --git a/editor/groups_editor.h b/editor/groups_editor.h
index 4ffeea84e7..78ef99d5c8 100644
--- a/editor/groups_editor.h
+++ b/editor/groups_editor.h
@@ -41,13 +41,9 @@
#include "scene/gui/tool_button.h"
#include "scene/gui/tree.h"
-/**
-@author Juan Linietsky <reduzio@gmail.com>
-*/
+class GroupDialog : public WindowDialog {
-class GroupDialog : public ConfirmationDialog {
-
- GDCLASS(GroupDialog, ConfirmationDialog);
+ GDCLASS(GroupDialog, WindowDialog);
ConfirmationDialog *error;
@@ -66,13 +62,15 @@ class GroupDialog : public ConfirmationDialog {
TreeItem *remove_node_root;
LineEdit *remove_filter;
+ Label *group_empty;
+
ToolButton *add_button;
ToolButton *remove_button;
String selected_group;
- void ok_pressed();
- void _cancel_pressed();
+ UndoRedo *undo_redo;
+
void _group_selected();
void _remove_filter_changed(const String &p_filter);
@@ -80,12 +78,14 @@ class GroupDialog : public ConfirmationDialog {
void _add_pressed();
void _removed_pressed();
- void _add_group_pressed();
+ void _add_group_pressed(const String &p_name);
void _group_renamed();
+ void _rename_group_item(const String &p_old_name, const String &p_new_name);
void _add_group(String p_name);
void _delete_group_pressed(Object *p_item, int p_column, int p_id);
+ void _delete_group_item(const String &p_name);
bool _can_edit(Node *p_node, String p_group);
@@ -98,6 +98,7 @@ protected:
public:
void edit();
+ void set_undo_redo(UndoRedo *p_undoredo) { undo_redo = p_undoredo; }
GroupDialog();
};
@@ -122,7 +123,6 @@ class GroupsEditor : public VBoxContainer {
void _close();
void _show_group_dialog();
- void _group_dialog_closed();
protected:
static void _bind_methods();
diff --git a/editor/icons/icon_GUI_tree_option.svg b/editor/icons/icon_GUI_tree_option.svg
deleted file mode 100644
index 4200745a78..0000000000
--- a/editor/icons/icon_GUI_tree_option.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1038.4)">
-<path transform="translate(0 1038.4)" d="m7.5 1a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm0 5a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm0 5a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5z" fill="#fff" fill-opacity=".58824" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_arrow_down.svg b/editor/icons/icon_arrow_down.svg
new file mode 100644
index 0000000000..49a93e6e28
--- /dev/null
+++ b/editor/icons/icon_arrow_down.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 3.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l2.293 2.293h-4.5859c-.55228 0-1 .4477-1 1s.44772 1 1 1h4.5859l-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l4-4a1.0001 1.0001 0 0 0 0-1.4141l-4-4a1 1 0 0 0 -.7207-.29102z" fill="#e0e0e0" fill-opacity=".99608" transform="matrix(0 1 -1 0 16.0021 -.00004)"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_arrow_up.svg b/editor/icons/icon_arrow_up.svg
index 77a20e8c50..9bf19a6a12 100644
--- a/editor/icons/icon_arrow_up.svg
+++ b/editor/icons/icon_arrow_up.svg
@@ -1,5 +1 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m2.9875 1044.4a1.0001 1.0001 0 0 0 1.7168 0.6972l2.293-2.2929v4.5859a1.0001 1.0001 0 1 0 2 0v-4.5859l2.293 2.2929a1.0001 1.0001 0 1 0 1.4141 -1.414l-3.9141-3.9141a1.0001 1.0001 0 0 0 -1.5859 0 1.0001 1.0001 0 0 0 -0.00391 0.01l-3.9102 3.9102a1.0001 1.0001 0 0 0 -0.30273 0.7168z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</g>
-</svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8.00008 1049.4022a1 1 0 0 0 .69336-.291 1 1 0 0 0 0-1.4141l-2.293-2.293h4.5859c.55228 0 1-.4477 1-1s-.44772-1-1-1h-4.5859l2.293-2.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-4 4a1.0001 1.0001 0 0 0 0 1.4141l4 4a1 1 0 0 0 .7207.291z" fill="#e0e0e0" fill-opacity=".99608" transform="matrix(0 1 -1 0 1052.4021 -.00004)"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_auto_key.svg b/editor/icons/icon_auto_key.svg
index cbafe1ac38..3d5569397f 100644
--- a/editor/icons/icon_auto_key.svg
+++ b/editor/icons/icon_auto_key.svg
@@ -1,56 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="16"
- height="16"
- version="1.1"
- viewBox="0 0 16 16"
- id="svg6"
- sodipodi:docname="icon_auto_key.svg"
- inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
- <metadata
- id="metadata12">
- <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></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1854"
- inkscape:window-height="1016"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="10.429825"
- inkscape:cx="10.199345"
- inkscape:cy="-4.0344119"
- inkscape:window-x="66"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg6" />
- <path
- style="fill:#e0e0e0;fill-opacity:1;stroke-width:0.0333107"
- d="M 3.5469681,13.426786 C 2.7965829,13.263778 2.2774312,12.503915 2.4037297,11.753472 c 0.1081234,-0.642451 0.6006808,-1.135008 1.2431317,-1.243131 0.9667125,-0.162696 1.8555225,0.726112 1.6928259,1.692826 -0.103766,0.616558 -0.5592173,1.098057 -1.1588427,1.225117 -0.2719576,0.05763 -0.3626872,0.05741 -0.6338765,-0.0014 z m 8.0861339,-0.08275 c -0.746862,-0.13829 -1.23937,-0.720718 -1.23937,-1.465649 0,-0.527377 0.244831,-0.978806 0.679757,-1.253362 0.471386,-0.297574 1.114188,-0.297574 1.585574,0 0.682727,0.430986 0.892336,1.362194 0.460575,2.046149 -0.307786,0.487563 -0.940521,0.773963 -1.486536,0.672862 z M 0.60726032,9.8305658 V 7.7161233 L 1.1770842,7.7070075 1.7469079,7.6978939 3.1889882,5.1995916 4.6310686,2.7012893 h 3.1726318 3.1726316 l 1.442755,2.4983023 1.442755,2.4983023 0.651097,0.00903 0.651096,0.00903 v 2.1145264 2.1145257 h -0.566282 -0.566281 v -0.161225 c 0,-0.234927 -0.113135,-0.639704 -0.255664,-0.914727 -0.16895,-0.326004 -0.574198,-0.731251 -0.900202,-0.9002019 -0.656732,-0.3403483 -1.428549,-0.3403483 -2.085281,0 -0.326004,0.1689519 -0.731252,0.5741989 -0.9002019,0.9002029 -0.1425297,0.275023 -0.2556639,0.6798 -0.2556639,0.914727 v 0.161225 H 7.8570969 6.0797346 L 6.0617736,11.686851 C 6.006289,10.889347 5.447548,10.170679 4.6603773,9.884336 4.4466221,9.8065798 4.3737631,9.797427 3.9716406,9.7978134 3.5871254,9.7981885 3.4905638,9.809405 3.3054265,9.8752358 2.5067319,10.159236 1.9362359,10.884501 1.8813215,11.68568 l -0.017772,0.259329 H 1.2354063 0.60726287 Z M 12.399247,7.7466889 c 0,-0.037287 -0.02623,-0.1073444 -0.0583,-0.1556843 -0.03206,-0.04834 -0.561225,-0.958444 -1.17592,-2.0224529 L 10.047407,3.6339894 7.6977565,3.6254406 C 5.4917229,3.6174174 5.3450379,3.6204563 5.2979001,3.6754094 5.1898818,3.8013046 2.9723198,7.6840061 2.9723198,7.7472381 c 0,0.067139 0.00758,0.067247 4.7134636,0.067247 h 4.7134636 z"
- id="path6243"
- inkscape:connector-curvature="0" />
-</svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m5 3-3 5h-1v4h1.0507812a2.5 2.5 0 0 1 2.4492188-2 2.5 2.5 0 0 1 2.4453125 2h2.1054687a2.5 2.5 0 0 1 2.4492188-2 2.5 2.5 0 0 1 2.445312 2h1.054688v-4h-1l-4-5zm1 1h3l3 4h-8z" stroke-width=".033311"/><circle cx="4.5" cy="12.5" r="1.5"/><circle cx="11.5" cy="12.5" r="1.5"/></g></svg> \ No newline at end of file
diff --git a/editor/icons/icon_bus_vu_db.svg b/editor/icons/icon_bus_vu_db.svg
deleted file mode 100644
index 236e41e1f5..0000000000
--- a/editor/icons/icon_bus_vu_db.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-<svg width="32" height="128" version="1.1" viewBox="0 0 32 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<defs>
-<linearGradient id="a" x1="16" x2="16" y2="128" gradientUnits="userSpaceOnUse">
-<stop stop-color="#ff7a7a" offset="0"/>
-<stop stop-color="#e1dc7a" offset=".5"/>
-<stop stop-color="#66ff9e" offset="1"/>
-</linearGradient>
-</defs>
-<g transform="translate(0 -924.36)">
-<path transform="translate(0 924.36)" d="m1.5 0c-0.831 0-1.5 0.669-1.5 1.5 0 0.831 0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5 0-0.831-0.669-1.5-1.5-1.5h-2zm0 7c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 3.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633-0.83248 0.70724-2.0616 1.4518-3.3574 2.3008-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01912 1.3523-2.0191 0-2h-1.7852c0.28375-0.20667 0.63106-0.39443 0.88867-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-7.0293 0.25195c-0.14519 0.0037-0.28782 0.03907-0.41797 0.10352l-2 1c-1.1924 0.59646-0.29787 2.3855 0.89453 1.7891l0.55273-0.27539v5.3809c-0.01913 1.3523 2.0191 1.3523 2 0v-7c-9.16e-4 -0.56314-0.4664-1.0145-1.0293-0.99805zm-15.471 2.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm0 7c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm21.5 3c-0.554 0-1 0.446-1 1v1 2h-0.92969c-0.02343-8.24e-4 -0.046882-8.24e-4 -0.070312 0-1.0702 0-2.0626 0.57318-2.5977 1.5-0.5351 0.92681-0.5351 2.0732 0 3 0.5351 0.92681 1.5275 1.5 2.5977 1.5h2c0.554 0 1-0.446 1-1v-8c0-0.554-0.446-1-1-1zm4 0c-0.554 0-1 0.446-1 1v8c0 0.554 0.446 1 1 1h2c1.0702 0 2.0626-0.57319 2.5977-1.5 0.5351-0.92682 0.5351-2.0732 0-3-0.10504-0.18193-0.23173-0.34698-0.36914-0.5 0.1378-0.15331 0.26385-0.31764 0.36914-0.5 0.5351-0.92682 0.5351-2.0732 0-3-0.5351-0.92682-1.5275-1.5-2.5977-1.5h-2zm-14 1c-1.6447 0-3 1.3553-3 3v3c0 1.6447 1.3553 3 3 3s3-1.3553 3-3v-3c0-1.6447-1.3553-3-3-3zm15 1h1c0.35887 0 0.6858 0.18921 0.86523 0.5 0.17944 0.31079 0.17944 0.68921 0 1-0.17943 0.31079-0.50636 0.5-0.86523 0.5h-0.070312-0.92969v-2zm-15 1c0.5713 0 1 0.4287 1 1v3c0 0.5713-0.4287 1-1 1s-1-0.4287-1-1v-3c0-0.5713 0.4287-1 1-1zm-11.5 1c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm19.5 2h1v2h-0.92969c-0.02343-8.24e-4 -0.046882-8.24e-4 -0.070312 0-0.35887 0-0.6858-0.18921-0.86523-0.5-0.17944-0.31079-0.17944-0.68921 0-1 0.17943-0.31079 0.50636-0.5 0.86523-0.5zm7 0h1c0.35887 0 0.6858 0.18921 0.86523 0.5 0.17944 0.31079 0.17944 0.68921 0 1-0.17943 0.31079-0.50636 0.5-0.86523 0.5h-1v-2zm-26.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 2.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633-0.83248 0.70724-2.0616 1.4518-3.3574 2.3008-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01913 1.3523-2.0191 0-2h-1.7852c0.28375-0.20667 0.63106-0.39443 0.88867-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-7.0293 0.25195c-0.14519 0.0037-0.28782 0.03907-0.41797 0.10352l-2 1c-1.1924 0.59646-0.29787 2.3855 0.89453 1.7891l0.55273-0.27539v5.3809c-0.01913 1.3523 2.0191 1.3523 2 0v-7c-9.16e-4 -0.56314-0.4664-1.0145-1.0293-0.99805zm-15.471 3.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 1v2h3v-2h-3zm-7 6c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm15.986 3.75c-1.5 0-3 1.3056-3 3.25-0.01913 1.3523 2.0191 1.3523 2 0 0-1.0556 0.5-1.25 1-1.25s1 0.19444 1 1.25c0 0.59157-0.35893 1.156-1.1914 1.8633s-2.0616 1.4518-3.3574 2.3008c-0.82974 0.54516-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.01913 1.3523-2.0191 0-2h-1.7871c0.2841-0.20689 0.63273-0.39419 0.89062-0.61328 1.0302-0.87519 1.8965-1.9783 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm7.0469 0.23828c-0.36561-0.0093-0.70715 0.18167-0.89062 0.49805l-3 5c-0.39877 0.66633 0.080888 1.5131 0.85742 1.5137h3v1c-0.01912 1.3523 2.0191 1.3523 2 0v-2c-5.5e-5 -0.55226-0.44774-0.99994-1-1h-2.2324l2.0898-3.4844c0.40768-0.65656-0.05163-1.5077-0.82422-1.5273zm-23.533 3.0117c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm24.547 4.9961c-0.12355-0.0037-0.24673 0.01547-0.36328 0.05664 0 0-0.98349 0.3331-1.8906 1.2402-0.90714 0.90717-1.793 2.457-1.793 4.707-6.13e-4 0.07218 0.006604 0.14421 0.021484 0.21484 0.11389 1.5445 1.4072 2.7852 2.9785 2.7852 1.645 0 3-1.355 3-3 0-1.645-1.355-3-3-3-0.01533 0-0.029642 0.003706-0.044922 0.003906 0.084-0.10099 0.16695-0.21188 0.25195-0.29688 0.59286-0.59287 1.1094-0.75781 1.1094-0.75781 1.0726-0.33926 0.85487-1.9171-0.26953-1.9531zm-9.0605 0.005859c-1.0407 0.006928-2.0405 0.55674-2.584 1.498a1 1 0 0 0 0.36523 1.3672 1 1 0 0 0 1.3672 -0.36719c0.24596-0.42602 0.74477-0.6077 1.207-0.43945 0.46226 0.16824 0.728 0.62882 0.64258 1.1133-0.085422 0.48445-0.49245 0.82617-0.98438 0.82617a1 1 0 0 0 -1 1 1 1 0 0 0 1 1c0.49193 0 0.89896 0.34368 0.98438 0.82812 0.085422 0.48446-0.18032 0.94508-0.64258 1.1133-0.46226 0.1683-0.96107-0.015436-1.207-0.44141-0.27644-0.47871-0.88884-0.6423-1.3672-0.36523-0.47752 0.27639-0.64095 0.88733-0.36523 1.3652 0.72462 1.2553 2.2612 1.816 3.623 1.3203 1.3618-0.4956 2.1813-1.9126 1.9297-3.3398-0.1003-0.56884-0.37254-1.0676-0.74023-1.4746 0.37098-0.40777 0.63937-0.91234 0.74023-1.4844 0.25166-1.4272-0.56786-2.8442-1.9297-3.3398-0.34046-0.12392-0.69218-0.182-1.0391-0.17969zm-15.486 1.998c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm16 1c0.56413 0 1 0.43587 1 1s-0.43587 1-1 1-1-0.43587-1-1 0.43587-1 1-1zm-23.5 4c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm16.533 3.9883c-0.36561-0.0093-0.70715 0.18167-0.89062 0.49805l-3 5c-0.39877 0.66633 0.080888 1.5131 0.85742 1.5137h3v1c-0.01912 1.3523 2.0191 1.3523 2 0v-2c-5.5e-5 -0.55226-0.44774-0.99994-1-1h-2.2324l2.0898-3.4844c0.40768-0.65656-0.05163-1.5077-0.82422-1.5273zm6.9668 0.011719c-1.645 0-3 1.355-3 3 0 0.769 0.30369 1.4666 0.78711 2-0.48282 0.53332-0.78711 1.2315-0.78711 2 0 1.645 1.355 3 3 3s3-1.355 3-3c0-0.76846-0.30429-1.4667-0.78711-2 0.48342-0.53345 0.78711-1.231 0.78711-2 0-1.645-1.355-3-3-3zm0 2c0.56413 0 1 0.4359 1 1 0 0.5642-0.43587 1-1 1s-1-0.4358-1-1c0-0.5641 0.43587-1 1-1zm-23.5 1c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm16 1c0.56413 0 1 0.4359 1 1 0 0.5642-0.43587 1-1 1s-1-0.4358-1-1c0-0.5641 0.43587-1 1-1zm-23.5 4c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm16.447 3.9824c-0.08995 0.0063-0.17865 0.024647-0.26367 0.054687 0 0-0.98349 0.33509-1.8906 1.2422-0.90714 0.9068-1.793 2.457-1.793 4.707-6.13e-4 0.0722 0.006604 0.14421 0.021484 0.21484 0.11389 1.5445 1.4072 2.7852 2.9785 2.7852 1.645 0 3-1.355 3-3 0-1.6451-1.355-3-3-3-0.01533 0-0.029642 0.003706-0.044922 0.003906 0.084-0.10099 0.16695-0.21187 0.25195-0.29688 0.59286-0.5929 1.1094-0.75781 1.1094-0.75781 1.0726-0.33926 0.85487-1.9171-0.26953-1.9531-0.03318-0.0017-0.066429-0.0017-0.099609 0zm7.0527 0.017578c-1.6447 0-3 1.3553-3 3v3c0 1.6447 1.3553 3 3 3s3-1.3553 3-3v-3c0-1.6447-1.3553-3-3-3zm0 2c0.5713 0 1 0.4287 1 1v3c0 0.5713-0.4287 1-1 1s-1-0.4287-1-1v-3c0-0.5713 0.4287-1 1-1zm-23.5 1c-0.831 0-1.5 0.669-1.5 1.5 0 0.831 0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5 0-0.831-0.669-1.5-1.5-1.5h-2zm15.5 1.9863c0.56413 0 1 0.4358 1 1 0 0.5641-0.43587 1-1 1s-1-0.4359-1-1c0-0.5642 0.43587-1 1-1zm-8 0.013672v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5zm22.5 3.75c-1.5 0-3 1.3056-3 3.25-0.01912 1.3523 2.0191 1.3523 2 0 0-1.0555 0.5-1.25 1-1.25s1 0.1945 1 1.25c0 0.5916-0.35893 1.1561-1.1914 1.8633-0.83248 0.7072-2.0616 1.4518-3.3574 2.3008-0.82975 0.54515-0.44398 1.8356 0.54883 1.8359h5c1.3523 0.0191 1.3523-2.0191 0-2h-1.7852c0.28375-0.2066 0.63106-0.39438 0.88867-0.61328 1.0302-0.8751 1.8965-1.9782 1.8965-3.3867 0-1.9444-1.5-3.25-3-3.25zm-10 0.25c-1.3523-0.0191-1.3523 2.0191 0 2h3.3828l-3.2773 6.5527c-0.59596 1.1926 1.1931 2.0871 1.7891 0.89454l4-8c0.33239-0.66495-0.15113-1.4472-0.89453-1.4473h-5zm-12.5 3c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5h2c0.831 0 1.5-0.669 1.5-1.5s-0.669-1.5-1.5-1.5h-2zm7.5 2v2h3v-2h-3zm-7.5 5c-0.831 0-1.5 0.669-1.5 1.5s0.669 1.5 1.5 1.5 1.5-0.669 1.5-1.5-0.669-1.5-1.5-1.5z" fill="url(#a)"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_camera_texture.svg b/editor/icons/icon_camera_texture.svg
new file mode 100644
index 0000000000..5629487451
--- /dev/null
+++ b/editor/icons/icon_camera_texture.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0,1036.4)" d="m2 1c-0.55228 0-1 0.44772-1 1v12c0 0.55228 0.44772 1 1 1h12c0.55228 0 1-0.44772 1-1v-12c0-0.55228-0.44772-1-1-1h-12zm1 2h10v8h-10v-8zm5.8184 1.0039c-0.85534 9.758e-4 -1.5654 0.66069-1.6289 1.5137-0.30036-0.27229-0.69029-0.4234-1.0957-0.42383-0.90315 0-1.6367 0.73162-1.6367 1.6348 9.732e-4 0.69217 0.43922 1.3103 1.0918 1.541v1.1855c0 0.30198 0.24293 0.54492 0.54492 0.54492h3.2695c0.30199 0 0.54492-0.24294 0.54492-0.54492v-0.54492l1.6367 1.0898v-3.2715l-1.6367 1.0918v-0.96484c0.34606-0.30952 0.54406-0.75251 0.54492-1.2168 0-0.90315-0.73162-1.6348-1.6348-1.6348z" fill="#e0e0e0" fill-opacity=".99608"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_clipped_camera.svg b/editor/icons/icon_clipped_camera.svg
new file mode 100644
index 0000000000..dd26abc638
--- /dev/null
+++ b/editor/icons/icon_clipped_camera.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m6.5 12v4h3v-1h-2v-3zm-1 0h-2c-0.5 0-1 0.5-1 1v2c-0.01829 0.53653 0.5 1 1 1h2v-1h-2v-2h2zm4-12c-1.5691 0.0017903-2.8718 1.2125-2.9883 2.7773-0.55103-0.49952-1.268-0.77655-2.0117-0.77734-1.6569 0-3 1.3431-3 3 0.00179 1.2698 0.80282 2.4009 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695c0.63486-0.56783 0.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm1 12v4h1v-1h1c0.55228 0 1-0.44772 1-1v-1c0-0.55228-0.44775-0.99374-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/>
+</svg>
diff --git a/editor/icons/icon_debug_skip_breakpoints_off.svg b/editor/icons/icon_debug_skip_breakpoints_off.svg
new file mode 100644
index 0000000000..2a0b949aa9
--- /dev/null
+++ b/editor/icons/icon_debug_skip_breakpoints_off.svg
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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"
+ width="17"
+ height="17"
+ version="1.1"
+ viewBox="0 0 17 17"
+ id="svg3801"
+ sodipodi:docname="icon_debug_skip_breakpoints_off.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata3807">
+ <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="defs3805" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1887"
+ inkscape:window-height="2103"
+ id="namedview3803"
+ showgrid="false"
+ inkscape:measure-start="15.5563,28.7373"
+ inkscape:measure-end="0,0"
+ inkscape:zoom="32"
+ inkscape:cx="8.5156226"
+ inkscape:cy="-9.0970543"
+ inkscape:window-x="1953"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg3801" />
+ <path
+ id="path3835"
+ sodipodi:type="arc"
+ sodipodi:cx="3.2790968"
+ sodipodi:cy="3.006855"
+ sodipodi:rx="1.6192284"
+ sodipodi:ry="1.3289529"
+ sodipodi:start="0"
+ sodipodi:end="0.0073006075"
+ sodipodi:open="true"
+ d="m 4.8983252,3.006855 a 1.6192284,1.3289529 0 0 1 -4.31e-5,0.0097"
+ style="fill:#000000;stroke-width:0.62631863" />
+ <path
+ style="fill:#000000;stroke-width:0.62631863"
+ id="path3837"
+ sodipodi:type="arc"
+ sodipodi:cx="6.233613"
+ sodipodi:cy="5.0553513"
+ sodipodi:rx="2.563139"
+ sodipodi:ry="3.6270869"
+ sodipodi:start="0"
+ sodipodi:end="0.0073006075"
+ sodipodi:open="true"
+ d="m 8.796752,5.0553513 a 2.563139,3.6270869 0 0 1 -6.83e-5,0.02648" />
+ <path
+ style="fill:#ff8585;fill-opacity:0.99607843;stroke-width:1.01912296"
+ id="path3839"
+ sodipodi:type="arc"
+ sodipodi:cx="8.4689026"
+ sodipodi:cy="8.479969"
+ sodipodi:rx="6.1594577"
+ sodipodi:ry="6.0545759"
+ sodipodi:start="5.5685493"
+ sodipodi:end="5.2409356"
+ d="M 13.121337,4.512148 A 6.1594577,6.0545759 0 0 1 12.87255,12.713238 6.1594577,6.0545759 0 0 1 4.5370096,13.140453 6.1594577,6.0545759 0 0 1 3.4219038,5.0092664 6.1594577,6.0545759 0 0 1 11.574987,3.2515951"
+ sodipodi:open="true" />
+</svg>
diff --git a/editor/icons/icon_debug_skip_breakpoints_on.svg b/editor/icons/icon_debug_skip_breakpoints_on.svg
new file mode 100644
index 0000000000..186778a1b4
--- /dev/null
+++ b/editor/icons/icon_debug_skip_breakpoints_on.svg
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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"
+ width="17"
+ height="17"
+ version="1.1"
+ viewBox="0 0 17 17"
+ id="svg3801"
+ sodipodi:docname="icon_debug_skip_breakpoints_on.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata3807">
+ <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></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3805" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1887"
+ inkscape:window-height="2105"
+ id="namedview3803"
+ showgrid="false"
+ inkscape:measure-start="15.5563,28.7373"
+ inkscape:measure-end="0,0"
+ inkscape:zoom="40.96"
+ inkscape:cx="12.825686"
+ inkscape:cy="-5.1961973"
+ inkscape:window-x="1953"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="layer1" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer1"
+ inkscape:label="bg" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="fg">
+ <path
+ id="path3835"
+ sodipodi:type="arc"
+ sodipodi:cx="3.2790968"
+ sodipodi:cy="3.006855"
+ sodipodi:rx="1.6192284"
+ sodipodi:ry="1.3289529"
+ sodipodi:start="0"
+ sodipodi:end="0.0073006075"
+ sodipodi:open="true"
+ d="m 4.8983252,3.006855 a 1.6192284,1.3289529 0 0 1 -4.31e-5,0.0097"
+ style="fill:#000000;stroke-width:0.62631863" />
+ <path
+ style="fill:#000000;stroke-width:0.62631863"
+ id="path3837"
+ sodipodi:type="arc"
+ sodipodi:cx="6.233613"
+ sodipodi:cy="5.0553513"
+ sodipodi:rx="2.563139"
+ sodipodi:ry="3.6270869"
+ sodipodi:start="0"
+ sodipodi:end="0.0073006075"
+ sodipodi:open="true"
+ d="m 8.796752,5.0553513 a 2.563139,3.6270869 0 0 1 -6.83e-5,0.02648" />
+ <path
+ style="fill:#ff8585;fill-opacity:0.99607843;stroke-width:1.01912296"
+ id="path3839"
+ sodipodi:type="arc"
+ sodipodi:cx="8.4689026"
+ sodipodi:cy="8.479969"
+ sodipodi:rx="6.1594577"
+ sodipodi:ry="6.0545759"
+ sodipodi:start="5.5685493"
+ sodipodi:end="5.2409356"
+ d="M 13.121337,4.512148 A 6.1594577,6.0545759 0 0 1 12.87255,12.713238 6.1594577,6.0545759 0 0 1 4.5370096,13.140453 6.1594577,6.0545759 0 0 1 3.4219038,5.0092664 6.1594577,6.0545759 0 0 1 11.574987,3.2515951"
+ sodipodi:open="true" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke-width:1.1873318"
+ id="rect5375"
+ width="18.575495"
+ height="2.5187109"
+ x="-9.2906752"
+ y="10.816157"
+ transform="matrix(0.70605846,-0.70815355,0.70605846,0.70815355,0,0)" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_editor_curve_handle.svg b/editor/icons/icon_editor_curve_handle.svg
new file mode 100644
index 0000000000..c405ceab9d
--- /dev/null
+++ b/editor/icons/icon_editor_curve_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill="#fefefe" r="2.75" stroke="#000" stroke-linecap="square"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_editor_path_sharp_handle.svg b/editor/icons/icon_editor_path_sharp_handle.svg
new file mode 100644
index 0000000000..db160dfeae
--- /dev/null
+++ b/editor/icons/icon_editor_path_sharp_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m-3.035534-10.106602h6.071068v6.071068h-6.071068z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 0 0)"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_editor_path_smooth_handle.svg b/editor/icons/icon_editor_path_smooth_handle.svg
new file mode 100644
index 0000000000..34f3d290bd
--- /dev/null
+++ b/editor/icons/icon_editor_path_smooth_handle.svg
@@ -0,0 +1 @@
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m1.5-8.5h7v7h-7z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="rotate(90)"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_gizmo_c_p_u_particles.svg b/editor/icons/icon_gizmo_c_p_u_particles.svg
new file mode 100644
index 0000000000..a6f0eaef5b
--- /dev/null
+++ b/editor/icons/icon_gizmo_c_p_u_particles.svg
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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"
+ width="128"
+ height="128"
+ version="1.1"
+ viewBox="0 0 128 128"
+ id="svg6"
+ sodipodi:docname="icon_gizmo_c_p_u_particles.svg"
+ inkscape:version="0.92.4 5da689c313, 2019-01-14">
+ <metadata
+ id="metadata12">
+ <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></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1606"
+ inkscape:window-height="821"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="2.6074563"
+ inkscape:cx="101.29539"
+ inkscape:cy="83.191634"
+ inkscape:window-x="295"
+ inkscape:window-y="81"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <path
+ style="display:inline;opacity:1;fill:#f7f5cf;fill-opacity:1;stroke:#b4b4b4;stroke-width:2.56380486;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 35.503779,1.2819066 c -3.570424,0 -6.435164,2.9483368 -6.435164,6.6019028 v 4.3900146 c 0,0.889114 0.169457,1.726301 0.478513,2.49893 H 19.465369 c -3.570424,0 -6.435167,2.931453 -6.435167,6.585021 v 7.969562 c -0.341543,-0.0568 -0.648813,-0.202614 -1.006525,-0.202614 H 7.7335674 c -3.5704232,0 -6.451665,2.948338 -6.451665,6.601904 v 3.224972 c 0,3.653568 2.8812418,6.585016 6.451665,6.585016 h 4.2901096 c 0.358169,0 0.664563,-0.14568 1.006525,-0.202618 V 83.83104 C 12.688659,83.77398 12.381388,83.628424 12.023677,83.628424 H 7.7335674 c -3.5704232,0 -6.451665,2.948332 -6.451665,6.601908 v 3.224971 c 0,3.653575 2.8812418,6.585017 6.451665,6.585017 h 4.2901096 c 0.358169,0 0.664563,-0.145692 1.006525,-0.202612 v 9.725542 c 0,3.6536 2.864743,6.60193 6.435167,6.60193 h 9.603246 v 3.951 c 0,3.65357 2.86474,6.60192 6.435164,6.60192 h 3.15158 c 3.57042,0 6.451663,-2.94836 6.451663,-6.60192 v -3.95104 h 37.224955 v 3.951 c 0,3.65358 2.86474,6.60193 6.435166,6.60193 h 3.151583 c 3.570418,0 6.451653,-2.94836 6.451653,-6.60193 v -3.951 h 10.725281 c 3.57043,0 6.45166,-2.94833 6.45166,-6.60191 v -9.607372 c 0.14985,0.0105 0.27643,0.0846 0.42899,0.0846 h 4.29014 c 3.5704,0 6.45165,-2.931432 6.45165,-6.585011 v -3.224992 c 0,-3.653565 -2.88125,-6.601906 -6.45165,-6.601906 h -4.29014 c -0.15231,0 -0.27938,0.07348 -0.42899,0.08472 V 45.452198 c 0.14985,0.01042 0.27643,0.08445 0.42899,0.08445 h 4.29014 c 3.5704,0 6.45165,-2.931451 6.45165,-6.585023 v -3.224986 c 0,-3.653566 -2.88125,-6.601906 -6.45165,-6.601906 h -4.29014 c -0.15231,0 -0.27938,0.07392 -0.42899,0.08446 v -7.851429 c 0,-3.653567 -2.88123,-6.585019 -6.45166,-6.585021 H 97.875379 c 0.309043,-0.772641 0.494982,-1.609791 0.494982,-2.498929 V 7.8838054 c 0,-3.6535651 -2.881246,-6.601903 -6.451662,-6.601903 h -3.15158 c -3.570428,0 -6.435167,2.9483379 -6.435167,6.601903 V 12.27382 c 0,0.889115 0.16948,1.726301 0.478507,2.49893 H 44.612011 c 0.309083,-0.772642 0.495011,-1.609792 0.495011,-2.49893 V 7.8838054 c 0,-3.6535651 -2.881243,-6.601903 -6.451663,-6.601903 z"
+ id="path4542"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
+ d="M 62.861474,21.661698 A 27.707285,31.502779 0 0 1 90.004671,47.07312 18.471523,18.901669 0 0 1 105.96058,65.764449 18.471523,18.901669 0 0 1 87.480108,84.658396 H 38.226348 A 18.471523,18.901669 0 0 1 19.762375,65.764449 18.471523,18.901669 0 0 1 35.685283,47.056234 27.707285,31.502779 0 0 1 62.861474,21.661698 Z"
+ id="path4540"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
+ d="m 38.226348,90.956369 a 6.1571744,6.3005562 0 0 1 6.154657,6.297979 6.1571744,6.3005562 0 0 1 -6.154657,6.314882 6.1571744,6.3005562 0 0 1 -6.154657,-6.314882 6.1571744,6.3005562 0 0 1 6.154657,-6.297979 z"
+ id="path4538"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
+ d="m 87.480108,90.956369 a 6.1571744,6.3005562 0 0 1 6.171159,6.297979 6.1571744,6.3005562 0 0 1 -6.171159,6.314882 6.1571744,6.3005562 0 0 1 -6.154656,-6.314882 6.1571744,6.3005562 0 0 1 6.154656,-6.297979 z"
+ id="path4536"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
+ d="m 62.861474,97.254348 a 6.1571744,6.3005562 0 0 1 6.154662,6.314882 6.1571744,6.3005562 0 0 1 -6.154662,6.29797 6.1571744,6.3005562 0 0 1 -6.154651,-6.29797 6.1571744,6.3005562 0 0 1 6.154651,-6.314882 z"
+ id="rect822"
+ inkscape:connector-curvature="0" />
+ <g
+ inkscape:groupmode="layer"
+ id="layer1"
+ inkscape:label="Layer 1"
+ transform="translate(-0.35794507,-5.5049216)" />
+</svg>
diff --git a/editor/icons/icon_height_map_shape.svg b/editor/icons/icon_height_map_shape.svg
new file mode 100644
index 0000000000..09d129a273
--- /dev/null
+++ b/editor/icons/icon_height_map_shape.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+<linearGradient id="a" x1="8" x2="8" y1="8" y2="11" gradientUnits="userSpaceOnUse">
+<stop stop-color="#68b6ff" offset="0"/>
+<stop stop-color="#a2d2ff" offset="1"/>
+</linearGradient>
+</defs>
+<g transform="translate(0,-1)">
+<path transform="translate(0,-1033.4)" d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd"/>
+<path d="m3 11c1-1 2-2 2-4s1-3 3-3 3 1 3 3 1 3 2 4z" fill="url(#a)"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_interpolated_camera.svg b/editor/icons/icon_interpolated_camera.svg
index 7a33c64ca2..24b4832105 100644
--- a/editor/icons/icon_interpolated_camera.svg
+++ b/editor/icons/icon_interpolated_camera.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m9 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117 -0.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3zm-6 12v4h1v-4h-1zm3 0v4h1v-1h1a1 1 0 0 0 1 -1v-1a1 1 0 0 0 -1 -1h-1-1zm5 0a1 1 0 0 0 -1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1 -1v-2a1 1 0 0 0 -1 -1h-1zm-4 1h1v1h-1v-1zm4 0h1v2h-1v-2z" fill="#fc9c9c"/>
+<path transform="translate(0,1036.4)" d="m9.5 4e-5c-1.5691 0.0017903-2.8718 1.2125-2.9883 2.7773-0.55103-0.49952-1.268-0.77655-2.0117-0.77734-1.6569 0-3 1.3431-3 3 0.00179 1.2698 0.80282 2.4009 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 0.9853-0.4462 1-1v-1l3 2v-6l-3 2v-1.7695c0.63486-0.56783 0.99842-1.3788 1-2.2305 0-1.6569-1.3431-3-3-3zm-6 12v4h1v-4zm3 0v4h1v-1h1c0.55228 0 1-0.44772 1-1v-1c0-0.55228-0.44824-1.024-1-1h-1zm5 0c-0.55228 0-1 0.44772-1 1v2c0 0.55228 0.44772 1 1 1h1c0.55228 0 1-0.44772 1-1v-2c0-0.55228-0.44772-1-1-1zm-4 1h1v1h-1zm4 0h1v2h-1z" fill="#fc9c9c"/>
</g>
</svg>
diff --git a/editor/icons/icon_key_animation.svg b/editor/icons/icon_key_animation.svg
index a09567498f..6db513ca26 100644
--- a/editor/icons/icon_key_animation.svg
+++ b/editor/icons/icon_key_animation.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_animation.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <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="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1852"
- inkscape:window-height="781"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="-10.271186"
- inkscape:cy="3.4149032"
- inkscape:window-x="68"
- inkscape:window-y="117"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#b76ef0;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#b76ef0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_audio.svg b/editor/icons/icon_key_audio.svg
index 7c728bfd01..75576885ec 100644
--- a/editor/icons/icon_key_audio.svg
+++ b/editor/icons/icon_key_audio.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_audio.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <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></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1053"
- inkscape:window-height="591"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#eae668;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae668" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_bezier.svg b/editor/icons/icon_key_bezier.svg
index 62af6fdb34..dc5800fd5a 100644
--- a/editor/icons/icon_key_bezier.svg
+++ b/editor/icons/icon_key_bezier.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_bezier.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <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="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1852"
- inkscape:window-height="781"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="-17.152542"
- inkscape:cy="3.4149032"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#5792f6;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5792f6" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_call.svg b/editor/icons/icon_key_call.svg
index e702898288..6cc442c391 100644
--- a/editor/icons/icon_key_call.svg
+++ b/editor/icons/icon_key_call.svg
@@ -1,64 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_call.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="836"
- inkscape:window-height="480"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#adf18f"
- id="rect2"
- style="fill:#66f376;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#66f376" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_selected.svg b/editor/icons/icon_key_selected.svg
index 2842fd93eb..6594aec6ee 100644
--- a/editor/icons/icon_key_selected.svg
+++ b/editor/icons/icon_key_selected.svg
@@ -1,76 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_selected.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1568"
- inkscape:window-height="767"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="41.7193"
- inkscape:cx="-0.48848775"
- inkscape:cy="3.5639274"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4-3" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#84c2ff"
- id="rect2" />
- </g>
- <g
- transform="translate(0,-1044.4)"
- id="g4-3">
- <rect
- style="fill:#003e7a;fill-opacity:1;stroke-width:0.56281364"
- transform="matrix(0.71728847,-0.69677633,0.71728847,0.69677633,0,0)"
- x="-751.20953"
- y="753.42743"
- width="3.4346831"
- height="3.4346831"
- ry="0.42934799"
- id="rect2-6" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#84c2ff" height="6.1027" ry=".76286" transform="matrix(.87871827 -.87871827 .87871827 .87871827 .03288 -1297.7965)" width="6.1027" x="-741.53003" y="741.08002"/><rect fill="#003e7a" height="3.434683" ry=".429348" stroke-width=".562814" transform="matrix(.89137101 -.86588067 .89137101 .86588067 -.038545 -1297.8361)" width="3.434683" x="-751.20953" y="753.42743"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_value.svg b/editor/icons/icon_key_value.svg
index 61032a1e16..8a4787d6ed 100644
--- a/editor/icons/icon_key_value.svg
+++ b/editor/icons/icon_key_value.svg
@@ -1,5 +1 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#e0e0e0"/>
-</g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 1.002946 -1043.3636)" width="6.1027" x="-741.53003" y="741.08002"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_xform.svg b/editor/icons/icon_key_xform.svg
index fd22b67f52..4a567075a7 100644
--- a/editor/icons/icon_key_xform.svg
+++ b/editor/icons/icon_key_xform.svg
@@ -1,64 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_xform.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="836"
- inkscape:window-height="480"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#ea9568;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea9568" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_mesh_texture.svg b/editor/icons/icon_mesh_texture.svg
new file mode 100644
index 0000000000..a877877c36
--- /dev/null
+++ b/editor/icons/icon_mesh_texture.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h6.541c0.35663 0.61771 1.0152 0.99874 1.7285 1 1.1046 0 2-0.89543 2-2 1.01e-4 -0.72747-0.39481-1.3976-1.0312-1.75h0.03125v-6.5215c0.61771-0.35663 0.99874-1.0152 1-1.7285 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm1.7266 3h0.6875 5.168 0.68945c0.17478 0.30301 0.42598 0.55488 0.72852 0.73047v0.68359 5.1719 0.68555c-0.30301 0.17478-0.55488 0.42598-0.73047 0.72852h-0.68359-5.1719-0.68555c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-0.6875l-0.0039062 0.003907v-5.8574c0.30302-0.17478 0.55488-0.42598 0.73047-0.72852zm4.0859 2.25v0.70117h-0.8125v0.69922h-1.625v0.69922h-0.8125v0.69922h-0.8125v0.70117h1.625 1.625 1.625 1.625v-1.4004h-0.8125v-1.3984h-0.8125v-0.70117h-0.8125z" fill="#e0e0e0" fill-opacity=".99608"/>
+</svg>
diff --git a/editor/icons/icon_point_mesh.svg b/editor/icons/icon_point_mesh.svg
new file mode 100644
index 0000000000..8da7759daf
--- /dev/null
+++ b/editor/icons/icon_point_mesh.svg
@@ -0,0 +1,7 @@
+<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
+<g fill="#ffd684" stroke="#000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0" stroke-width="0">
+<ellipse cx="3.7237" cy="3.0268" rx="2.0114" ry="1.9956"/>
+<ellipse cx="11.717" cy="6.1734" rx="2.0114" ry="1.9956"/>
+<ellipse cx="6.5219" cy="12.477" rx="2.0114" ry="1.9956"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_reparent_to_new_node.svg b/editor/icons/icon_reparent_to_new_node.svg
new file mode 100644
index 0000000000..29db56279c
--- /dev/null
+++ b/editor/icons/icon_reparent_to_new_node.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg8"
+ sodipodi:docname="icon_reparent_to_new_node.svg"
+ inkscape:version="0.92.1 r15371">
+ <metadata
+ id="metadata14">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs12" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1023"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="29.5"
+ inkscape:cx="2.2588225"
+ inkscape:cy="3.6882199"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g6" />
+ <g
+ transform="translate(0 -1036.4)"
+ id="g6">
+ <path
+ transform="translate(0,1036.4)"
+ d="m 1.4915254,13 c 0,1.104569 0.8954305,2 2,2 0.7139771,-5.54e-4 1.3735116,-0.381677 1.7305,-1 H 11.2715 c 0.356631,0.617705 1.015238,0.998733 1.7285,1 1.104569,0 2,-0.895431 2,-2 0,-1.104569 -0.895431,-2 -2,-2 -0.713977,5.54e-4 -1.373512,0.381677 -1.7305,1 H 5.2200254 c -0.1747809,-0.30301 -0.8483719,-1 -1.7285,-1 -0.9027301,0 -2,0.891221 -2,2 z"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0"
+ sodipodi:nodetypes="cccccsccccc" />
+ <path
+ d="m 10.421845,1038.2814 -2.7947264,2.096 2.7947264,2.0961 v -1.3974 c 2.716918,0 2.180792,1.4469 2.180792,3.9265 V 1046.4 H 14 v -1.3974 c 0,-3.863 0.13086,-5.3239 -3.578155,-5.3239 z"
+ id="path4"
+ inkscape:connector-curvature="0"
+ style="fill:#84ffb1;stroke-width:0.69868171"
+ sodipodi:nodetypes="cccccccccc" />
+ <g
+ transform="translate(-8.5,-8)"
+ id="g6-7">
+ <path
+ style="fill:#84ffb1"
+ inkscape:connector-curvature="0"
+ transform="translate(0,1036.4)"
+ d="m 11,9 v 2 H 9 v 2 h 2 v 2 h 2 v -2 h 2 V 11 H 13 V 9 Z"
+ id="path4-5" />
+ </g>
+ <path
+ d="m 4.5,1047.7968 v -3.1171 H 2.4999995 v 3.1171 z"
+ id="path2-3"
+ inkscape:connector-curvature="0"
+ style="fill:#e0e0e0;stroke-width:0.7178387"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_rich_text_effect.svg b/editor/icons/icon_rich_text_effect.svg
new file mode 100644
index 0000000000..c2705ad8c4
--- /dev/null
+++ b/editor/icons/icon_rich_text_effect.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m1 1v2h7v-2zm9 0v2h5v-2zm-9 4v2h11v-2zm0 4v2h4v-2zm6 0v2h1c-0.044949-0.094701-0.088906-0.20229-0.125-0.3418-0.077717-0.30039-0.10439-0.81722 0.16406-1.293 0.081489-0.1441 0.18202-0.26127 0.28906-0.36523zm-6 4v2h8.2812c-0.066517-0.011548-0.1231-0.014758-0.20117-0.037109-0.30195-0.08645-0.76491-0.33245-1.0352-0.80664-0.23366-0.4121-0.24101-0.84933-0.18945-1.1562z" fill="#e0e0e0"/>
+<path d="m12.216 8.598a0.53334 3.2001 0 0 0-0.50976 2.2754 3.2001 0.53334 30 0 0-2.2656-0.71484 3.2001 0.53334 30 0 0 1.75 1.6016 0.53334 3.2001 60 0 0-1.7461 1.5996 0.53334 3.2001 60 0 0 2.2578-0.71094 0.53334 3.2001 0 0 0 0.51367 2.3496 0.53334 3.2001 0 0 0 0.51367-2.3516 3.2001 0.53334 30 0 0 2.2539 0.71094 3.2001 0.53334 30 0 0-1.7441-1.5977 0.53334 3.2001 60 0 0 1.748-1.5996 0.53334 3.2001 60 0 0-2.2617 0.71484 0.53334 3.2001 0 0 0-0.50977-2.2773z" fill="#cea4f1" stroke-width="1.0667"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_ruler.svg b/editor/icons/icon_ruler.svg
new file mode 100644
index 0000000000..a16eda000b
--- /dev/null
+++ b/editor/icons/icon_ruler.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -292.77)">
+<path transform="matrix(.26458 0 0 .26458 0 292.77)" d="m1 1v7.5 6.5h14l-14-14zm3 7 4 4h-4v-4z" fill="#e0e0e0"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_shrink_bottom_dock.svg b/editor/icons/icon_shrink_bottom_dock.svg
deleted file mode 100644
index c1e8c1bfdb..0000000000
--- a/editor/icons/icon_shrink_bottom_dock.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="16"
- height="16"
- version="1.1"
- viewBox="0 0 16 16"
- id="svg6"
- sodipodi:docname="icon_shrink_bottom_dock.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <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></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <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="namedview8"
- showgrid="false"
- inkscape:zoom="20.85965"
- inkscape:cx="9.4509357"
- inkscape:cy="6.016355"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg6" />
- <path
- style="fill:#e0e0e0"
- d="M 11.907447,9.9752038 15.442981,6.4396699 H 12.907296 V 1.4659528 h -1.999839 l 0,4.9737171 -2.5356852,0 3.5355342,3.5355339 z"
- id="path829"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccc" />
- <path
- inkscape:connector-curvature="0"
- id="path831"
- d="M 4.2131662,9.8793249 7.7487004,6.343791 H 5.2130152 V 1.3700738 H 3.2131762 V 6.343791 h -2.535685 l 3.535534,3.5355339 z"
- style="fill:#e0e0e0"
- sodipodi:nodetypes="ccccccccc" />
- <rect
- style="fill:#e0e0e0;fill-opacity:1"
- id="rect855"
- width="14"
- height="1.8305085"
- x="-14.832336"
- y="-13.121187"
- transform="scale(-1)" />
-</svg>
diff --git a/editor/icons/icon_skeleton_i_k.svg b/editor/icons/icon_skeleton_i_k.svg
new file mode 100644
index 0000000000..851023ab4d
--- /dev/null
+++ b/editor/icons/icon_skeleton_i_k.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m6 2a4 4 0 0 0-4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 0.26562v0.001953h4v-0.001953a2 2 0 0 0 1-0.26562 2 2 0 0 0 1-1.7324v-3.5469a4 4 0 0 0 2-3.4531 4 4 0 0 0-4-4h-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1zm-4 2h2v1h-2v-1zm-2 2h1v1h1v-1h1 1v1h1v-1h1v0.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-0.86914z" fill="#e0e0e0"/>
+</svg>
diff --git a/editor/icons/icon_soft_body.svg b/editor/icons/icon_soft_body.svg
index 9930026b61..2c907df847 100644
--- a/editor/icons/icon_soft_body.svg
+++ b/editor/icons/icon_soft_body.svg
@@ -1,56 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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"
- width="16"
- height="16"
- version="1.1"
- viewBox="0 0 16 16"
- id="svg2"
- inkscape:version="0.91 r13725"
- sodipodi:docname="icon_soft_body.svg">
- <metadata
- id="metadata14">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs12" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1027"
- id="namedview10"
- showgrid="false"
- inkscape:zoom="18.792233"
- inkscape:cx="2.8961304"
- inkscape:cy="4.3816933"
- inkscape:window-x="-8"
- inkscape:window-y="-8"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2" />
- <path
- style="opacity:1;fill:#fc9c9c;fill-opacity:0.99607843;fill-rule:nonzero;stroke:none;stroke-width:1.42799997;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="m 2.3447105,1.6091897 c -0.011911,1.9816766 -1.4168958,3.9344766 0,5.9495986 1.4168957,2.0151221 0,6.6693597 0,6.6693597 l 10.9510055,0 c 0,0 1.780829,-4.4523824 0,-6.489075 -1.780829,-2.0366925 -0.183458,-4.119112 0,-6.1298833 z m 1.8894067,0.7549031 7.4390658,0 c -0.431995,1.5996085 -1.62289,4.0426807 0,5.3749802 1.622888,1.3322996 0,5.887932 0,5.887932 l -7.4390658,0 c 0,0 1.3903413,-4.3680495 0,-5.9780743 -1.3903412,-1.6100247 -0.3951213,-3.7149271 0,-5.2848379 z"
- id="rect4142"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czcczcccczcczc" />
-</svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1s-3 5 0 7-1 7-1 7h13s3-6 0-8 1-6 1-6zm2 2h7s-2 3 1 5 0 5 0 5h-7s2-4-1-6 0-4 0-4z" fill="#fc9c9c" fill-opacity=".996078"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_spring_arm.svg b/editor/icons/icon_spring_arm.svg
new file mode 100644
index 0000000000..0700966369
--- /dev/null
+++ b/editor/icons/icon_spring_arm.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m8 14 6-6" fill="none" stroke="#fc9c9c" stroke-width="2"/>
+<path d="m2 2 7 7" fill="none" stroke="#fc9c9c" stroke-width="2"/>
+<path d="m10 9h-6" fill="none" stroke="#fc9c9c" stroke-width="2"/>
+<path d="m9 9v-5" fill="none" stroke="#fc9c9c" stroke-width="2"/>
+</svg>
diff --git a/editor/icons/icon_style_box_line.svg b/editor/icons/icon_style_box_line.svg
new file mode 100644
index 0000000000..28f2eec6c0
--- /dev/null
+++ b/editor/icons/icon_style_box_line.svg
@@ -0,0 +1,11 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m13.303 1c-0.4344 0-0.86973 0.16881-1.2012 0.50586l-1.4688 1.4941h4.3418c0.082839-0.52789-0.072596-1.0872-0.47266-1.4941-0.33144-0.33705-0.76482-0.50586-1.1992-0.50586z" fill="#ff7070"/>
+<path transform="translate(0 1036.4)" d="m10.633 3-1.9668 2h4.8008l1.0352-1.0527c0.2628-0.2673 0.41824-0.60049 0.47266-0.94727h-4.3418z" fill="#ffeb70"/>
+<path transform="translate(0,1036.4)" d="m8.666 5-1.9648 2h2.8809c0.25686-0.33847 0.49465-0.66934 0.68555-1 0.33885-0.5859 0.95098-0.96109 1.627-0.99609 0.44399-0.023642 0.86385 0.115 1.2188 0.35547l0.35352-0.35938h-4.8008z" fill="#9dff70"/>
+</g>
+<path d="m1.2617 13c-0.08284 0.52789 0.072596 1.0872 0.47266 1.4941 0.33144 0.33705 0.76484 0.50586 1.1992 0.50586 0.4344 0 0.8697-0.16881 1.2012-0.50586l1.4688-1.4941h-4.3418zm7.9219 0c0.41312 1.1628 1.5119 2 2.8164 2s2.4033-0.83718 2.8164-2h-5.6328z" fill="#ff70ac"/>
+<path d="m2.7695 11-1.0352 1.0527c-0.2628 0.2673-0.41824 0.60049-0.47266 0.94727h4.3418l1.4238-1.4473c0.020288-0.18998 0.04923-0.37542 0.089844-0.55273h-4.3477zm6.4609 0c-0.13656 0.32585-0.23047 0.65576-0.23047 1 0 0.35235 0.072014 0.68593 0.18359 1h5.6328c0.11158-0.31407 0.18359-0.64765 0.18359-1 0-0.34424-0.093909-0.67415-0.23047-1h-5.5391z" fill="#9f70ff"/>
+<path d="m4.7363 9-1.9668 2h4.3477c0.17955-0.78395 0.54577-1.4354 0.9375-2h-3.3184zm5.8281 0c-0.55248 0.69003-1.0583 1.3421-1.334 2h5.5391c-0.2757-0.65786-0.78149-1.31-1.334-2h-2.8711z" fill="#70deff"/>
+<path d="m6.7012 7-1.9648 2h3.3184c0.14116-0.20345 0.28508-0.40233 0.42383-0.58398 0.38601-0.5053 0.7635-0.96796 1.1035-1.416h-2.8809zm5.2988 0c-0.43047 0.7456-0.94456 1.3867-1.4355 2h2.8711c-0.49104-0.6133-1.0051-1.2544-1.4355-2z" fill="#70ffb9"/>
+</svg>
diff --git a/editor/icons/icon_timeline_indicator.svg b/editor/icons/icon_timeline_indicator.svg
new file mode 100644
index 0000000000..fd18192705
--- /dev/null
+++ b/editor/icons/icon_timeline_indicator.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 0h10l-4 4h-2z" fill="#fefefe"/></svg> \ No newline at end of file
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_import_collada.cpp b/editor/import/editor_import_collada.cpp
index e152827c63..adfdfee603 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -176,7 +176,6 @@ Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
Skeleton *sk = memnew(Skeleton);
int bone = 0;
- sk->set_use_bones_in_world_transform(true); // This improves compatibility in Collada
for (int i = 0; i < p_node->children.size(); i++) {
_populate_skeleton(sk, p_node->children[i], bone, -1);
@@ -692,16 +691,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
pre_weights[w_i] = weights;
- /*
- for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) {
-
- int dst = E->get();
- ERR_EXPLAIN("invalid vertex index in array");
- ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA);
- vertex_array[dst].weights=weights;
-
- }*/
-
index_ofs += wstride * amount;
}
@@ -711,7 +700,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
Set<Collada::Vertex> vertex_set; //vertex set will be the vertices
List<int> indices_list; //indices will be the indices
- //Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph)
/**************************/
/* CREATE PRIMITIVE ARRAY */
@@ -834,9 +822,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
vertex_set.insert(vertex);
}
- /* if (!vertex_map.has(vertex_index))
- vertex_map[vertex_index]=Set<int>();
- vertex_map[vertex_index].insert(index); //should be outside..*/
//build triangles if needed
if (j == 0)
prev2[0] = index;
@@ -1175,41 +1160,36 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
morph = &collada.state.morph_controller_data_map[ngsource];
meshid = morph->mesh;
- Vector<String> targets;
-
- morph->targets.has("MORPH_TARGET");
- String target = morph->targets["MORPH_TARGET"];
- bool valid = false;
- if (morph->sources.has(target)) {
- valid = true;
- Vector<String> names = morph->sources[target].sarray;
- for (int i = 0; i < names.size(); i++) {
-
- String meshid2 = names[i];
- if (collada.state.mesh_data_map.has(meshid2)) {
- Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
- const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
- mesh->set_name(meshdata.name);
- Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
- ERR_FAIL_COND_V(err, err);
-
- morphs.push_back(mesh);
- } else {
- valid = false;
+ if (morph->targets.has("MORPH_TARGET")) {
+ String target = morph->targets["MORPH_TARGET"];
+ bool valid = false;
+ if (morph->sources.has(target)) {
+ valid = true;
+ Vector<String> names = morph->sources[target].sarray;
+ for (int i = 0; i < names.size(); i++) {
+
+ String meshid2 = names[i];
+ if (collada.state.mesh_data_map.has(meshid2)) {
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
+ mesh->set_name(meshdata.name);
+ Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
+ ERR_FAIL_COND_V(err, err);
+
+ morphs.push_back(mesh);
+ } else {
+ valid = false;
+ }
}
}
- }
- if (!valid)
- morphs.clear();
-
- ngsource = "";
+ if (!valid)
+ morphs.clear();
+ ngsource = "";
+ }
}
- if (ngsource != "") {
- ERR_EXPLAIN("Controller Instance Source '" + ngsource + "' is neither skin or morph!");
- ERR_FAIL_V(ERR_INVALID_DATA);
- }
+ ERR_FAIL_COND_V_MSG(ngsource != "", ERR_INVALID_DATA, "Controller instance source '" + ngsource + "' is neither skin or morph!");
} else {
meshid = ng2->source;
@@ -1610,7 +1590,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
if (xform_idx == -1) {
- WARN_PRINTS("Collada: Couldn't find matching node " + at.target + " xform for track " + at.param);
+ WARN_PRINTS("Collada: Couldn't find matching node " + at.target + " xform for track " + at.param + ".");
continue;
}
@@ -1632,8 +1612,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
} else if (data.size() == xf.data.size()) {
xf.data = data;
} else {
- ERR_EXPLAIN("Component " + at.component + " has datasize " + itos(data.size()) + ", xfdatasize " + itos(xf.data.size()));
- ERR_CONTINUE(data.size() != xf.data.size());
+ ERR_CONTINUE_MSG(data.size() != xf.data.size(), "Component " + at.component + " has datasize " + itos(data.size()) + ", xfdatasize " + itos(xf.data.size()) + ".");
}
}
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index bc507e91b2..79658c5a4c 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -29,11 +29,14 @@
/*************************************************************************/
#include "editor_scene_importer_gltf.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/json.h"
-#include "core/math/crypto_core.h"
+#include "core/math/disjoint_set.h"
#include "core/math/math_defs.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
+#include "modules/regex/regex.h"
+#include "scene/3d/bone_attachment.h"
#include "scene/3d/camera.h"
#include "scene/3d/mesh_instance.h"
#include "scene/animation/animation_player.h"
@@ -152,14 +155,21 @@ static Transform _arr_to_xform(const Array &p_array) {
return xform;
}
+String EditorSceneImporterGLTF::_sanitize_scene_name(const String &name) {
+ RegEx regex("([^a-zA-Z0-9_ ]+)");
+ String p_name = regex.sub(name, "", true);
+ return p_name;
+}
+
String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String &p_name) {
- int index = 1;
+ const String s_name = _sanitize_scene_name(p_name);
String name;
+ int index = 1;
while (true) {
+ name = s_name;
- name = p_name;
if (index > 1) {
name += " " + itos(index);
}
@@ -174,20 +184,63 @@ String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String
return name;
}
+String EditorSceneImporterGLTF::_sanitize_bone_name(const String &name) {
+ String p_name = name.camelcase_to_underscore(true);
+
+ RegEx pattern_del("([^a-zA-Z0-9_ ])+");
+ p_name = pattern_del.sub(p_name, "", true);
+
+ RegEx pattern_nospace(" +");
+ p_name = pattern_nospace.sub(p_name, "_", true);
+
+ RegEx pattern_multiple("_+");
+ p_name = pattern_multiple.sub(p_name, "_", true);
+
+ RegEx pattern_padded("0+(\\d+)");
+ p_name = pattern_padded.sub(p_name, "$1", true);
+
+ return p_name;
+}
+
+String EditorSceneImporterGLTF::_gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name) {
+
+ const String s_name = _sanitize_bone_name(p_name);
+
+ String name;
+ int index = 1;
+ while (true) {
+ name = s_name;
+
+ if (index > 1) {
+ name += "_" + itos(index);
+ }
+ if (!state.skeletons[skel_i].unique_names.has(name)) {
+ break;
+ }
+ index++;
+ }
+
+ state.skeletons.write[skel_i].unique_names.insert(name);
+
+ return name;
+}
+
Error EditorSceneImporterGLTF::_parse_scenes(GLTFState &state) {
ERR_FAIL_COND_V(!state.json.has("scenes"), ERR_FILE_CORRUPT);
- Array scenes = state.json["scenes"];
+ const Array &scenes = state.json["scenes"];
for (int i = 0; i < 1; i++) { //only first scene is imported
- Dictionary s = scenes[i];
+ const Dictionary &s = scenes[i];
ERR_FAIL_COND_V(!s.has("nodes"), ERR_UNAVAILABLE);
- Array nodes = s["nodes"];
+ const Array &nodes = s["nodes"];
for (int j = 0; j < nodes.size(); j++) {
state.root_nodes.push_back(nodes[j]);
}
- if (s.has("name")) {
- state.scene_name = s["name"];
+ if (s.has("name") && s["name"] != "") {
+ state.scene_name = _gen_unique_name(state, s["name"]);
+ } else {
+ state.scene_name = _gen_unique_name(state, "Scene");
}
}
@@ -197,11 +250,11 @@ Error EditorSceneImporterGLTF::_parse_scenes(GLTFState &state) {
Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
ERR_FAIL_COND_V(!state.json.has("nodes"), ERR_FILE_CORRUPT);
- Array nodes = state.json["nodes"];
+ const Array &nodes = state.json["nodes"];
for (int i = 0; i < nodes.size(); i++) {
GLTFNode *node = memnew(GLTFNode);
- Dictionary n = nodes[i];
+ const Dictionary &n = nodes[i];
if (n.has("name")) {
node->name = n["name"];
@@ -214,13 +267,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
}
if (n.has("skin")) {
node->skin = n["skin"];
- /*
- if (!state.skin_users.has(node->skin)) {
- state.skin_users[node->skin] = Vector<int>();
- }
-
- state.skin_users[node->skin].push_back(i);
- */
}
if (n.has("matrix")) {
node->xform = _arr_to_xform(n["matrix"]);
@@ -242,7 +288,7 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
}
if (n.has("children")) {
- Array children = n["children"];
+ const Array &children = n["children"];
for (int j = 0; j < children.size(); j++) {
node->children.push_back(children[j]);
}
@@ -251,22 +297,46 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
state.nodes.push_back(node);
}
- //build the hierarchy
+ // build the hierarchy
+ for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); node_i++) {
- for (int i = 0; i < state.nodes.size(); i++) {
+ for (int j = 0; j < state.nodes[node_i]->children.size(); j++) {
+ GLTFNodeIndex child_i = state.nodes[node_i]->children[j];
- for (int j = 0; j < state.nodes[i]->children.size(); j++) {
- int child = state.nodes[i]->children[j];
- ERR_FAIL_INDEX_V(child, state.nodes.size(), ERR_FILE_CORRUPT);
- ERR_CONTINUE(state.nodes[child]->parent != -1); //node already has a parent, wtf.
+ ERR_FAIL_INDEX_V(child_i, state.nodes.size(), ERR_FILE_CORRUPT);
+ ERR_CONTINUE(state.nodes[child_i]->parent != -1); //node already has a parent, wtf.
- state.nodes[child]->parent = i;
+ state.nodes[child_i]->parent = node_i;
}
}
+ _compute_node_heights(state);
+
return OK;
}
+void EditorSceneImporterGLTF::_compute_node_heights(GLTFState &state) {
+
+ state.root_nodes.clear();
+ for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); ++node_i) {
+ GLTFNode *node = state.nodes[node_i];
+ node->height = 0;
+
+ GLTFNodeIndex current_i = node_i;
+ while (current_i >= 0) {
+ const GLTFNodeIndex parent_i = state.nodes[current_i]->parent;
+ if (parent_i >= 0) {
+ ++node->height;
+ }
+ current_i = parent_i;
+ }
+
+ if (node->height == 0) {
+ state.root_nodes.push_back(node_i);
+ }
+ }
+}
+
static Vector<uint8_t> _parse_base64_uri(const String &uri) {
int start = uri.find(",");
@@ -292,14 +362,14 @@ Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_
if (!state.json.has("buffers"))
return OK;
- Array buffers = state.json["buffers"];
- for (int i = 0; i < buffers.size(); i++) {
+ const Array &buffers = state.json["buffers"];
+ for (GLTFBufferIndex i = 0; i < buffers.size(); i++) {
if (i == 0 && state.glb_data.size()) {
state.buffers.push_back(state.glb_data);
} else {
- Dictionary buffer = buffers[i];
+ const Dictionary &buffer = buffers[i];
if (buffer.has("uri")) {
Vector<uint8_t> buffer_data;
@@ -331,10 +401,10 @@ Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_
Error EditorSceneImporterGLTF::_parse_buffer_views(GLTFState &state) {
ERR_FAIL_COND_V(!state.json.has("bufferViews"), ERR_FILE_CORRUPT);
- Array buffers = state.json["bufferViews"];
- for (int i = 0; i < buffers.size(); i++) {
+ const Array &buffers = state.json["bufferViews"];
+ for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
- Dictionary d = buffers[i];
+ const Dictionary &d = buffers[i];
GLTFBufferView buffer_view;
@@ -352,7 +422,7 @@ Error EditorSceneImporterGLTF::_parse_buffer_views(GLTFState &state) {
}
if (d.has("target")) {
- int target = d["target"];
+ const int target = d["target"];
buffer_view.indices = target == ELEMENT_ARRAY_BUFFER;
}
@@ -389,10 +459,10 @@ EditorSceneImporterGLTF::GLTFType EditorSceneImporterGLTF::_get_type_from_str(co
Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
ERR_FAIL_COND_V(!state.json.has("accessors"), ERR_FILE_CORRUPT);
- Array accessors = state.json["accessors"];
- for (int i = 0; i < accessors.size(); i++) {
+ const Array &accessors = state.json["accessors"];
+ for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
- Dictionary d = accessors[i];
+ const Dictionary &d = accessors[i];
GLTFAccessor accessor;
@@ -422,12 +492,12 @@ Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
if (d.has("sparse")) {
//eeh..
- Dictionary s = d["sparse"];
+ const Dictionary &s = d["sparse"];
ERR_FAIL_COND_V(!d.has("count"), ERR_PARSE_ERROR);
accessor.sparse_count = d["count"];
ERR_FAIL_COND_V(!d.has("indices"), ERR_PARSE_ERROR);
- Dictionary si = d["indices"];
+ const Dictionary &si = d["indices"];
ERR_FAIL_COND_V(!si.has("bufferView"), ERR_PARSE_ERROR);
accessor.sparse_indices_buffer_view = si["bufferView"];
@@ -439,7 +509,7 @@ Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
}
ERR_FAIL_COND_V(!d.has("values"), ERR_PARSE_ERROR);
- Dictionary sv = d["values"];
+ const Dictionary &sv = d["values"];
ERR_FAIL_COND_V(!sv.has("bufferView"), ERR_PARSE_ERROR);
accessor.sparse_values_buffer_view = sv["bufferView"];
@@ -456,7 +526,7 @@ Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
return OK;
}
-String EditorSceneImporterGLTF::_get_component_type_name(uint32_t p_component) {
+String EditorSceneImporterGLTF::_get_component_type_name(const uint32_t p_component) {
switch (p_component) {
case COMPONENT_TYPE_BYTE: return "Byte";
@@ -470,7 +540,7 @@ String EditorSceneImporterGLTF::_get_component_type_name(uint32_t p_component) {
return "<Error>";
}
-String EditorSceneImporterGLTF::_get_type_name(GLTFType p_component) {
+String EditorSceneImporterGLTF::_get_type_name(const GLTFType p_component) {
static const char *names[] = {
"float",
@@ -485,7 +555,7 @@ String EditorSceneImporterGLTF::_get_type_name(GLTFType p_component) {
return names[p_component];
}
-Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, int p_buffer_view, double *dst, int skip_every, int skip_bytes, int element_size, int count, GLTFType type, int component_count, int component_type, int component_size, bool normalized, int byte_offset, bool for_vertex) {
+Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, double *dst, const GLTFBufferViewIndex p_buffer_view, const int skip_every, const int skip_bytes, const int element_size, const int count, const GLTFType type, const int component_count, const int component_type, const int component_size, const bool normalized, const int byte_offset, const bool for_vertex) {
const GLTFBufferView &bv = state.buffer_views[p_buffer_view];
@@ -496,7 +566,7 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, int p_buffe
ERR_FAIL_INDEX_V(bv.buffer, state.buffers.size(), ERR_PARSE_ERROR);
- uint32_t offset = bv.byte_offset + byte_offset;
+ const uint32_t offset = bv.byte_offset + byte_offset;
Vector<uint8_t> buffer = state.buffers[bv.buffer]; //copy on write, so no performance hit
const uint8_t *bufptr = buffer.ptr();
@@ -504,7 +574,7 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, int p_buffe
print_verbose("glTF: type " + _get_type_name(type) + " component type: " + _get_component_type_name(component_type) + " stride: " + itos(stride) + " amount " + itos(count));
print_verbose("glTF: accessor offset" + itos(byte_offset) + " view offset: " + itos(bv.byte_offset) + " total buffer len: " + itos(buffer.size()) + " view len " + itos(bv.byte_length));
- int buffer_end = (stride * (count - 1)) + element_size;
+ const int buffer_end = (stride * (count - 1)) + element_size;
ERR_FAIL_COND_V(buffer_end > bv.byte_length, ERR_PARSE_ERROR);
ERR_FAIL_COND_V((int)(offset + buffer_end) > buffer.size(), ERR_PARSE_ERROR);
@@ -573,7 +643,7 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, int p_buffe
return OK;
}
-int EditorSceneImporterGLTF::_get_component_type_size(int component_type) {
+int EditorSceneImporterGLTF::_get_component_type_size(const int component_type) {
switch (component_type) {
case COMPONENT_TYPE_BYTE: return 1; break;
@@ -589,7 +659,7 @@ int EditorSceneImporterGLTF::_get_component_type_size(int component_type) {
return 0;
}
-Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p_accessor, bool p_for_vertex) {
+Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
//spec, for reference:
//https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -598,12 +668,12 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
const GLTFAccessor &a = state.accessors[p_accessor];
- int component_count_for_type[7] = {
+ const int component_count_for_type[7] = {
1, 2, 3, 4, 4, 9, 16
};
- int component_count = component_count_for_type[a.type];
- int component_size = _get_component_type_size(a.component_type);
+ const int component_count = component_count_for_type[a.type];
+ const int component_size = _get_component_type_size(a.component_type);
ERR_FAIL_COND_V(component_size == 0, Vector<double>());
int element_size = component_count * component_size;
@@ -646,7 +716,7 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
ERR_FAIL_INDEX_V(a.buffer_view, state.buffer_views.size(), Vector<double>());
- Error err = _decode_buffer_view(state, a.buffer_view, dst, skip_every, skip_bytes, element_size, a.count, a.type, component_count, a.component_type, component_size, a.normalized, a.byte_offset, p_for_vertex);
+ const Error err = _decode_buffer_view(state, dst, a.buffer_view, skip_every, skip_bytes, element_size, a.count, a.type, component_count, a.component_type, component_size, a.normalized, a.byte_offset, p_for_vertex);
if (err != OK)
return Vector<double>();
@@ -661,20 +731,20 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
// I could not find any file using this, so this code is so far untested
Vector<double> indices;
indices.resize(a.sparse_count);
- int indices_component_size = _get_component_type_size(a.sparse_indices_component_type);
+ const int indices_component_size = _get_component_type_size(a.sparse_indices_component_type);
- Error err = _decode_buffer_view(state, a.sparse_indices_buffer_view, indices.ptrw(), 0, 0, indices_component_size, a.sparse_count, TYPE_SCALAR, 1, a.sparse_indices_component_type, indices_component_size, false, a.sparse_indices_byte_offset, false);
+ Error err = _decode_buffer_view(state, indices.ptrw(), a.sparse_indices_buffer_view, 0, 0, indices_component_size, a.sparse_count, TYPE_SCALAR, 1, a.sparse_indices_component_type, indices_component_size, false, a.sparse_indices_byte_offset, false);
if (err != OK)
return Vector<double>();
Vector<double> data;
data.resize(component_count * a.sparse_count);
- err = _decode_buffer_view(state, a.sparse_values_buffer_view, data.ptrw(), skip_every, skip_bytes, element_size, a.sparse_count, a.type, component_count, a.component_type, component_size, a.normalized, a.sparse_values_byte_offset, p_for_vertex);
+ err = _decode_buffer_view(state, data.ptrw(), a.sparse_values_buffer_view, skip_every, skip_bytes, element_size, a.sparse_count, a.type, component_count, a.component_type, component_size, a.normalized, a.sparse_values_byte_offset, p_for_vertex);
if (err != OK)
return Vector<double>();
for (int i = 0; i < indices.size(); i++) {
- int write_offset = int(indices[i]) * component_count;
+ const int write_offset = int(indices[i]) * component_count;
for (int j = 0; j < component_count; j++) {
dst[write_offset + j] = data[i * component_count + j];
@@ -685,14 +755,16 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, int p
return dst_buffer;
}
-PoolVector<int> EditorSceneImporterGLTF::_decode_accessor_as_ints(GLTFState &state, int p_accessor, bool p_for_vertex) {
+PoolVector<int> EditorSceneImporterGLTF::_decode_accessor_as_ints(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
PoolVector<int> ret;
+
if (attribs.size() == 0)
return ret;
+
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size();
+ const int ret_size = attribs.size();
ret.resize(ret_size);
{
PoolVector<int>::Write w = ret.write();
@@ -703,14 +775,16 @@ PoolVector<int> EditorSceneImporterGLTF::_decode_accessor_as_ints(GLTFState &sta
return ret;
}
-PoolVector<float> EditorSceneImporterGLTF::_decode_accessor_as_floats(GLTFState &state, int p_accessor, bool p_for_vertex) {
+PoolVector<float> EditorSceneImporterGLTF::_decode_accessor_as_floats(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
PoolVector<float> ret;
+
if (attribs.size() == 0)
return ret;
+
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size();
+ const int ret_size = attribs.size();
ret.resize(ret_size);
{
PoolVector<float>::Write w = ret.write();
@@ -721,15 +795,17 @@ PoolVector<float> EditorSceneImporterGLTF::_decode_accessor_as_floats(GLTFState
return ret;
}
-PoolVector<Vector2> EditorSceneImporterGLTF::_decode_accessor_as_vec2(GLTFState &state, int p_accessor, bool p_for_vertex) {
+PoolVector<Vector2> EditorSceneImporterGLTF::_decode_accessor_as_vec2(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
PoolVector<Vector2> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret);
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size() / 2;
+ const int ret_size = attribs.size() / 2;
ret.resize(ret_size);
{
PoolVector<Vector2>::Write w = ret.write();
@@ -740,15 +816,17 @@ PoolVector<Vector2> EditorSceneImporterGLTF::_decode_accessor_as_vec2(GLTFState
return ret;
}
-PoolVector<Vector3> EditorSceneImporterGLTF::_decode_accessor_as_vec3(GLTFState &state, int p_accessor, bool p_for_vertex) {
+PoolVector<Vector3> EditorSceneImporterGLTF::_decode_accessor_as_vec3(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
PoolVector<Vector3> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret);
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size() / 3;
+ const int ret_size = attribs.size() / 3;
ret.resize(ret_size);
{
PoolVector<Vector3>::Write w = ret.write();
@@ -758,13 +836,16 @@ PoolVector<Vector3> EditorSceneImporterGLTF::_decode_accessor_as_vec3(GLTFState
}
return ret;
}
-PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &state, int p_accessor, bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
+
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
PoolVector<Color> ret;
+
if (attribs.size() == 0)
return ret;
- int type = state.accessors[p_accessor].type;
+
+ const int type = state.accessors[p_accessor].type;
ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret);
int components;
if (type == TYPE_VEC3) {
@@ -772,9 +853,10 @@ PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &
} else { // TYPE_VEC4
components = 4;
}
+
ERR_FAIL_COND_V(attribs.size() % components != 0, ret);
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size() / components;
+ const int ret_size = attribs.size() / components;
ret.resize(ret_size);
{
PoolVector<Color>::Write w = ret.write();
@@ -784,15 +866,17 @@ PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &
}
return ret;
}
-Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state, int p_accessor, bool p_for_vertex) {
+Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Quat> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
const double *attribs_ptr = attribs.ptr();
- int ret_size = attribs.size() / 4;
+ const int ret_size = attribs.size() / 4;
ret.resize(ret_size);
{
for (int i = 0; i < ret_size; i++) {
@@ -801,12 +885,14 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
}
return ret;
}
-Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFState &state, int p_accessor, bool p_for_vertex) {
+Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform2D> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
ret.resize(attribs.size() / 4);
for (int i = 0; i < ret.size(); i++) {
@@ -816,12 +902,14 @@ Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFSta
return ret;
}
-Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex) {
+Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &state, const GLTFAccessorIndex p_accessor, bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Basis> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
ret.resize(attribs.size() / 9);
for (int i = 0; i < ret.size(); i++) {
@@ -831,12 +919,15 @@ Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &stat
}
return ret;
}
-Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex) {
- Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
+Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
+
+ const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform> ret;
+
if (attribs.size() == 0)
return ret;
+
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
ret.resize(attribs.size() / 16);
for (int i = 0; i < ret.size(); i++) {
@@ -854,7 +945,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
return OK;
Array meshes = state.json["meshes"];
- for (int i = 0; i < meshes.size(); i++) {
+ for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
print_verbose("glTF: Parsing mesh: " + itos(i));
Dictionary d = meshes[i];
@@ -865,7 +956,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR);
Array primitives = d["primitives"];
- Dictionary extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
+ const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
for (int j = 0; j < primitives.size(); j++) {
@@ -880,7 +971,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
if (p.has("mode")) {
- int mode = p["mode"];
+ const int mode = p["mode"];
ERR_FAIL_INDEX_V(mode, 7, ERR_FILE_CORRUPT);
static const Mesh::PrimitiveType primitives2[7] = {
Mesh::PRIMITIVE_POINTS,
@@ -899,7 +990,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
if (a.has("POSITION")) {
array[Mesh::ARRAY_VERTEX] = _decode_accessor_as_vec3(state, a["POSITION"], true);
}
-
if (a.has("NORMAL")) {
array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(state, a["NORMAL"], true);
}
@@ -924,9 +1014,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
int wc = weights.size();
PoolVector<float>::Write w = weights.write();
- //PoolVector<int> v = array[Mesh::ARRAY_BONES];
- //PoolVector<int>::Read r = v.read();
-
for (int k = 0; k < wc; k += 4) {
float total = 0.0;
total += w[k + 0];
@@ -939,36 +1026,34 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
w[k + 2] /= total;
w[k + 3] /= total;
}
-
- //print_verbose(itos(j / 4) + ": " + itos(r[j + 0]) + ":" + rtos(w[j + 0]) + ", " + itos(r[j + 1]) + ":" + rtos(w[j + 1]) + ", " + itos(r[j + 2]) + ":" + rtos(w[j + 2]) + ", " + itos(r[j + 3]) + ":" + rtos(w[j + 3]));
}
}
array[Mesh::ARRAY_WEIGHTS] = weights;
}
if (p.has("indices")) {
-
PoolVector<int> indices = _decode_accessor_as_ints(state, p["indices"], false);
if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
//swap around indices, convert ccw to cw for front face
- int is = indices.size();
- PoolVector<int>::Write w = indices.write();
+ const int is = indices.size();
+ const PoolVector<int>::Write w = indices.write();
for (int k = 0; k < is; k += 3) {
SWAP(w[k + 1], w[k + 2]);
}
}
array[Mesh::ARRAY_INDEX] = indices;
+
} else if (primitive == Mesh::PRIMITIVE_TRIANGLES) {
//generate indices because they need to be swapped for CW/CCW
- PoolVector<Vector3> vertices = array[Mesh::ARRAY_VERTEX];
+ const PoolVector<Vector3> &vertices = array[Mesh::ARRAY_VERTEX];
ERR_FAIL_COND_V(vertices.size() == 0, ERR_PARSE_ERROR);
PoolVector<int> indices;
- int vs = vertices.size();
+ const int vs = vertices.size();
indices.resize(vs);
{
- PoolVector<int>::Write w = indices.write();
+ const PoolVector<int>::Write w = indices.write();
for (int k = 0; k < vs; k += 3) {
w[k] = k;
w[k + 1] = k + 2;
@@ -986,7 +1071,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
Ref<SurfaceTool> st;
st.instance();
st->create_from_triangle_arrays(array);
- if (p.has("targets")) {
+ if (!p.has("targets")) {
//morph targets should not be reindexed, as array size might differ
//removing indices is the best bet here
st->deindex();
@@ -1002,23 +1087,23 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
//blend shapes
if (p.has("targets")) {
print_verbose("glTF: Mesh has targets");
- Array targets = p["targets"];
+ const Array &targets = p["targets"];
//ideally BLEND_SHAPE_MODE_RELATIVE since gltf2 stores in displacement
//but it could require a larger refactor?
mesh.mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
if (j == 0) {
- Array target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array();
+ const Array &target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array();
for (int k = 0; k < targets.size(); k++) {
- String name = k < target_names.size() ? (String)target_names[k] : String("morph_") + itos(k);
+ const String name = k < target_names.size() ? (String)target_names[k] : String("morph_") + itos(k);
mesh.mesh->add_blend_shape(name);
}
}
for (int k = 0; k < targets.size(); k++) {
- Dictionary t = targets[k];
+ const Dictionary &t = targets[k];
Array array_copy;
array_copy.resize(Mesh::ARRAY_MAX);
@@ -1031,17 +1116,17 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
if (t.has("POSITION")) {
PoolVector<Vector3> varr = _decode_accessor_as_vec3(state, t["POSITION"], true);
- PoolVector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
- int size = src_varr.size();
+ const PoolVector<Vector3> src_varr = array[Mesh::ARRAY_VERTEX];
+ const int size = src_varr.size();
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
{
- int max_idx = varr.size();
+ const int max_idx = varr.size();
varr.resize(size);
- PoolVector<Vector3>::Write w_varr = varr.write();
- PoolVector<Vector3>::Read r_varr = varr.read();
- PoolVector<Vector3>::Read r_src_varr = src_varr.read();
+ const PoolVector<Vector3>::Write w_varr = varr.write();
+ const PoolVector<Vector3>::Read r_varr = varr.read();
+ const PoolVector<Vector3>::Read r_src_varr = src_varr.read();
for (int l = 0; l < size; l++) {
if (l < max_idx) {
w_varr[l] = r_varr[l] + r_src_varr[l];
@@ -1054,16 +1139,16 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
}
if (t.has("NORMAL")) {
PoolVector<Vector3> narr = _decode_accessor_as_vec3(state, t["NORMAL"], true);
- PoolVector<Vector3> src_narr = array[Mesh::ARRAY_NORMAL];
+ const PoolVector<Vector3> src_narr = array[Mesh::ARRAY_NORMAL];
int size = src_narr.size();
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
{
int max_idx = narr.size();
narr.resize(size);
- PoolVector<Vector3>::Write w_narr = narr.write();
- PoolVector<Vector3>::Read r_narr = narr.read();
- PoolVector<Vector3>::Read r_src_narr = src_narr.read();
+ const PoolVector<Vector3>::Write w_narr = narr.write();
+ const PoolVector<Vector3>::Read r_narr = narr.read();
+ const PoolVector<Vector3>::Read r_src_narr = src_narr.read();
for (int l = 0; l < size; l++) {
if (l < max_idx) {
w_narr[l] = r_narr[l] + r_src_narr[l];
@@ -1075,21 +1160,22 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
array_copy[Mesh::ARRAY_NORMAL] = narr;
}
if (t.has("TANGENT")) {
- PoolVector<Vector3> tangents_v3 = _decode_accessor_as_vec3(state, t["TANGENT"], true);
- PoolVector<float> tangents_v4;
- PoolVector<float> src_tangents = array[Mesh::ARRAY_TANGENT];
+ const PoolVector<Vector3> tangents_v3 = _decode_accessor_as_vec3(state, t["TANGENT"], true);
+ const PoolVector<float> src_tangents = array[Mesh::ARRAY_TANGENT];
ERR_FAIL_COND_V(src_tangents.size() == 0, ERR_PARSE_ERROR);
+ PoolVector<float> tangents_v4;
+
{
int max_idx = tangents_v3.size();
int size4 = src_tangents.size();
tangents_v4.resize(size4);
- PoolVector<float>::Write w4 = tangents_v4.write();
+ const PoolVector<float>::Write w4 = tangents_v4.write();
- PoolVector<Vector3>::Read r3 = tangents_v3.read();
- PoolVector<float>::Read r4 = src_tangents.read();
+ const PoolVector<Vector3>::Read r3 = tangents_v3.read();
+ const PoolVector<float>::Read r4 = src_tangents.read();
for (int l = 0; l < size4 / 4; l++) {
@@ -1127,16 +1213,16 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
mesh.mesh->add_surface_from_arrays(primitive, array, morphs);
if (p.has("material")) {
- int material = p["material"];
+ const int material = p["material"];
ERR_FAIL_INDEX_V(material, state.materials.size(), ERR_FILE_CORRUPT);
- Ref<Material> mat = state.materials[material];
+ const Ref<Material> &mat = state.materials[material];
mesh.mesh->surface_set_material(mesh.mesh->get_surface_count() - 1, mat);
}
}
if (d.has("weights")) {
- Array weights = d["weights"];
+ const Array &weights = d["weights"];
ERR_FAIL_COND_V(mesh.mesh->get_blend_shape_count() != weights.size(), ERR_PARSE_ERROR);
mesh.blend_weights.resize(weights.size());
for (int j = 0; j < weights.size(); j++) {
@@ -1157,10 +1243,10 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
if (!state.json.has("images"))
return OK;
- Array images = state.json["images"];
+ const Array &images = state.json["images"];
for (int i = 0; i < images.size(); i++) {
- Dictionary d = images[i];
+ const Dictionary &d = images[i];
String mimetype;
if (d.has("mimeType")) {
@@ -1190,13 +1276,13 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
}
if (d.has("bufferView")) {
- int bvi = d["bufferView"];
+ const GLTFBufferViewIndex bvi = d["bufferView"];
ERR_FAIL_INDEX_V(bvi, state.buffer_views.size(), ERR_PARAMETER_RANGE_ERROR);
const GLTFBufferView &bv = state.buffer_views[bvi];
- int bi = bv.buffer;
+ const GLTFBufferIndex bi = bv.buffer;
ERR_FAIL_INDEX_V(bi, state.buffers.size(), ERR_PARAMETER_RANGE_ERROR);
ERR_FAIL_COND_V(bv.byte_offset + bv.byte_length > state.buffers[bi].size(), ERR_FILE_CORRUPT);
@@ -1209,7 +1295,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
if (mimetype.findn("png") != -1) {
//is a png
- Ref<Image> img = Image::_png_mem_loader_func(data_ptr, data_size);
+ const Ref<Image> img = Image::_png_mem_loader_func(data_ptr, data_size);
ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT);
@@ -1223,7 +1309,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
if (mimetype.findn("jpeg") != -1) {
//is a jpg
- Ref<Image> img = Image::_jpg_mem_loader_func(data_ptr, data_size);
+ const Ref<Image> img = Image::_jpg_mem_loader_func(data_ptr, data_size);
ERR_FAIL_COND_V(img.is_null(), ERR_FILE_CORRUPT);
@@ -1249,10 +1335,10 @@ Error EditorSceneImporterGLTF::_parse_textures(GLTFState &state) {
if (!state.json.has("textures"))
return OK;
- Array textures = state.json["textures"];
- for (int i = 0; i < textures.size(); i++) {
+ const Array &textures = state.json["textures"];
+ for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
- Dictionary d = textures[i];
+ const Dictionary &d = textures[i];
ERR_FAIL_COND_V(!d.has("source"), ERR_PARSE_ERROR);
@@ -1264,9 +1350,9 @@ Error EditorSceneImporterGLTF::_parse_textures(GLTFState &state) {
return OK;
}
-Ref<Texture> EditorSceneImporterGLTF::_get_texture(GLTFState &state, int p_texture) {
+Ref<Texture> EditorSceneImporterGLTF::_get_texture(GLTFState &state, const GLTFTextureIndex p_texture) {
ERR_FAIL_INDEX_V(p_texture, state.textures.size(), Ref<Texture>());
- int image = state.textures[p_texture].src_image;
+ const GLTFImageIndex image = state.textures[p_texture].src_image;
ERR_FAIL_INDEX_V(image, state.images.size(), Ref<Texture>());
@@ -1278,10 +1364,10 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
if (!state.json.has("materials"))
return OK;
- Array materials = state.json["materials"];
- for (int i = 0; i < materials.size(); i++) {
+ const Array &materials = state.json["materials"];
+ for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
- Dictionary d = materials[i];
+ const Dictionary &d = materials[i];
Ref<SpatialMaterial> material;
material.instance();
@@ -1291,17 +1377,17 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
if (d.has("pbrMetallicRoughness")) {
- Dictionary mr = d["pbrMetallicRoughness"];
+ const Dictionary &mr = d["pbrMetallicRoughness"];
if (mr.has("baseColorFactor")) {
- Array arr = mr["baseColorFactor"];
+ const Array &arr = mr["baseColorFactor"];
ERR_FAIL_COND_V(arr.size() != 4, ERR_PARSE_ERROR);
- Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2], arr[3]).to_srgb();
material->set_albedo(c);
}
if (mr.has("baseColorTexture")) {
- Dictionary bct = mr["baseColorTexture"];
+ const Dictionary &bct = mr["baseColorTexture"];
if (bct.has("index")) {
material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, _get_texture(state, bct["index"]));
}
@@ -1323,11 +1409,13 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
}
if (mr.has("metallicRoughnessTexture")) {
- Dictionary bct = mr["metallicRoughnessTexture"];
+ const Dictionary &bct = mr["metallicRoughnessTexture"];
if (bct.has("index")) {
- Ref<Texture> t = _get_texture(state, bct["index"]);
+ const Ref<Texture> t = _get_texture(state, bct["index"]);
material->set_texture(SpatialMaterial::TEXTURE_METALLIC, t);
+ material->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_BLUE);
material->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, t);
+ material->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GREEN);
if (!mr.has("metallicFactor")) {
material->set_metallic(1);
}
@@ -1339,7 +1427,7 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
}
if (d.has("normalTexture")) {
- Dictionary bct = d["normalTexture"];
+ const Dictionary &bct = d["normalTexture"];
if (bct.has("index")) {
material->set_texture(SpatialMaterial::TEXTURE_NORMAL, _get_texture(state, bct["index"]));
material->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true);
@@ -1349,24 +1437,25 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
}
}
if (d.has("occlusionTexture")) {
- Dictionary bct = d["occlusionTexture"];
+ const Dictionary &bct = d["occlusionTexture"];
if (bct.has("index")) {
material->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, _get_texture(state, bct["index"]));
+ material->set_ao_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_RED);
material->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true);
}
}
if (d.has("emissiveFactor")) {
- Array arr = d["emissiveFactor"];
+ const Array &arr = d["emissiveFactor"];
ERR_FAIL_COND_V(arr.size() != 3, ERR_PARSE_ERROR);
- Color c = Color(arr[0], arr[1], arr[2]).to_srgb();
+ const Color c = Color(arr[0], arr[1], arr[2]).to_srgb();
material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
material->set_emission(c);
}
if (d.has("emissiveTexture")) {
- Dictionary bct = d["emissiveTexture"];
+ const Dictionary &bct = d["emissiveTexture"];
if (bct.has("index")) {
material->set_texture(SpatialMaterial::TEXTURE_EMISSION, _get_texture(state, bct["index"]));
material->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
@@ -1375,16 +1464,17 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
}
if (d.has("doubleSided")) {
- bool ds = d["doubleSided"];
+ const bool ds = d["doubleSided"];
if (ds) {
material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
}
}
if (d.has("alphaMode")) {
- String am = d["alphaMode"];
+ const String &am = d["alphaMode"];
if (am != "OPAQUE") {
material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
}
}
@@ -1396,131 +1486,764 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
return OK;
}
+EditorSceneImporterGLTF::GLTFNodeIndex EditorSceneImporterGLTF::_find_highest_node(GLTFState &state, const Vector<GLTFNodeIndex> &subset) {
+ int heighest = -1;
+ GLTFNodeIndex best_node = -1;
+
+ for (int i = 0; i < subset.size(); ++i) {
+ const GLTFNodeIndex node_i = subset[i];
+ const GLTFNode *node = state.nodes[node_i];
+
+ if (heighest == -1 || node->height < heighest) {
+ heighest = node->height;
+ best_node = node_i;
+ }
+ }
+
+ return best_node;
+}
+
+bool EditorSceneImporterGLTF::_capture_nodes_in_skin(GLTFState &state, GLTFSkin &skin, const GLTFNodeIndex node_index) {
+
+ bool found_joint = false;
+
+ for (int i = 0; i < state.nodes[node_index]->children.size(); ++i) {
+ found_joint |= _capture_nodes_in_skin(state, skin, state.nodes[node_index]->children[i]);
+ }
+
+ if (found_joint) {
+ // Mark it if we happen to find another skins joint...
+ if (state.nodes[node_index]->joint && skin.joints.find(node_index) < 0) {
+ skin.joints.push_back(node_index);
+ } else if (skin.non_joints.find(node_index) < 0) {
+ skin.non_joints.push_back(node_index);
+ }
+ }
+
+ if (skin.joints.find(node_index) > 0) {
+ return true;
+ }
+
+ return false;
+}
+
+void EditorSceneImporterGLTF::_capture_nodes_for_multirooted_skin(GLTFState &state, GLTFSkin &skin) {
+
+ DisjointSet<GLTFNodeIndex> disjoint_set;
+
+ for (int i = 0; i < skin.joints.size(); ++i) {
+ const GLTFNodeIndex node_index = skin.joints[i];
+ const GLTFNodeIndex parent = state.nodes[node_index]->parent;
+ disjoint_set.insert(node_index);
+
+ if (skin.joints.find(parent) >= 0) {
+ disjoint_set.create_union(parent, node_index);
+ }
+ }
+
+ Vector<GLTFNodeIndex> roots;
+ disjoint_set.get_representatives(roots);
+
+ if (roots.size() <= 1) {
+ return;
+ }
+
+ int maxHeight = -1;
+
+ // Determine the max height rooted tree
+ for (int i = 0; i < roots.size(); ++i) {
+ const GLTFNodeIndex root = roots[i];
+
+ if (maxHeight == -1 || state.nodes[root]->height < maxHeight) {
+ maxHeight = state.nodes[root]->height;
+ }
+ }
+
+ // Go up the tree till all of the multiple roots of the skin are at the same hierarchy level.
+ // This sucks, but 99% of all game engines (not just Godot) would have this same issue.
+ for (int i = 0; i < roots.size(); ++i) {
+
+ GLTFNodeIndex current_node = roots[i];
+ while (state.nodes[current_node]->height > maxHeight) {
+ GLTFNodeIndex parent = state.nodes[current_node]->parent;
+
+ if (state.nodes[parent]->joint && skin.joints.find(parent) < 0) {
+ skin.joints.push_back(parent);
+ } else if (skin.non_joints.find(parent) < 0) {
+ skin.non_joints.push_back(parent);
+ }
+
+ current_node = parent;
+ }
+
+ // replace the roots
+ roots.write[i] = current_node;
+ }
+
+ // Climb up the tree until they all have the same parent
+ bool all_same;
+
+ do {
+ all_same = true;
+ const GLTFNodeIndex first_parent = state.nodes[roots[0]]->parent;
+
+ for (int i = 1; i < roots.size(); ++i) {
+ all_same &= (first_parent == state.nodes[roots[i]]->parent);
+ }
+
+ if (!all_same) {
+ for (int i = 0; i < roots.size(); ++i) {
+ const GLTFNodeIndex current_node = roots[i];
+ const GLTFNodeIndex parent = state.nodes[current_node]->parent;
+
+ if (state.nodes[parent]->joint && skin.joints.find(parent) < 0) {
+ skin.joints.push_back(parent);
+ } else if (skin.non_joints.find(parent) < 0) {
+ skin.non_joints.push_back(parent);
+ }
+
+ roots.write[i] = parent;
+ }
+ }
+
+ } while (!all_same);
+}
+
+Error EditorSceneImporterGLTF::_expand_skin(GLTFState &state, GLTFSkin &skin) {
+
+ _capture_nodes_for_multirooted_skin(state, skin);
+
+ // Grab all nodes that lay in between skin joints/nodes
+ DisjointSet<GLTFNodeIndex> disjoint_set;
+
+ Vector<GLTFNodeIndex> all_skin_nodes;
+ all_skin_nodes.append_array(skin.joints);
+ all_skin_nodes.append_array(skin.non_joints);
+
+ for (int i = 0; i < all_skin_nodes.size(); ++i) {
+ const GLTFNodeIndex node_index = all_skin_nodes[i];
+ const GLTFNodeIndex parent = state.nodes[node_index]->parent;
+ disjoint_set.insert(node_index);
+
+ if (all_skin_nodes.find(parent) >= 0) {
+ disjoint_set.create_union(parent, node_index);
+ }
+ }
+
+ Vector<GLTFNodeIndex> out_owners;
+ disjoint_set.get_representatives(out_owners);
+
+ Vector<GLTFNodeIndex> out_roots;
+
+ for (int i = 0; i < out_owners.size(); ++i) {
+ Vector<GLTFNodeIndex> set;
+ disjoint_set.get_members(set, out_owners[i]);
+
+ const GLTFNodeIndex root = _find_highest_node(state, set);
+ ERR_FAIL_COND_V(root < 0, FAILED);
+ out_roots.push_back(root);
+ }
+
+ out_roots.sort();
+
+ for (int i = 0; i < out_roots.size(); ++i) {
+ _capture_nodes_in_skin(state, skin, out_roots[i]);
+ }
+
+ skin.roots = out_roots;
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_verify_skin(GLTFState &state, GLTFSkin &skin) {
+ // Grab all nodes that lay in between skin joints/nodes
+ DisjointSet<GLTFNodeIndex> disjoint_set;
+
+ Vector<GLTFNodeIndex> all_skin_nodes;
+ all_skin_nodes.append_array(skin.joints);
+ all_skin_nodes.append_array(skin.non_joints);
+
+ for (int i = 0; i < all_skin_nodes.size(); ++i) {
+ const GLTFNodeIndex node_index = all_skin_nodes[i];
+ const GLTFNodeIndex parent = state.nodes[node_index]->parent;
+ disjoint_set.insert(node_index);
+
+ if (all_skin_nodes.find(parent) >= 0) {
+ disjoint_set.create_union(parent, node_index);
+ }
+ }
+
+ Vector<GLTFNodeIndex> out_roots;
+ disjoint_set.get_representatives(out_roots);
+ out_roots.sort();
+
+ ERR_FAIL_COND_V(out_roots.size() == 0, FAILED);
+
+ ERR_FAIL_COND_V(out_roots.size() != skin.roots.size(), FAILED);
+ for (int i = 0; i < out_roots.size(); ++i) {
+ ERR_FAIL_COND_V(out_roots.size() != skin.roots.size(), FAILED);
+ }
+
+ // Single rooted skin? Perfectly ok!
+ if (out_roots.size() == 1) {
+ return OK;
+ }
+
+ // Make sure all parents of a multi-rooted skin are the SAME
+ const GLTFNodeIndex parent = state.nodes[out_roots[0]]->parent;
+ for (int i = 1; i < out_roots.size(); ++i) {
+ if (state.nodes[out_roots[i]]->parent != parent) {
+ return FAILED;
+ }
+ }
+
+ return OK;
+}
+
Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
if (!state.json.has("skins"))
return OK;
- Array skins = state.json["skins"];
+ const Array &skins = state.json["skins"];
+
+ // Create the base skins, and mark nodes that are joints
for (int i = 0; i < skins.size(); i++) {
- Dictionary d = skins[i];
+ const Dictionary &d = skins[i];
GLTFSkin skin;
ERR_FAIL_COND_V(!d.has("joints"), ERR_PARSE_ERROR);
- Array joints = d["joints"];
- Vector<Transform> bind_matrices;
+ const Array &joints = d["joints"];
if (d.has("inverseBindMatrices")) {
- bind_matrices = _decode_accessor_as_xform(state, d["inverseBindMatrices"], false);
- ERR_FAIL_COND_V(bind_matrices.size() != joints.size(), ERR_PARSE_ERROR);
+ skin.inverse_binds = _decode_accessor_as_xform(state, d["inverseBindMatrices"], false);
+ ERR_FAIL_COND_V(skin.inverse_binds.size() != joints.size(), ERR_PARSE_ERROR);
}
for (int j = 0; j < joints.size(); j++) {
- int index = joints[j];
- ERR_FAIL_INDEX_V(index, state.nodes.size(), ERR_PARSE_ERROR);
- GLTFNode::Joint joint;
- joint.skin = state.skins.size();
- joint.bone = j;
- state.nodes[index]->joints.push_back(joint);
- GLTFSkin::Bone bone;
- bone.node = index;
- if (bind_matrices.size()) {
- bone.inverse_bind = bind_matrices[j];
- }
+ const GLTFNodeIndex node = joints[j];
+ ERR_FAIL_INDEX_V(node, state.nodes.size(), ERR_PARSE_ERROR);
- skin.bones.push_back(bone);
+ skin.joints.push_back(node);
+ skin.joints_original.push_back(node);
+
+ state.nodes[node]->joint = true;
+ }
+
+ if (d.has("name")) {
+ skin.name = d["name"];
}
- print_verbose("glTF: Skin has skeleton? " + itos(d.has("skeleton")));
if (d.has("skeleton")) {
- int skeleton = d["skeleton"];
- ERR_FAIL_INDEX_V(skeleton, state.nodes.size(), ERR_PARSE_ERROR);
- print_verbose("glTF: Setting skeleton skin to" + itos(skeleton));
- skin.skeleton = skeleton;
- if (!state.skeleton_nodes.has(skeleton)) {
- state.skeleton_nodes[skeleton] = Vector<int>();
+ skin.skin_root = d["skeleton"];
+ }
+
+ state.skins.push_back(skin);
+ }
+
+ for (GLTFSkinIndex i = 0; i < state.skins.size(); ++i) {
+ GLTFSkin &skin = state.skins.write[i];
+
+ // Expand the skin to capture all the extra non-joints that lie in between the actual joints,
+ // and expand the hierarchy to ensure multi-rooted trees lie on the same height level
+ ERR_FAIL_COND_V(_expand_skin(state, skin), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(_verify_skin(state, skin), ERR_PARSE_ERROR);
+ }
+
+ print_verbose("glTF: Total skins: " + itos(state.skins.size()));
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_determine_skeletons(GLTFState &state) {
+
+ // Using a disjoint set, we are going to potentially combine all skins that are actually branches
+ // of a main skeleton, or treat skins defining the same set of nodes as ONE skeleton.
+ // This is another unclear issue caused by the current glTF specification.
+
+ DisjointSet<GLTFNodeIndex> skeleton_sets;
+
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ const GLTFSkin &skin = state.skins[skin_i];
+
+ Vector<GLTFNodeIndex> all_skin_nodes;
+ all_skin_nodes.append_array(skin.joints);
+ all_skin_nodes.append_array(skin.non_joints);
+
+ for (int i = 0; i < all_skin_nodes.size(); ++i) {
+ const GLTFNodeIndex node_index = all_skin_nodes[i];
+ const GLTFNodeIndex parent = state.nodes[node_index]->parent;
+ skeleton_sets.insert(node_index);
+
+ if (all_skin_nodes.find(parent) >= 0) {
+ skeleton_sets.create_union(parent, node_index);
}
- state.skeleton_nodes[skeleton].push_back(i);
}
- if (d.has("name")) {
- skin.name = d["name"];
+ // We are going to connect the separate skin subtrees in each skin together
+ // so that the final roots are entire sets of valid skin trees
+ for (int i = 1; i < skin.roots.size(); ++i) {
+ skeleton_sets.create_union(skin.roots[0], skin.roots[i]);
}
+ }
- //locate the right place to put a Skeleton node
- /*
- if (state.skin_users.has(i)) {
- Vector<int> users = state.skin_users[i];
- int skin_node = -1;
- for (int j = 0; j < users.size(); j++) {
- int user = state.nodes[users[j]]->parent; //always go from parent
- if (j == 0) {
- skin_node = user;
- } else if (skin_node != -1) {
- bool found = false;
- while (skin_node >= 0) {
-
- int cuser = user;
- while (cuser != -1) {
- if (cuser == skin_node) {
- found = true;
- break;
- }
- cuser = state.nodes[skin_node]->parent;
- }
- if (found)
- break;
- skin_node = state.nodes[skin_node]->parent;
- }
+ { // attempt to joint all touching subsets (siblings/parent are part of another skin)
+ Vector<GLTFNodeIndex> groups_representatives;
+ skeleton_sets.get_representatives(groups_representatives);
+
+ Vector<GLTFNodeIndex> highest_group_members;
+ Vector<Vector<GLTFNodeIndex> > groups;
+ for (int i = 0; i < groups_representatives.size(); ++i) {
+ Vector<GLTFNodeIndex> group;
+ skeleton_sets.get_members(group, groups_representatives[i]);
+ highest_group_members.push_back(_find_highest_node(state, group));
+ groups.push_back(group);
+ }
+
+ for (int i = 0; i < highest_group_members.size(); ++i) {
+ const GLTFNodeIndex node_i = highest_group_members[i];
+
+ // Attach any siblings together (this needs to be done n^2/2 times)
+ for (int j = i + 1; j < highest_group_members.size(); ++j) {
+ const GLTFNodeIndex node_j = highest_group_members[j];
+
+ // Even if they are siblings under the root! :)
+ if (state.nodes[node_i]->parent == state.nodes[node_j]->parent) {
+ skeleton_sets.create_union(node_i, node_j);
+ }
+ }
- if (!found) {
- skin_node = -1; //just leave where it is
+ // Attach any parenting going on together (we need to do this n^2 times)
+ const GLTFNodeIndex node_i_parent = state.nodes[node_i]->parent;
+ if (node_i_parent >= 0) {
+ for (int j = 0; j < groups.size() && i != j; ++j) {
+ const Vector<GLTFNodeIndex> &group = groups[j];
+
+ if (group.find(node_i_parent) >= 0) {
+ const GLTFNodeIndex node_j = highest_group_members[j];
+ skeleton_sets.create_union(node_i, node_j);
}
+ }
+ }
+ }
+ }
+
+ // At this point, the skeleton groups should be finalized
+ Vector<GLTFNodeIndex> skeleton_owners;
+ skeleton_sets.get_representatives(skeleton_owners);
+
+ // Mark all the skins actual skeletons, after we have merged them
+ for (GLTFSkeletonIndex skel_i = 0; skel_i < skeleton_owners.size(); ++skel_i) {
- //find a common parent
+ const GLTFNodeIndex skeleton_owner = skeleton_owners[skel_i];
+ GLTFSkeleton skeleton;
+
+ Vector<GLTFNodeIndex> skeleton_nodes;
+ skeleton_sets.get_members(skeleton_nodes, skeleton_owner);
+
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ GLTFSkin &skin = state.skins.write[skin_i];
+
+ // If any of the the skeletons nodes exist in a skin, that skin now maps to the skeleton
+ for (int i = 0; i < skeleton_nodes.size(); ++i) {
+ GLTFNodeIndex skel_node_i = skeleton_nodes[i];
+ if (skin.joints.find(skel_node_i) >= 0 || skin.non_joints.find(skel_node_i) >= 0) {
+ skin.skeleton = skel_i;
+ continue;
}
}
+ }
+
+ Vector<GLTFNodeIndex> non_joints;
+ for (int i = 0; i < skeleton_nodes.size(); ++i) {
+ const GLTFNodeIndex node_i = skeleton_nodes[i];
+
+ if (state.nodes[node_i]->joint) {
+ skeleton.joints.push_back(node_i);
+ } else {
+ non_joints.push_back(node_i);
+ }
+ }
+
+ state.skeletons.push_back(skeleton);
+
+ _reparent_non_joint_skeleton_subtrees(state, state.skeletons.write[skel_i], non_joints);
+ }
+
+ for (GLTFSkeletonIndex skel_i = 0; skel_i < state.skeletons.size(); ++skel_i) {
+ GLTFSkeleton &skeleton = state.skeletons.write[skel_i];
+
+ for (int i = 0; i < skeleton.joints.size(); ++i) {
+ const GLTFNodeIndex node_i = skeleton.joints[i];
+ GLTFNode *node = state.nodes[node_i];
+
+ ERR_FAIL_COND_V(!node->joint, ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(node->skeleton >= 0, ERR_PARSE_ERROR);
+ node->skeleton = skel_i;
+ }
+
+ ERR_FAIL_COND_V(_determine_skeleton_roots(state, skel_i), ERR_PARSE_ERROR);
+ }
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_reparent_non_joint_skeleton_subtrees(GLTFState &state, GLTFSkeleton &skeleton, const Vector<GLTFNodeIndex> &non_joints) {
+
+ DisjointSet<GLTFNodeIndex> subtree_set;
+
+ // Populate the disjoint set with ONLY non joints that are in the skeleton hierarchy (non_joints vector)
+ // This way we can find any joints that lie in between joints, as the current glTF specification
+ // mentions nothing about non-joints being in between joints of the same skin. Hopefully one day we
+ // can remove this code.
+
+ // skinD depicted here explains this issue:
+ // https://github.com/KhronosGroup/glTF-Asset-Generator/blob/master/Output/Positive/Animation_Skin
+
+ for (int i = 0; i < non_joints.size(); ++i) {
+ const GLTFNodeIndex node_i = non_joints[i];
+
+ subtree_set.insert(node_i);
+
+ const GLTFNodeIndex parent_i = state.nodes[node_i]->parent;
+ if (parent_i >= 0 && non_joints.find(parent_i) >= 0 && !state.nodes[parent_i]->joint) {
+ subtree_set.create_union(parent_i, node_i);
+ }
+ }
+
+ // Find all the non joint subtrees and re-parent them to a new "fake" joint
+
+ Vector<GLTFNodeIndex> non_joint_subtree_roots;
+ subtree_set.get_representatives(non_joint_subtree_roots);
+
+ for (int root_i = 0; root_i < non_joint_subtree_roots.size(); ++root_i) {
+ const GLTFNodeIndex subtree_root = non_joint_subtree_roots[root_i];
+
+ Vector<GLTFNodeIndex> subtree_nodes;
+ subtree_set.get_members(subtree_nodes, subtree_root);
+
+ for (int subtree_i = 0; subtree_i < subtree_nodes.size(); ++subtree_i) {
+ ERR_FAIL_COND_V(_reparent_to_fake_joint(state, skeleton, subtree_nodes[subtree_i]), FAILED);
+
+ // We modified the tree, recompute all the heights
+ _compute_node_heights(state);
+ }
+ }
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_reparent_to_fake_joint(GLTFState &state, GLTFSkeleton &skeleton, const GLTFNodeIndex node_index) {
+ GLTFNode *node = state.nodes[node_index];
+
+ // Can we just "steal" this joint if it is just a spatial node?
+ if (node->skin < 0 && node->mesh < 0 && node->camera < 0) {
+ node->joint = true;
+ // Add the joint to the skeletons joints
+ skeleton.joints.push_back(node_index);
+ return OK;
+ }
+
+ GLTFNode *fake_joint = memnew(GLTFNode);
+ const GLTFNodeIndex fake_joint_index = state.nodes.size();
+ state.nodes.push_back(fake_joint);
+
+ // We better not be a joint, or we messed up in our logic
+ if (node->joint == true)
+ return FAILED;
+
+ fake_joint->translation = node->translation;
+ fake_joint->rotation = node->rotation;
+ fake_joint->scale = node->scale;
+ fake_joint->xform = node->xform;
+ fake_joint->joint = true;
+
+ // We can use the exact same name here, because the joint will be inside a skeleton and not the scene
+ fake_joint->name = node->name;
+
+ // Clear the nodes transforms, since it will be parented to the fake joint
+ node->translation = Vector3(0, 0, 0);
+ node->rotation = Quat();
+ node->scale = Vector3(1, 1, 1);
+ node->xform = Transform();
+
+ // Transfer the node children to the fake joint
+ for (int child_i = 0; child_i < node->children.size(); ++child_i) {
+ GLTFNode *child = state.nodes[node->children[child_i]];
+ child->parent = fake_joint_index;
+ }
+
+ fake_joint->children = node->children;
+ node->children.clear();
+
+ // add the fake joint to the parent and remove the original joint
+ if (node->parent >= 0) {
+ GLTFNode *parent = state.nodes[node->parent];
+ parent->children.erase(node_index);
+ parent->children.push_back(fake_joint_index);
+ fake_joint->parent = node->parent;
+ }
+
+ // Add the node to the fake joint
+ fake_joint->children.push_back(node_index);
+ node->parent = fake_joint_index;
+ node->fake_joint_parent = fake_joint_index;
+
+ // Add the fake joint to the skeletons joints
+ skeleton.joints.push_back(fake_joint_index);
+
+ // Replace skin_skeletons with fake joints if we must.
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ GLTFSkin &skin = state.skins.write[skin_i];
+ if (skin.skin_root == node_index) {
+ skin.skin_root = fake_joint_index;
+ }
+ }
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_determine_skeleton_roots(GLTFState &state, const GLTFSkeletonIndex skel_i) {
+
+ DisjointSet<GLTFNodeIndex> disjoint_set;
+
+ for (GLTFNodeIndex i = 0; i < state.nodes.size(); ++i) {
+ const GLTFNode *node = state.nodes[i];
+
+ if (node->skeleton != skel_i) {
+ continue;
+ }
+
+ disjoint_set.insert(i);
+
+ if (node->parent >= 0 && state.nodes[node->parent]->skeleton == skel_i) {
+ disjoint_set.create_union(node->parent, i);
+ }
+ }
+
+ GLTFSkeleton &skeleton = state.skeletons.write[skel_i];
+
+ Vector<GLTFNodeIndex> owners;
+ disjoint_set.get_representatives(owners);
+
+ Vector<GLTFNodeIndex> roots;
+
+ for (int i = 0; i < owners.size(); ++i) {
+ Vector<GLTFNodeIndex> set;
+ disjoint_set.get_members(set, owners[i]);
+ const GLTFNodeIndex root = _find_highest_node(state, set);
+ ERR_FAIL_COND_V(root < 0, FAILED);
+ roots.push_back(root);
+ }
+
+ roots.sort();
+
+ skeleton.roots = roots;
+
+ if (roots.size() == 0) {
+ return FAILED;
+ } else if (roots.size() == 1) {
+ return OK;
+ }
+
+ // Check that the subtrees have the same parent root
+ const GLTFNodeIndex parent = state.nodes[roots[0]]->parent;
+ for (int i = 1; i < roots.size(); ++i) {
+ if (state.nodes[roots[i]]->parent != parent) {
+ return FAILED;
+ }
+ }
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_create_skeletons(GLTFState &state) {
+ for (GLTFSkeletonIndex skel_i = 0; skel_i < state.skeletons.size(); ++skel_i) {
+
+ GLTFSkeleton &gltf_skeleton = state.skeletons.write[skel_i];
+
+ Skeleton *skeleton = memnew(Skeleton);
+ gltf_skeleton.godot_skeleton = skeleton;
+
+ // Make a unique name, no gltf node represents this skeleton
+ skeleton->set_name(_gen_unique_name(state, "Skeleton"));
+
+ List<GLTFNodeIndex> bones;
- if (skin_node != -1) {
- for (int j = 0; j < users.size(); j++) {
- state.nodes[users[j]]->child_of_skeleton = i;
+ for (int i = 0; i < gltf_skeleton.roots.size(); ++i) {
+ bones.push_back(gltf_skeleton.roots[i]);
+ }
+
+ // Make the skeleton creation deterministic by going through the roots in
+ // a sorted order, and DEPTH FIRST
+ bones.sort();
+
+ while (!bones.empty()) {
+ const GLTFNodeIndex node_i = bones.front()->get();
+ bones.pop_front();
+
+ GLTFNode *node = state.nodes[node_i];
+ ERR_FAIL_COND_V(node->skeleton != skel_i, FAILED);
+
+ { // Add all child nodes to the stack (deterministically)
+ Vector<GLTFNodeIndex> child_nodes;
+ for (int i = 0; i < node->children.size(); ++i) {
+ const GLTFNodeIndex child_i = node->children[i];
+ if (state.nodes[child_i]->skeleton == skel_i) {
+ child_nodes.push_back(child_i);
+ }
}
- state.nodes[skin_node]->skeleton_children.push_back(i);
+ // Depth first insertion
+ child_nodes.sort();
+ for (int i = child_nodes.size() - 1; i >= 0; --i) {
+ bones.push_front(child_nodes[i]);
+ }
}
+
+ const int bone_index = skeleton->get_bone_count();
+
+ if (node->name.empty()) {
+ node->name = "bone";
+ }
+
+ node->name = _gen_unique_bone_name(state, skel_i, node->name);
+
+ skeleton->add_bone(node->name);
+ skeleton->set_bone_rest(bone_index, node->xform);
+ skeleton->set_bone_pose(bone_index, node->xform);
+
+ if (node->parent >= 0 && state.nodes[node->parent]->skeleton == skel_i) {
+ const int bone_parent = skeleton->find_bone(state.nodes[node->parent]->name);
+ ERR_FAIL_COND_V(bone_parent < 0, FAILED);
+ skeleton->set_bone_parent(bone_index, skeleton->find_bone(state.nodes[node->parent]->name));
+ }
+
+ state.scene_nodes.insert(node_i, skeleton);
}
- */
- state.skins.push_back(skin);
}
- print_verbose("glTF: Total skins: " + itos(state.skins.size()));
- //now
+ ERR_FAIL_COND_V(_map_skin_joints_indices_to_skeleton_bone_indices(state), ERR_PARSE_ERROR);
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_map_skin_joints_indices_to_skeleton_bone_indices(GLTFState &state) {
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ GLTFSkin &skin = state.skins.write[skin_i];
+
+ const GLTFSkeleton &skeleton = state.skeletons[skin.skeleton];
+
+ for (int joint_index = 0; joint_index < skin.joints_original.size(); ++joint_index) {
+ const GLTFNodeIndex node_i = skin.joints_original[joint_index];
+ const GLTFNode *node = state.nodes[node_i];
+
+ const int bone_index = skeleton.godot_skeleton->find_bone(node->name);
+ ERR_FAIL_COND_V(bone_index < 0, FAILED);
+
+ skin.joint_i_to_bone_i.insert(joint_index, bone_index);
+ }
+ }
+
+ return OK;
+}
+
+Error EditorSceneImporterGLTF::_create_skins(GLTFState &state) {
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ GLTFSkin &gltf_skin = state.skins.write[skin_i];
+
+ Ref<Skin> skin;
+ skin.instance();
+
+ // Some skins don't have IBM's! What absolute monsters!
+ const bool has_ibms = !gltf_skin.inverse_binds.empty();
+
+ for (int joint_i = 0; joint_i < gltf_skin.joints_original.size(); ++joint_i) {
+ int bone_i = gltf_skin.joint_i_to_bone_i[joint_i];
+
+ if (has_ibms) {
+ skin->add_bind(bone_i, gltf_skin.inverse_binds[joint_i]);
+ } else {
+ skin->add_bind(bone_i, Transform());
+ }
+ }
+
+ gltf_skin.godot_skin = skin;
+ }
+
+ // Purge the duplicates!
+ _remove_duplicate_skins(state);
+
+ // Create unique names now, after removing duplicates
+ for (GLTFSkinIndex skin_i = 0; skin_i < state.skins.size(); ++skin_i) {
+ Ref<Skin> skin = state.skins[skin_i].godot_skin;
+ if (skin->get_name().empty()) {
+ // Make a unique name, no gltf node represents this skin
+ skin->set_name(_gen_unique_name(state, "Skin"));
+ }
+ }
return OK;
}
+bool EditorSceneImporterGLTF::_skins_are_same(const Ref<Skin> &skin_a, const Ref<Skin> &skin_b) {
+ if (skin_a->get_bind_count() != skin_b->get_bind_count()) {
+ return false;
+ }
+
+ for (int i = 0; i < skin_a->get_bind_count(); ++i) {
+
+ if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
+ return false;
+ }
+
+ Transform a_xform = skin_a->get_bind_pose(i);
+ Transform b_xform = skin_b->get_bind_pose(i);
+
+ if (a_xform != b_xform) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void EditorSceneImporterGLTF::_remove_duplicate_skins(GLTFState &state) {
+ for (int i = 0; i < state.skins.size(); ++i) {
+ for (int j = i + 1; j < state.skins.size(); ++j) {
+ const Ref<Skin> &skin_i = state.skins[i].godot_skin;
+ const Ref<Skin> &skin_j = state.skins[j].godot_skin;
+
+ if (_skins_are_same(skin_i, skin_j)) {
+ // replace it and delete the old
+ state.skins.write[j].godot_skin = skin_i;
+ }
+ }
+ }
+}
+
Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
if (!state.json.has("cameras"))
return OK;
- Array cameras = state.json["cameras"];
+ const Array &cameras = state.json["cameras"];
- for (int i = 0; i < cameras.size(); i++) {
+ for (GLTFCameraIndex i = 0; i < cameras.size(); i++) {
- Dictionary d = cameras[i];
+ const Dictionary &d = cameras[i];
GLTFCamera camera;
ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
- String type = d["type"];
+ const String &type = d["type"];
if (type == "orthographic") {
camera.perspective = false;
if (d.has("orthographic")) {
- Dictionary og = d["orthographic"];
+ const Dictionary &og = d["orthographic"];
camera.fov_size = og["ymag"];
camera.zfar = og["zfar"];
camera.znear = og["znear"];
@@ -1532,7 +2255,7 @@ Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
camera.perspective = true;
if (d.has("perspective")) {
- Dictionary ppt = d["perspective"];
+ const Dictionary &ppt = d["perspective"];
// GLTF spec is in radians, Godot's camera is in degrees.
camera.fov_size = (double)ppt["yfov"] * 180.0 / Math_PI;
camera.zfar = ppt["zfar"];
@@ -1541,8 +2264,7 @@ Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
camera.fov_size = 10;
}
} else {
- ERR_EXPLAIN("Camera should be in 'orthographic' or 'perspective'");
- ERR_FAIL_V(ERR_PARSE_ERROR);
+ ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "Camera should be in 'orthographic' or 'perspective'");
}
state.cameras.push_back(camera);
@@ -1558,11 +2280,11 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
if (!state.json.has("animations"))
return OK;
- Array animations = state.json["animations"];
+ const Array &animations = state.json["animations"];
- for (int i = 0; i < animations.size(); i++) {
+ for (GLTFAnimationIndex i = 0; i < animations.size(); i++) {
- Dictionary d = animations[i];
+ const Dictionary &d = animations[i];
GLTFAnimation animation;
@@ -1578,25 +2300,25 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
for (int j = 0; j < channels.size(); j++) {
- Dictionary c = channels[j];
+ const Dictionary &c = channels[j];
if (!c.has("target"))
continue;
- Dictionary t = c["target"];
+ const Dictionary &t = c["target"];
if (!t.has("node") || !t.has("path")) {
continue;
}
ERR_FAIL_COND_V(!c.has("sampler"), ERR_PARSE_ERROR);
- int sampler = c["sampler"];
+ const int sampler = c["sampler"];
ERR_FAIL_INDEX_V(sampler, samplers.size(), ERR_PARSE_ERROR);
- int node = t["node"];
+ GLTFNodeIndex node = t["node"];
String path = t["path"];
ERR_FAIL_INDEX_V(node, state.nodes.size(), ERR_PARSE_ERROR);
- GLTFAnimation::Track *track = NULL;
+ GLTFAnimation::Track *track = nullptr;
if (!animation.tracks.has(node)) {
animation.tracks[node] = GLTFAnimation::Track();
@@ -1604,17 +2326,17 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
track = &animation.tracks[node];
- Dictionary s = samplers[sampler];
+ const Dictionary &s = samplers[sampler];
ERR_FAIL_COND_V(!s.has("input"), ERR_PARSE_ERROR);
ERR_FAIL_COND_V(!s.has("output"), ERR_PARSE_ERROR);
- int input = s["input"];
- int output = s["output"];
+ const int input = s["input"];
+ const int output = s["output"];
GLTFAnimation::Interpolation interp = GLTFAnimation::INTERP_LINEAR;
if (s.has("interpolation")) {
- String in = s["interpolation"];
+ const String &in = s["interpolation"];
if (in == "STEP") {
interp = GLTFAnimation::INTERP_STEP;
} else if (in == "LINEAR") {
@@ -1626,33 +2348,33 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
}
}
- PoolVector<float> times = _decode_accessor_as_floats(state, input, false);
+ const PoolVector<float> times = _decode_accessor_as_floats(state, input, false);
if (path == "translation") {
- PoolVector<Vector3> translations = _decode_accessor_as_vec3(state, output, false);
+ const PoolVector<Vector3> translations = _decode_accessor_as_vec3(state, output, false);
track->translation_track.interpolation = interp;
track->translation_track.times = Variant(times); //convert via variant
track->translation_track.values = Variant(translations); //convert via variant
} else if (path == "rotation") {
- Vector<Quat> rotations = _decode_accessor_as_quat(state, output, false);
+ const Vector<Quat> rotations = _decode_accessor_as_quat(state, output, false);
track->rotation_track.interpolation = interp;
track->rotation_track.times = Variant(times); //convert via variant
track->rotation_track.values = rotations; //convert via variant
} else if (path == "scale") {
- PoolVector<Vector3> scales = _decode_accessor_as_vec3(state, output, false);
+ const PoolVector<Vector3> scales = _decode_accessor_as_vec3(state, output, false);
track->scale_track.interpolation = interp;
track->scale_track.times = Variant(times); //convert via variant
track->scale_track.values = Variant(scales); //convert via variant
} else if (path == "weights") {
- PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
+ const PoolVector<float> weights = _decode_accessor_as_floats(state, output, false);
ERR_FAIL_INDEX_V(state.nodes[node]->mesh, state.meshes.size(), ERR_PARSE_ERROR);
const GLTFMesh *mesh = &state.meshes[state.nodes[node]->mesh];
ERR_FAIL_COND_V(mesh->blend_weights.size() == 0, ERR_PARSE_ERROR);
- int wc = mesh->blend_weights.size();
+ const int wc = mesh->blend_weights.size();
track->weight_tracks.resize(wc);
- int wlen = weights.size() / wc;
+ const int wlen = weights.size() / wc;
PoolVector<float>::Read r = weights.read();
for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea
GLTFAnimation::Channel<float> cf;
@@ -1684,11 +2406,16 @@ void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
for (int i = 0; i < state.nodes.size(); i++) {
GLTFNode *n = state.nodes[i];
- if (n->name == "") {
+
+ // Any joints get unique names generated when the skeleton is made, unique to the skeleton
+ if (n->skeleton >= 0)
+ continue;
+
+ if (n->name.empty()) {
if (n->mesh >= 0) {
n->name = "Mesh";
- } else if (n->joints.size()) {
- n->name = "Bone";
+ } else if (n->camera >= 0) {
+ n->name = "Camera";
} else {
n->name = "Node";
}
@@ -1698,127 +2425,131 @@ void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
}
}
-void EditorSceneImporterGLTF::_reparent_skeleton(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node) {
- //reparent skeletons to proper place
- Vector<int> nodes = state.skeleton_nodes[p_node];
- for (int i = 0; i < nodes.size(); i++) {
- Skeleton *skeleton = skeletons[nodes[i]];
- Node *owner = skeleton->get_owner();
- skeleton->get_parent()->remove_child(skeleton);
- p_parent_node->add_child(skeleton);
- skeleton->set_owner(owner);
- //may have meshes as children, set owner in them too
- for (int j = 0; j < skeleton->get_child_count(); j++) {
- skeleton->get_child(j)->set_owner(owner);
- }
- }
-}
+BoneAttachment *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &state, Skeleton *skeleton, const GLTFNodeIndex node_index) {
-void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons) {
- ERR_FAIL_INDEX(p_node, state.nodes.size());
+ const GLTFNode *gltf_node = state.nodes[node_index];
+ const GLTFNode *bone_node = state.nodes[gltf_node->parent];
- GLTFNode *n = state.nodes[p_node];
- Spatial *node;
+ BoneAttachment *bone_attachment = memnew(BoneAttachment);
+ print_verbose("glTF: Creating bone attachment for: " + gltf_node->name);
- if (n->mesh >= 0) {
- ERR_FAIL_INDEX(n->mesh, state.meshes.size());
- MeshInstance *mi = memnew(MeshInstance);
- print_verbose("glTF: Creating mesh for: " + n->name);
- GLTFMesh &mesh = state.meshes.write[n->mesh];
- mi->set_mesh(mesh.mesh);
- if (mesh.mesh->get_name() == "") {
- mesh.mesh->set_name(n->name);
- }
- for (int i = 0; i < mesh.blend_weights.size(); i++) {
- mi->set("blend_shapes/" + mesh.mesh->get_blend_shape_name(i), mesh.blend_weights[i]);
- }
+ ERR_FAIL_COND_V(!bone_node->joint, nullptr);
- node = mi;
+ bone_attachment->set_bone_name(bone_node->name);
- } else if (n->camera >= 0) {
- ERR_FAIL_INDEX(n->camera, state.cameras.size());
- Camera *camera = memnew(Camera);
+ return bone_attachment;
+}
- const GLTFCamera &c = state.cameras[n->camera];
- if (c.perspective) {
- camera->set_perspective(c.fov_size, c.znear, c.znear);
- } else {
- camera->set_orthogonal(c.fov_size, c.znear, c.znear);
- }
+MeshInstance *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+ const GLTFNode *gltf_node = state.nodes[node_index];
- node = camera;
- } else {
- node = memnew(Spatial);
+ ERR_FAIL_INDEX_V(gltf_node->mesh, state.meshes.size(), nullptr);
+
+ MeshInstance *mi = memnew(MeshInstance);
+ print_verbose("glTF: Creating mesh for: " + gltf_node->name);
+
+ GLTFMesh &mesh = state.meshes.write[gltf_node->mesh];
+ mi->set_mesh(mesh.mesh);
+
+ if (mesh.mesh->get_name() == "") {
+ mesh.mesh->set_name(gltf_node->name);
+ }
+
+ for (int i = 0; i < mesh.blend_weights.size(); i++) {
+ mi->set("blend_shapes/" + mesh.mesh->get_blend_shape_name(i), mesh.blend_weights[i]);
}
- node->set_name(n->name);
+ return mi;
+}
- n->godot_nodes.push_back(node);
+Camera *EditorSceneImporterGLTF::_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+ const GLTFNode *gltf_node = state.nodes[node_index];
- if (n->skin >= 0 && n->skin < skeletons.size() && Object::cast_to<MeshInstance>(node)) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(node);
+ ERR_FAIL_INDEX_V(gltf_node->camera, state.cameras.size(), nullptr);
- Skeleton *s = skeletons[n->skin];
- s->add_child(node); //According to spec, mesh should actually act as a child of the skeleton, as it inherits its transform
- mi->set_skeleton_path(String(".."));
+ Camera *camera = memnew(Camera);
+ print_verbose("glTF: Creating camera for: " + gltf_node->name);
+ const GLTFCamera &c = state.cameras[gltf_node->camera];
+ if (c.perspective) {
+ camera->set_perspective(c.fov_size, c.znear, c.znear);
} else {
- p_parent->add_child(node);
- node->set_transform(n->xform);
+ camera->set_orthogonal(c.fov_size, c.znear, c.znear);
}
- node->set_owner(p_owner);
+ return camera;
+}
-#if 0
- for (int i = 0; i < n->skeleton_children.size(); i++) {
+Spatial *EditorSceneImporterGLTF::_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+ const GLTFNode *gltf_node = state.nodes[node_index];
- Skeleton *s = skeletons[n->skeleton_children[i]];
- s->get_parent()->remove_child(s);
- node->add_child(s);
- s->set_owner(p_owner);
- }
-#endif
- for (int i = 0; i < n->children.size(); i++) {
- if (state.nodes[n->children[i]]->joints.size()) {
- _generate_bone(state, n->children[i], skeletons, node);
- } else {
- _generate_node(state, n->children[i], node, p_owner, skeletons);
- }
- }
+ Spatial *spatial = memnew(Spatial);
+ print_verbose("glTF: Creating spatial for: " + gltf_node->name);
- if (state.skeleton_nodes.has(p_node)) {
- _reparent_skeleton(state, p_node, skeletons, node);
- }
+ return spatial;
}
-void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node) {
- ERR_FAIL_INDEX(p_node, state.nodes.size());
+void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene_parent, Spatial *scene_root, const GLTFNodeIndex node_index) {
+
+ const GLTFNode *gltf_node = state.nodes[node_index];
+
+ Spatial *current_node = nullptr;
+
+ // Is our parent a skeleton
+ Skeleton *active_skeleton = Object::cast_to<Skeleton>(scene_parent);
+
+ if (gltf_node->skeleton >= 0) {
+ Skeleton *skeleton = state.skeletons[gltf_node->skeleton].godot_skeleton;
- if (state.skeleton_nodes.has(p_node)) {
- _reparent_skeleton(state, p_node, skeletons, p_parent_node);
+ if (active_skeleton != skeleton) {
+ ERR_FAIL_COND_MSG(active_skeleton != nullptr, "glTF: Generating scene detected direct parented Skeletons");
+
+ // Add it to the scene if it has not already been added
+ if (skeleton->get_parent() == nullptr) {
+ scene_parent->add_child(skeleton);
+ skeleton->set_owner(scene_root);
+ }
+ }
+
+ active_skeleton = skeleton;
+ current_node = skeleton;
}
- GLTFNode *n = state.nodes[p_node];
+ // If we have an active skeleton, and the node is node skinned, we need to create a bone attachment
+ if (current_node == nullptr && active_skeleton != nullptr && gltf_node->skin < 0) {
+ BoneAttachment *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index);
- for (int i = 0; i < n->joints.size(); i++) {
- const int skin = n->joints[i].skin;
- ERR_FAIL_COND(skin < 0);
+ scene_parent->add_child(bone_attachment);
+ bone_attachment->set_owner(scene_root);
- Skeleton *s = skeletons[skin];
- const GLTFNode *gltf_bone_node = state.nodes[state.skins[skin].bones[n->joints[i].bone].node];
- const String bone_name = gltf_bone_node->name;
- const int parent = gltf_bone_node->parent;
- const int parent_index = s->find_bone(state.nodes[parent]->name);
+ // There is no gltf_node that represent this, so just directly create a unique name
+ bone_attachment->set_name(_gen_unique_name(state, "BoneAttachment"));
- const int bone_index = s->find_bone(bone_name);
- s->set_bone_parent(bone_index, parent_index);
+ // We change the scene_parent to our bone attachment now. We do not set current_node because we want to make the node
+ // and attach it to the bone_attachment
+ scene_parent = bone_attachment;
+ }
+
+ // We still have not managed to make a node
+ if (current_node == nullptr) {
+ if (gltf_node->mesh >= 0) {
+ current_node = _generate_mesh_instance(state, scene_parent, node_index);
+ } else if (gltf_node->camera >= 0) {
+ current_node = _generate_camera(state, scene_parent, node_index);
+ } else {
+ current_node = _generate_spatial(state, scene_parent, node_index);
+ }
- n->godot_nodes.push_back(s);
- n->joints.write[i].godot_bone_index = bone_index;
+ scene_parent->add_child(current_node);
+ current_node->set_owner(scene_root);
+ current_node->set_transform(gltf_node->xform);
+ current_node->set_name(gltf_node->name);
}
- for (int i = 0; i < n->children.size(); i++) {
- _generate_bone(state, n->children[i], skeletons, p_parent_node);
+ state.scene_nodes.insert(node_index, current_node);
+
+ for (int i = 0; i < gltf_node->children.size(); ++i) {
+ _generate_scene_node(state, current_node, scene_root, gltf_node->children[i]);
}
}
@@ -1832,43 +2563,43 @@ struct EditorSceneImporterGLTFInterpolate {
T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
- float t2 = t * t;
- float t3 = t2 * t;
+ const float t2 = t * t;
+ const float t3 = t2 * t;
return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
}
T bezier(T start, T control_1, T control_2, T end, float t) {
/* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - t);
- real_t omt2 = omt * omt;
- real_t omt3 = omt2 * omt;
- real_t t2 = t * t;
- real_t t3 = t2 * t;
+ const real_t omt = (1.0 - t);
+ const real_t omt2 = omt * omt;
+ const real_t omt3 = omt2 * omt;
+ const real_t t2 = t * t;
+ const real_t t3 = t2 * t;
return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
}
};
-//thank you for existing, partial specialization
+// thank you for existing, partial specialization
template <>
struct EditorSceneImporterGLTFInterpolate<Quat> {
- Quat lerp(const Quat &a, const Quat &b, float c) const {
+ Quat lerp(const Quat &a, const Quat &b, const float c) const {
ERR_FAIL_COND_V(!a.is_normalized(), Quat());
ERR_FAIL_COND_V(!b.is_normalized(), Quat());
return a.slerp(b, c).normalized();
}
- Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) {
+ Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, const float c) {
ERR_FAIL_COND_V(!p1.is_normalized(), Quat());
ERR_FAIL_COND_V(!p2.is_normalized(), Quat());
return p1.slerp(p2, c).normalized();
}
- Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) {
+ Quat bezier(const Quat start, const Quat control_1, const Quat control_2, const Quat end, const float t) {
ERR_FAIL_COND_V(!start.is_normalized(), Quat());
ERR_FAIL_COND_V(!end.is_normalized(), Quat());
@@ -1877,7 +2608,7 @@ struct EditorSceneImporterGLTFInterpolate<Quat> {
};
template <class T>
-T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, GLTFAnimation::Interpolation p_interp) {
+T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
//could use binary search, worth it?
int idx = -1;
@@ -1898,7 +2629,7 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
return p_values[p_times.size() - 1];
}
- float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
+ const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
return interp.lerp(p_values[idx], p_values[idx + 1], c);
@@ -1922,7 +2653,7 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
return p_values[1 + p_times.size() - 1];
}
- float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
+ const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
return interp.catmull_rom(p_values[idx - 1], p_values[idx], p_values[idx + 1], p_values[idx + 3], c);
@@ -1935,12 +2666,12 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
return p_values[(p_times.size() - 1) * 3 + 1];
}
- float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
+ const float c = (p_time - p_times[idx]) / (p_times[idx + 1] - p_times[idx]);
- T from = p_values[idx * 3 + 1];
- T c1 = from + p_values[idx * 3 + 2];
- T to = p_values[idx * 3 + 4];
- T c2 = to + p_values[idx * 3 + 3];
+ const T from = p_values[idx * 3 + 1];
+ const T c1 = from + p_values[idx * 3 + 2];
+ const T to = p_values[idx * 3 + 4];
+ const T c2 = to + p_values[idx * 3 + 3];
return interp.bezier(from, c1, c2, to, c);
@@ -1950,12 +2681,13 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
ERR_FAIL_V(p_values[0]);
}
-void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlayer *ap, int index, int bake_fps, Vector<Skeleton *> skeletons) {
+void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps) {
const GLTFAnimation &anim = state.animations[index];
String name = anim.name;
- if (name == "") {
+ if (name.empty()) {
+ // No node represent these, and they are not in the hierarchy, so just make a unique name
name = _gen_unique_name(state, "Animation");
}
@@ -1971,102 +2703,143 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
//need to find the path
NodePath node_path;
- GLTFNode *node = state.nodes[E->key()];
- for (int n = 0; n < node->godot_nodes.size(); n++) {
+ GLTFNodeIndex node_index = E->key();
+ if (state.nodes[node_index]->fake_joint_parent >= 0) {
+ // Should be same as parent
+ node_index = state.nodes[node_index]->fake_joint_parent;
+ }
- if (node->joints.size()) {
- Skeleton *sk = (Skeleton *)node->godot_nodes[n];
- String path = ap->get_parent()->get_path_to(sk);
- String bone = sk->get_bone_name(node->joints[n].godot_bone_index);
- node_path = path + ":" + bone;
- } else {
- node_path = ap->get_parent()->get_path_to(node->godot_nodes[n]);
- }
+ const GLTFNode *node = state.nodes[E->key()];
- for (int i = 0; i < track.rotation_track.times.size(); i++) {
- length = MAX(length, track.rotation_track.times[i]);
- }
- for (int i = 0; i < track.translation_track.times.size(); i++) {
- length = MAX(length, track.translation_track.times[i]);
+ if (node->skeleton >= 0) {
+ const Skeleton *sk = Object::cast_to<Skeleton>(state.scene_nodes.find(node_index)->get());
+ ERR_FAIL_COND(sk == nullptr);
+
+ const String path = ap->get_parent()->get_path_to(sk);
+ const String bone = node->name;
+ node_path = path + ":" + bone;
+ } else {
+ node_path = ap->get_parent()->get_path_to(state.scene_nodes.find(node_index)->get());
+ }
+
+ for (int i = 0; i < track.rotation_track.times.size(); i++) {
+ length = MAX(length, track.rotation_track.times[i]);
+ }
+ for (int i = 0; i < track.translation_track.times.size(); i++) {
+ length = MAX(length, track.translation_track.times[i]);
+ }
+ for (int i = 0; i < track.scale_track.times.size(); i++) {
+ length = MAX(length, track.scale_track.times[i]);
+ }
+
+ for (int i = 0; i < track.weight_tracks.size(); i++) {
+ for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
+ length = MAX(length, track.weight_tracks[i].times[j]);
}
- for (int i = 0; i < track.scale_track.times.size(); i++) {
- length = MAX(length, track.scale_track.times[i]);
+ }
+
+ if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) {
+ //make transform track
+ int track_idx = animation->get_track_count();
+ animation->add_track(Animation::TYPE_TRANSFORM);
+ animation->track_set_path(track_idx, node_path);
+ //first determine animation length
+
+ const float increment = 1.0 / float(bake_fps);
+ float time = 0.0;
+
+ Vector3 base_pos;
+ Quat base_rot;
+ Vector3 base_scale = Vector3(1, 1, 1);
+
+ if (!track.rotation_track.values.size()) {
+ base_rot = state.nodes[E->key()]->rotation.normalized();
}
- for (int i = 0; i < track.weight_tracks.size(); i++) {
- for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
- length = MAX(length, track.weight_tracks[i].times[j]);
- }
+ if (!track.translation_track.values.size()) {
+ base_pos = state.nodes[E->key()]->translation;
}
- if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) {
- //make transform track
- int track_idx = animation->get_track_count();
- animation->add_track(Animation::TYPE_TRANSFORM);
- animation->track_set_path(track_idx, node_path);
- //first determine animation length
+ if (!track.scale_track.values.size()) {
+ base_scale = state.nodes[E->key()]->scale;
+ }
- float increment = 1.0 / float(bake_fps);
- float time = 0.0;
+ bool last = false;
+ while (true) {
- Vector3 base_pos;
- Quat base_rot;
- Vector3 base_scale = Vector3(1, 1, 1);
+ Vector3 pos = base_pos;
+ Quat rot = base_rot;
+ Vector3 scale = base_scale;
- if (!track.rotation_track.values.size()) {
- base_rot = state.nodes[E->key()]->rotation.normalized();
+ if (track.translation_track.times.size()) {
+ pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
}
- if (!track.translation_track.values.size()) {
- base_pos = state.nodes[E->key()]->translation;
+ if (track.rotation_track.times.size()) {
+ rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
}
- if (!track.scale_track.values.size()) {
- base_scale = state.nodes[E->key()]->scale;
+ if (track.scale_track.times.size()) {
+ scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
}
- bool last = false;
- while (true) {
-
- Vector3 pos = base_pos;
- Quat rot = base_rot;
- Vector3 scale = base_scale;
-
- if (track.translation_track.times.size()) {
+ if (node->skeleton >= 0) {
- pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
- }
-
- if (track.rotation_track.times.size()) {
-
- rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
- }
+ Transform xform;
+ xform.basis.set_quat_scale(rot, scale);
+ xform.origin = pos;
- if (track.scale_track.times.size()) {
+ const Skeleton *skeleton = state.skeletons[node->skeleton].godot_skeleton;
+ const int bone_idx = skeleton->find_bone(node->name);
+ xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform;
- scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
- }
+ rot = xform.basis.get_rotation_quat();
+ rot.normalize();
+ scale = xform.basis.get_scale();
+ pos = xform.origin;
+ }
- if (node->joints.size()) {
+ animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
- Transform xform;
- //xform.basis = Basis(rot);
- //xform.basis.scale(scale);
- xform.basis.set_quat_scale(rot, scale);
- xform.origin = pos;
+ if (last) {
+ break;
+ }
+ time += increment;
+ if (time >= length) {
+ last = true;
+ time = length;
+ }
+ }
+ }
- Skeleton *skeleton = skeletons[node->joints[n].skin];
- int bone = node->joints[n].godot_bone_index;
- xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
+ for (int i = 0; i < track.weight_tracks.size(); i++) {
+ ERR_CONTINUE(node->mesh < 0 || node->mesh >= state.meshes.size());
+ const GLTFMesh &mesh = state.meshes[node->mesh];
+ const String prop = "blend_shapes/" + mesh.mesh->get_blend_shape_name(i);
- rot = xform.basis.get_rotation_quat();
- rot.normalize();
- scale = xform.basis.get_scale();
- pos = xform.origin;
- }
+ const String blend_path = String(node_path) + ":" + prop;
- animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
+ const int track_idx = animation->get_track_count();
+ animation->add_track(Animation::TYPE_VALUE);
+ animation->track_set_path(track_idx, blend_path);
+ // Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
+ // the other modes have to be baked.
+ GLTFAnimation::Interpolation gltf_interp = track.weight_tracks[i].interpolation;
+ if (gltf_interp == GLTFAnimation::INTERP_LINEAR || gltf_interp == GLTFAnimation::INTERP_STEP) {
+ animation->track_set_interpolation_type(track_idx, gltf_interp == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_LINEAR);
+ for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
+ const float t = track.weight_tracks[i].times[j];
+ const float w = track.weight_tracks[i].values[j];
+ animation->track_insert_key(track_idx, t, w);
+ }
+ } else {
+ // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
+ const float increment = 1.0 / float(bake_fps);
+ float time = 0.0;
+ bool last = false;
+ while (true) {
+ _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
if (last) {
break;
}
@@ -2077,86 +2850,54 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
}
}
}
-
- for (int i = 0; i < track.weight_tracks.size(); i++) {
- ERR_CONTINUE(node->mesh < 0 || node->mesh >= state.meshes.size());
- const GLTFMesh &mesh = state.meshes[node->mesh];
- String prop = "blend_shapes/" + mesh.mesh->get_blend_shape_name(i);
- node_path = String(node_path) + ":" + prop;
-
- int track_idx = animation->get_track_count();
- animation->add_track(Animation::TYPE_VALUE);
- animation->track_set_path(track_idx, node_path);
-
- // Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
- // the other modes have to be baked.
- GLTFAnimation::Interpolation gltf_interp = track.weight_tracks[i].interpolation;
- if (gltf_interp == GLTFAnimation::INTERP_LINEAR || gltf_interp == GLTFAnimation::INTERP_STEP) {
- animation->track_set_interpolation_type(track_idx, gltf_interp == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_LINEAR);
- for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
- float t = track.weight_tracks[i].times[j];
- float w = track.weight_tracks[i].values[j];
- animation->track_insert_key(track_idx, t, w);
- }
- } else {
- // CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
- float increment = 1.0 / float(bake_fps);
- float time = 0.0;
- bool last = false;
- while (true) {
- _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
- if (last) {
- break;
- }
- time += increment;
- if (time >= length) {
- last = true;
- time = length;
- }
- }
- }
- }
}
}
+
animation->set_length(length);
ap->add_animation(name, animation);
}
-Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_fps) {
+void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial *scene_root) {
+ for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); ++node_i) {
+ const GLTFNode *node = state.nodes[node_i];
- Spatial *root = memnew(Spatial);
- root->set_name(state.scene_name);
- //generate skeletons
- Vector<Skeleton *> skeletons;
- for (int i = 0; i < state.skins.size(); i++) {
- Skeleton *s = memnew(Skeleton);
- s->set_use_bones_in_world_transform(false); //GLTF does not need this since meshes are always local
- String name = state.skins[i].name;
- if (name == "") {
- name = _gen_unique_name(state, "Skeleton");
- }
- for (int j = 0; j < state.skins[i].bones.size(); j++) {
- s->add_bone(state.nodes[state.skins[i].bones[j].node]->name);
- s->set_bone_rest(j, state.skins[i].bones[j].inverse_bind.affine_inverse());
- }
- s->set_name(name);
- root->add_child(s);
- s->set_owner(root);
- skeletons.push_back(s);
- }
- for (int i = 0; i < state.root_nodes.size(); i++) {
- if (state.nodes[state.root_nodes[i]]->joints.size()) {
- _generate_bone(state, state.root_nodes[i], skeletons, root);
- } else {
- _generate_node(state, state.root_nodes[i], root, root, skeletons);
+ if (node->skin >= 0 && node->mesh >= 0) {
+ const GLTFSkinIndex skin_i = node->skin;
+
+ Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
+ MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
+ ERR_FAIL_COND(mi == nullptr);
+
+ const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
+ const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i];
+ Skeleton *skeleton = gltf_skeleton.godot_skeleton;
+ ERR_FAIL_COND(skeleton == nullptr);
+
+ mi->get_parent()->remove_child(mi);
+ skeleton->add_child(mi);
+ mi->set_owner(scene_root);
+
+ mi->set_skin(state.skins[skin_i].godot_skin);
+ mi->set_skeleton_path(mi->get_path_to(skeleton));
+ mi->set_transform(Transform());
}
}
+}
- for (int i = 0; i < skeletons.size(); i++) {
- skeletons[i]->localize_rests();
+Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_bake_fps) {
+
+ Spatial *root = memnew(Spatial);
+
+ // scene_name is already unique
+ root->set_name(state.scene_name);
+
+ for (int i = 0; i < state.root_nodes.size(); ++i) {
+ _generate_scene_node(state, root, root, state.root_nodes[i]);
}
+ _process_mesh_instances(state, root);
+
if (state.animations.size()) {
AnimationPlayer *ap = memnew(AnimationPlayer);
ap->set_name("AnimationPlayer");
@@ -2164,7 +2905,7 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
ap->set_owner(root);
for (int i = 0; i < state.animations.size(); i++) {
- _import_animation(state, ap, i, p_bake_fps, skeletons);
+ _import_animation(state, ap, i, p_bake_fps);
}
}
@@ -2239,30 +2980,45 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
if (err != OK)
return NULL;
- /* STEP 8 PARSE MESHES (we have enough info now) */
- err = _parse_meshes(state);
+ /* STEP 9 PARSE SKINS */
+ err = _parse_skins(state);
if (err != OK)
return NULL;
- /* STEP 9 PARSE SKINS */
- err = _parse_skins(state);
+ /* STEP 10 DETERMINE SKELETONS */
+ err = _determine_skeletons(state);
+ if (err != OK)
+ return NULL;
+
+ /* STEP 11 CREATE SKELETONS */
+ err = _create_skeletons(state);
+ if (err != OK)
+ return NULL;
+
+ /* STEP 12 CREATE SKINS */
+ err = _create_skins(state);
+ if (err != OK)
+ return NULL;
+
+ /* STEP 13 PARSE MESHES (we have enough info now) */
+ err = _parse_meshes(state);
if (err != OK)
return NULL;
- /* STEP 10 PARSE CAMERAS */
+ /* STEP 14 PARSE CAMERAS */
err = _parse_cameras(state);
if (err != OK)
return NULL;
- /* STEP 11 PARSE ANIMATIONS */
+ /* STEP 15 PARSE ANIMATIONS */
err = _parse_animations(state);
if (err != OK)
return NULL;
- /* STEP 12 ASSIGN SCENE NAMES */
+ /* STEP 16 ASSIGN SCENE NAMES */
_assign_scene_names(state);
- /* STEP 13 MAKE SCENE! */
+ /* STEP 17 MAKE SCENE! */
Spatial *scene = _generate_scene(state, p_bake_fps);
return scene;
diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h
index ebf20e122a..6021bf10c8 100644
--- a/editor/import/editor_scene_importer_gltf.h
+++ b/editor/import/editor_scene_importer_gltf.h
@@ -36,11 +36,26 @@
#include "scene/3d/spatial.h"
class AnimationPlayer;
+class BoneAttachment;
+class MeshInstance;
class EditorSceneImporterGLTF : public EditorSceneImporter {
GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter);
+ typedef int GLTFAccessorIndex;
+ typedef int GLTFAnimationIndex;
+ typedef int GLTFBufferIndex;
+ typedef int GLTFBufferViewIndex;
+ typedef int GLTFCameraIndex;
+ typedef int GLTFImageIndex;
+ typedef int GLTFMaterialIndex;
+ typedef int GLTFMeshIndex;
+ typedef int GLTFNodeIndex;
+ typedef int GLTFSkeletonIndex;
+ typedef int GLTFSkinIndex;
+ typedef int GLTFTextureIndex;
+
enum {
ARRAY_BUFFER = 34962,
ELEMENT_ARRAY_BUFFER = 34963,
@@ -61,8 +76,8 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
};
- String _get_component_type_name(uint32_t p_component);
- int _get_component_type_size(int component_type);
+ String _get_component_type_name(const uint32_t p_component);
+ int _get_component_type_size(const int component_type);
enum GLTFType {
TYPE_SCALAR,
@@ -74,60 +89,48 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
TYPE_MAT4,
};
- String _get_type_name(GLTFType p_component);
+ String _get_type_name(const GLTFType p_component);
struct GLTFNode {
+
//matrices need to be transformed to this
- int parent;
+ GLTFNodeIndex parent;
+ int height;
Transform xform;
String name;
- //Node *godot_node;
- //int godot_bone_index;
-
- int mesh;
- int camera;
- int skin;
- //int skeleton_skin;
- //int child_of_skeleton; // put as children of skeleton
- //Vector<int> skeleton_children; //skeleton put as children of this
-
- struct Joint {
- int skin;
- int bone;
- int godot_bone_index;
-
- Joint() {
- skin = -1;
- bone = -1;
- godot_bone_index = -1;
- }
- };
- Vector<Joint> joints;
+ GLTFMeshIndex mesh;
+ GLTFCameraIndex camera;
+ GLTFSkinIndex skin;
+
+ GLTFSkeletonIndex skeleton;
+ bool joint;
- //keep them for animation
Vector3 translation;
Quat rotation;
Vector3 scale;
Vector<int> children;
- Vector<Node *> godot_nodes;
+
+ GLTFNodeIndex fake_joint_parent;
GLTFNode() :
parent(-1),
+ height(-1),
mesh(-1),
camera(-1),
skin(-1),
- //skeleton_skin(-1),
- //child_of_skeleton(-1),
- scale(Vector3(1, 1, 1)) {
- }
+ skeleton(-1),
+ joint(false),
+ translation(0, 0, 0),
+ scale(Vector3(1, 1, 1)),
+ fake_joint_parent(-1) {}
};
struct GLTFBufferView {
- int buffer;
+ GLTFBufferIndex buffer;
int byte_offset;
int byte_length;
int byte_stride;
@@ -135,7 +138,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
//matrices need to be transformed to this
GLTFBufferView() :
- buffer(0),
+ buffer(-1),
byte_offset(0),
byte_length(0),
byte_stride(0),
@@ -145,7 +148,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
struct GLTFAccessor {
- int buffer_view;
+ GLTFBufferViewIndex buffer_view;
int byte_offset;
int component_type;
bool normalized;
@@ -160,8 +163,6 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
int sparse_values_buffer_view;
int sparse_values_byte_offset;
- //matrices need to be transformed to this
-
GLTFAccessor() {
buffer_view = 0;
byte_offset = 0;
@@ -176,27 +177,67 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
}
};
struct GLTFTexture {
- int src_image;
+ GLTFImageIndex src_image;
};
- struct GLTFSkin {
+ struct GLTFSkeleton {
+ // The *synthesized* skeletons joints
+ Vector<GLTFNodeIndex> joints;
- String name;
- struct Bone {
- Transform inverse_bind;
- int node;
- };
+ // The roots of the skeleton. If there are multiple, each root must have the same parent
+ // (ie roots are siblings)
+ Vector<GLTFNodeIndex> roots;
- int skeleton;
- Vector<Bone> bones;
+ // The created Skeleton for the scene
+ Skeleton *godot_skeleton;
- //matrices need to be transformed to this
+ // Set of unique bone names for the skeleton
+ Set<String> unique_names;
- GLTFSkin() {
- skeleton = -1;
+ GLTFSkeleton() :
+ godot_skeleton(nullptr) {
}
};
+ struct GLTFSkin {
+ String name;
+
+ // The "skeleton" property defined in the gltf spec. -1 = Scene Root
+ GLTFNodeIndex skin_root;
+
+ Vector<GLTFNodeIndex> joints_original;
+ Vector<Transform> inverse_binds;
+
+ // Note: joints + non_joints should form a complete subtree, or subtrees with a common parent
+
+ // All nodes that are skins that are caught in-between the original joints
+ // (inclusive of joints_original)
+ Vector<GLTFNodeIndex> joints;
+
+ // All Nodes that are caught in-between skin joint nodes, and are not defined
+ // as joints by any skin
+ Vector<GLTFNodeIndex> non_joints;
+
+ // The roots of the skin. In the case of multiple roots, their parent *must*
+ // be the same (the roots must be siblings)
+ Vector<GLTFNodeIndex> roots;
+
+ // The GLTF Skeleton this Skin points to (after we determine skeletons)
+ GLTFSkeletonIndex skeleton;
+
+ // A mapping from the joint indices (in the order of joints_original) to the
+ // Godot Skeleton's bone_indices
+ Map<int, int> joint_i_to_bone_i;
+
+ // The Actual Skin that will be created as a mapping between the IBM's of this skin
+ // to the generated skeleton for the mesh instances.
+ Ref<Skin> godot_skin;
+
+ GLTFSkin() :
+ skin_root(-1),
+ skeleton(-1) {}
+ };
+
struct GLTFMesh {
Ref<ArrayMesh> mesh;
Vector<float> blend_weights;
@@ -272,11 +313,10 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Set<String> unique_names;
+ Vector<GLTFSkeleton> skeletons;
Vector<GLTFAnimation> animations;
- Map<int, Vector<int> > skeleton_nodes;
-
- //Map<int, Vector<int> > skin_users; //cache skin users
+ Map<GLTFNodeIndex, Node *> scene_nodes;
~GLTFState() {
for (int i = 0; i < nodes.size(); i++) {
@@ -285,37 +325,38 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
}
};
+ String _sanitize_scene_name(const String &name);
String _gen_unique_name(GLTFState &state, const String &p_name);
- Ref<Texture> _get_texture(GLTFState &state, int p_texture);
+ String _sanitize_bone_name(const String &name);
+ String _gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name);
+
+ Ref<Texture> _get_texture(GLTFState &state, const GLTFTextureIndex p_texture);
Error _parse_json(const String &p_path, GLTFState &state);
Error _parse_glb(const String &p_path, GLTFState &state);
Error _parse_scenes(GLTFState &state);
Error _parse_nodes(GLTFState &state);
+
+ void _compute_node_heights(GLTFState &state);
+
Error _parse_buffers(GLTFState &state, const String &p_base_path);
Error _parse_buffer_views(GLTFState &state);
GLTFType _get_type_from_str(const String &p_string);
Error _parse_accessors(GLTFState &state);
- Error _decode_buffer_view(GLTFState &state, int p_buffer_view, double *dst, int skip_every, int skip_bytes, int element_size, int count, GLTFType type, int component_count, int component_type, int component_size, bool normalized, int byte_offset, bool for_vertex);
- Vector<double> _decode_accessor(GLTFState &state, int p_accessor, bool p_for_vertex);
- PoolVector<float> _decode_accessor_as_floats(GLTFState &state, int p_accessor, bool p_for_vertex);
- PoolVector<int> _decode_accessor_as_ints(GLTFState &state, int p_accessor, bool p_for_vertex);
- PoolVector<Vector2> _decode_accessor_as_vec2(GLTFState &state, int p_accessor, bool p_for_vertex);
- PoolVector<Vector3> _decode_accessor_as_vec3(GLTFState &state, int p_accessor, bool p_for_vertex);
- PoolVector<Color> _decode_accessor_as_color(GLTFState &state, int p_accessor, bool p_for_vertex);
- Vector<Quat> _decode_accessor_as_quat(GLTFState &state, int p_accessor, bool p_for_vertex);
- Vector<Transform2D> _decode_accessor_as_xform2d(GLTFState &state, int p_accessor, bool p_for_vertex);
- Vector<Basis> _decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex);
- Vector<Transform> _decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex);
-
- void _reparent_skeleton(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node);
- void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, Node *p_parent_node);
- void _generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons);
- void _import_animation(GLTFState &state, AnimationPlayer *ap, int index, int bake_fps, Vector<Skeleton *> skeletons);
-
- Spatial *_generate_scene(GLTFState &state, int p_bake_fps);
+ Error _decode_buffer_view(GLTFState &state, double *dst, const GLTFBufferViewIndex p_buffer_view, const int skip_every, const int skip_bytes, const int element_size, const int count, const GLTFType type, const int component_count, const int component_type, const int component_size, const bool normalized, const int byte_offset, const bool for_vertex);
+
+ Vector<double> _decode_accessor(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ PoolVector<float> _decode_accessor_as_floats(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ PoolVector<int> _decode_accessor_as_ints(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ PoolVector<Vector2> _decode_accessor_as_vec2(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ PoolVector<Vector3> _decode_accessor_as_vec3(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ PoolVector<Color> _decode_accessor_as_color(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ Vector<Quat> _decode_accessor_as_quat(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ Vector<Transform2D> _decode_accessor_as_xform2d(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ Vector<Basis> _decode_accessor_as_basis(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
+ Vector<Transform> _decode_accessor_as_xform(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex);
Error _parse_meshes(GLTFState &state);
Error _parse_images(GLTFState &state, const String &p_base_path);
@@ -323,16 +364,46 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Error _parse_materials(GLTFState &state);
+ GLTFNodeIndex _find_highest_node(GLTFState &state, const Vector<GLTFNodeIndex> &subset);
+
+ bool _capture_nodes_in_skin(GLTFState &state, GLTFSkin &skin, const GLTFNodeIndex node_index);
+ void _capture_nodes_for_multirooted_skin(GLTFState &state, GLTFSkin &skin);
+ Error _expand_skin(GLTFState &state, GLTFSkin &skin);
+ Error _verify_skin(GLTFState &state, GLTFSkin &skin);
Error _parse_skins(GLTFState &state);
+ Error _determine_skeletons(GLTFState &state);
+ Error _reparent_non_joint_skeleton_subtrees(GLTFState &state, GLTFSkeleton &skeleton, const Vector<GLTFNodeIndex> &non_joints);
+ Error _reparent_to_fake_joint(GLTFState &state, GLTFSkeleton &skeleton, const GLTFNodeIndex node_index);
+ Error _determine_skeleton_roots(GLTFState &state, const GLTFSkeletonIndex skel_i);
+
+ Error _create_skeletons(GLTFState &state);
+ Error _map_skin_joints_indices_to_skeleton_bone_indices(GLTFState &state);
+
+ Error _create_skins(GLTFState &state);
+ bool _skins_are_same(const Ref<Skin> &skin_a, const Ref<Skin> &skin_b);
+ void _remove_duplicate_skins(GLTFState &state);
+
Error _parse_cameras(GLTFState &state);
Error _parse_animations(GLTFState &state);
+ BoneAttachment *_generate_bone_attachment(GLTFState &state, Skeleton *skeleton, const GLTFNodeIndex node_index);
+ MeshInstance *_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+ Camera *_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+ Spatial *_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+
+ void _generate_scene_node(GLTFState &state, Node *scene_parent, Spatial *scene_root, const GLTFNodeIndex node_index);
+ Spatial *_generate_scene(GLTFState &state, const int p_bake_fps);
+
+ void _process_mesh_instances(GLTFState &state, Spatial *scene_root);
+
void _assign_scene_names(GLTFState &state);
template <class T>
- T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, GLTFAnimation::Interpolation p_interp);
+ T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp);
+
+ void _import_animation(GLTFState &state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps);
public:
virtual uint32_t get_import_flags() const;
diff --git a/editor/import/resource_importer_csv.cpp b/editor/import/resource_importer_csv.cpp
new file mode 100644
index 0000000000..64b5309cab
--- /dev/null
+++ b/editor/import/resource_importer_csv.cpp
@@ -0,0 +1,80 @@
+/*************************************************************************/
+/* resource_importer_csv.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 "resource_importer_csv.h"
+
+#include "core/io/resource_saver.h"
+#include "core/os/file_access.h"
+
+String ResourceImporterCSV::get_importer_name() const {
+
+ return "csv";
+}
+
+String ResourceImporterCSV::get_visible_name() const {
+
+ return "CSV";
+}
+void ResourceImporterCSV::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("csv");
+}
+
+String ResourceImporterCSV::get_save_extension() const {
+ return ""; //does not save a single resource
+}
+
+String ResourceImporterCSV::get_resource_type() const {
+
+ return "TextFile";
+}
+
+bool ResourceImporterCSV::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterCSV::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterCSV::get_preset_name(int p_idx) const {
+
+ return "";
+}
+
+void ResourceImporterCSV::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+}
+
+Error ResourceImporterCSV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
+ return OK;
+}
+
+ResourceImporterCSV::ResourceImporterCSV() {
+}
diff --git a/editor/import/resource_importer_csv.h b/editor/import/resource_importer_csv.h
new file mode 100644
index 0000000000..7d06bdb188
--- /dev/null
+++ b/editor/import/resource_importer_csv.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* resource_importer_csv.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 RESOURCEIMPORTERCSV_H
+#define RESOURCEIMPORTERCSV_H
+
+#include "core/io/resource_importer.h"
+
+class ResourceImporterCSV : public ResourceImporter {
+ GDCLASS(ResourceImporterCSV, ResourceImporter);
+
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+
+ ResourceImporterCSV();
+};
+
+#endif // RESOURCEIMPORTERCSV_H
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index cfcdbc8de4..301422a25a 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -101,8 +101,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
for (int i = 1; i < line.size(); i++) {
String locale = line[i];
- ERR_EXPLAIN("Error importing CSV translation: '" + locale + "' is not a valid locale");
- ERR_FAIL_COND_V(!TranslationServer::is_locale_valid(locale), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V_MSG(!TranslationServer::is_locale_valid(locale), ERR_PARSE_ERROR, "Error importing CSV translation: '" + locale + "' is not a valid locale.");
locales.push_back(locale);
Ref<Translation> translation;
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 868f67fd77..9061c92f6e 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -45,8 +45,7 @@ uint32_t EditorOBJImporter::get_import_flags() const {
static Error _parse_material_library(const String &p_path, Map<String, Ref<SpatialMaterial> > &material_map, List<String> *r_missing_deps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
- ERR_EXPLAIN(vformat("Couldn't open MTL file '%s', it may not exist or not be readable.", p_path));
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open MTL file '%s', it may not exist or not be readable.", p_path));
Ref<SpatialMaterial> current;
String current_name;
@@ -207,8 +206,7 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, List<String> *r_missing_deps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
- ERR_EXPLAIN(vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
Ref<ArrayMesh> mesh;
mesh.instance();
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index a8197ec2a2..b111750992 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -435,6 +435,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
Object::cast_to<Spatial>(sb)->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
p_node->replace_by(sb);
memdelete(p_node);
+ p_node = NULL;
CollisionShape *colshape = memnew(CollisionShape);
if (empty_draw_type == "CUBE") {
BoxShape *boxShape = memnew(BoxShape);
@@ -893,7 +894,6 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
keep.insert(F->get());
}
_filter_anim_tracks(anim->get_animation(name), keep);
- } else {
}
}
}
@@ -960,7 +960,7 @@ void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Trans
}
}
-void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
+void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
List<PropertyInfo> pi;
@@ -982,7 +982,14 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
anim->track_set_imported(i, true);
}
- String ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim");
+ String ext_name;
+
+ if (p_animations_as_text) {
+ ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".tres");
+ } else {
+ ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim");
+ }
+
if (FileAccess::exists(ext_name) && p_keep_animations) {
//try to keep custom animation tracks
Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true);
@@ -1017,7 +1024,14 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_materials.has(mat)) {
- String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material");
+ String ext_name;
+
+ if (p_materials_as_text) {
+ ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".tres");
+ } else {
+ ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material");
+ }
+
if (p_keep_materials && FileAccess::exists(ext_name)) {
//if exists, use it
p_materials[mat] = ResourceLoader::load(ext_name);
@@ -1045,7 +1059,13 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_meshes.has(mesh)) {
//meshes are always overwritten, keeping them is not practical
- String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh");
+ String ext_name;
+
+ if (p_meshes_as_text) {
+ ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".tres");
+ } else {
+ ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh");
+ }
ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH);
p_meshes[mesh] = ResourceLoader::load(ext_name);
@@ -1067,9 +1087,14 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
continue;
if (!p_materials.has(mat)) {
+ String ext_name;
+
+ if (p_materials_as_text) {
+ ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".tres");
+ } else {
+ ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material");
+ }
- String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material");
- ;
if (p_keep_materials && FileAccess::exists(ext_name)) {
//if exists, use it
p_materials[mat] = ResourceLoader::load(ext_name);
@@ -1086,7 +1111,15 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
//re-save the mesh since a material is now assigned
if (p_make_meshes) {
- String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh");
+
+ String ext_name;
+
+ if (p_meshes_as_text) {
+ ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".tres");
+ } else {
+ ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh");
+ }
+
ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH);
p_meshes[mesh] = ResourceLoader::load(ext_name);
}
@@ -1105,7 +1138,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
for (int i = 0; i < p_node->get_child_count(); i++) {
- _make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_keep_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes);
+ _make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_animations_as_text, p_keep_animations, p_make_materials, p_materials_as_text, p_keep_materials, p_make_meshes, p_meshes_as_text, p_animations, p_materials, p_meshes);
}
}
@@ -1134,18 +1167,18 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), (meshes_out || materials_out) ? 1 : 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Built-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.material),Files (.tres)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_on_reimport"), materials_out));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? 1 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.mesh),Files (.tres)"), meshes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable,Gen Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), animations_out));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.anim),Files (.tres)"), animations_out));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/keep_custom_tracks"), animations_out));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05));
@@ -1367,10 +1400,13 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
_filter_tracks(scene, animation_filter);
}
- bool external_animations = int(p_options["animation/storage"]) == 1;
+ bool external_animations = int(p_options["animation/storage"]) == 1 || int(p_options["animation/storage"]) == 2;
+ bool external_animations_as_text = int(p_options["animation/storage"]) == 2;
bool keep_custom_tracks = p_options["animation/keep_custom_tracks"];
- bool external_materials = p_options["materials/storage"];
- bool external_meshes = p_options["meshes/storage"];
+ bool external_materials = int(p_options["materials/storage"]) == 1 || int(p_options["materials/storage"]) == 2;
+ bool external_materials_as_text = int(p_options["materials/storage"]) == 2;
+ bool external_meshes = int(p_options["meshes/storage"]) == 1 || int(p_options["meshes/storage"]) == 2;
+ bool external_meshes_as_text = int(p_options["meshes/storage"]) == 2;
bool external_scenes = int(p_options["nodes/storage"]) == 1;
String base_path = p_source_file.get_base_dir();
@@ -1425,7 +1461,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
bool keep_materials = bool(p_options["materials/keep_on_reimport"]);
- _make_external_resources(scene, base_path, external_animations, keep_custom_tracks, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map);
+ _make_external_resources(scene, base_path, external_animations, external_animations_as_text, keep_custom_tracks, external_materials, external_materials_as_text, keep_materials, external_meshes, external_meshes_as_text, anim_map, mat_map, mesh_map);
}
progress.step(TTR("Running Custom Script..."), 2);
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 498e0f6fb8..ef9a77917f 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -144,7 +144,7 @@ public:
void _find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes);
- void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
+ void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape> > > &collision_map, LightBakeMode p_light_bake_mode);
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index e728dbac31..f1de71e25e 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -83,8 +83,8 @@ void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/mono"), 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));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/trim"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/normalize"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/loop"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Disabled,RAM (Ima-ADPCM)"), 0));
}
@@ -123,8 +123,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
file->close();
memdelete(file);
- ERR_EXPLAIN("Not a WAV file (no WAVE RIFF Header)");
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+ ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Not a WAV file (no WAVE RIFF header).");
}
int format_bits = 0;
@@ -166,16 +165,14 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
if (compression_code != 1 && compression_code != 3) {
file->close();
memdelete(file);
- ERR_EXPLAIN("Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead.");
- ERR_FAIL_V(ERR_INVALID_DATA);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead.");
}
format_channels = file->get_16();
if (format_channels != 1 && format_channels != 2) {
file->close();
memdelete(file);
- ERR_EXPLAIN("Format not supported for WAVE file (not stereo or mono).");
- ERR_FAIL_V(ERR_INVALID_DATA);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Format not supported for WAVE file (not stereo or mono).");
}
format_freq = file->get_32(); //sampling rate
@@ -187,8 +184,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
if (format_bits % 8 || format_bits == 0) {
file->close();
memdelete(file);
- ERR_EXPLAIN("Invalid amount of bits in the sample (should be one of 8, 16, 24 or 32).");
- ERR_FAIL_V(ERR_INVALID_DATA);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Invalid amount of bits in the sample (should be one of 8, 16, 24 or 32).");
}
/* Don't need anything else, continue */
@@ -206,6 +202,11 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
frames = chunksize;
+ if (format_channels == 0) {
+ file->close();
+ memdelete(file);
+ ERR_FAIL_COND_V(format_channels == 0, ERR_INVALID_DATA);
+ }
frames /= format_channels;
frames /= (format_bits >> 3);
@@ -253,8 +254,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
if (file->eof_reached()) {
file->close();
memdelete(file);
- ERR_EXPLAIN("Premature end of file.");
- ERR_FAIL_V(ERR_FILE_CORRUPT);
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Premature end of file.");
}
}
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 6918fe7977..1d72e370b3 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -132,6 +132,7 @@ void ImportDock::set_edit_path(const String &p_path) {
params->paths.push_back(p_path);
import->set_disabled(false);
import_as->set_disabled(false);
+ preset->set_disabled(false);
imported->set_text(p_path.get_file());
}
@@ -287,6 +288,7 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
params->paths = p_paths;
import->set_disabled(false);
import_as->set_disabled(false);
+ preset->set_disabled(false);
imported->set_text(itos(p_paths.size()) + TTR(" Files"));
}
@@ -367,6 +369,7 @@ void ImportDock::clear() {
import->set_disabled(true);
import_as->clear();
import_as->set_disabled(true);
+ preset->set_disabled(true);
params->values.clear();
params->properties.clear();
params->update();
@@ -528,11 +531,13 @@ ImportDock::ImportDock() {
HBoxContainer *hb = memnew(HBoxContainer);
add_margin_child(TTR("Import As:"), hb);
import_as = memnew(OptionButton);
+ import_as->set_disabled(true);
import_as->connect("item_selected", this, "_importer_selected");
hb->add_child(import_as);
import_as->set_h_size_flags(SIZE_EXPAND_FILL);
preset = memnew(MenuButton);
- preset->set_text(TTR("Preset..."));
+ preset->set_text(TTR("Preset"));
+ preset->set_disabled(true);
preset->get_popup()->connect("index_pressed", this, "_preset_selected");
hb->add_child(preset);
@@ -545,6 +550,7 @@ ImportDock::ImportDock() {
add_child(hb);
import = memnew(Button);
import->set_text(TTR("Reimport"));
+ import->set_disabled(true);
import->connect("pressed", this, "_reimport_attempt");
hb->add_spacer();
hb->add_child(import);
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 8a0812973f..e4411e436a 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -408,6 +408,11 @@ void InspectorDock::update(Object *p_object) {
warning->hide();
search->set_editable(false);
+ editor_path->set_disabled(true);
+ editor_path->set_text("");
+ editor_path->set_tooltip("");
+ editor_path->set_icon(NULL);
+
return;
}
@@ -416,6 +421,7 @@ void InspectorDock::update(Object *p_object) {
object_menu->set_disabled(false);
search->set_editable(true);
+ editor_path->set_disabled(false);
resource_save_button->set_disabled(!is_resource);
PopupMenu *p = object_menu->get_popup();
diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp
index 6af7e4bd00..85e47594a8 100644
--- a/editor/multi_node_edit.cpp
+++ b/editor/multi_node_edit.cpp
@@ -152,7 +152,9 @@ void MultiNodeEdit::_get_property_list(List<PropertyInfo> *p_list) const {
datas.push_back(usage.getptr(F->get().name));
}
- usage[F->get().name].uses++;
+ // Make sure only properties with the same exact PropertyInfo data will appear
+ if (usage[F->get().name].info == F->get())
+ usage[F->get().name].uses++;
}
nc++;
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 1c0151ed0a..d6df3bd369 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -56,10 +56,7 @@ void NodeDock::_bind_methods() {
void NodeDock::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- connections_button->set_icon(get_icon("Signals", "EditorIcons"));
- groups_button->set_icon(get_icon("Groups", "EditorIcons"));
- } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
connections_button->set_icon(get_icon("Signals", "EditorIcons"));
groups_button->set_icon(get_icon("Groups", "EditorIcons"));
}
@@ -131,7 +128,7 @@ NodeDock::NodeDock() {
groups->hide();
select_a_node = memnew(Label);
- select_a_node->set_text(TTR("Select a Node to edit Signals and Groups."));
+ select_a_node->set_text(TTR("Select a single node to edit its signals and groups."));
select_a_node->set_v_size_flags(SIZE_EXPAND_FILL);
select_a_node->set_valign(Label::VALIGN_CENTER);
select_a_node->set_align(Label::ALIGN_CENTER);
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 12bf544357..23056d25c0 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -130,7 +130,8 @@ void PluginConfigDialog::_notification(int p_what) {
void PluginConfigDialog::config(const String &p_config_path) {
if (p_config_path.length()) {
Ref<ConfigFile> cf = memnew(ConfigFile);
- cf->load(p_config_path);
+ Error err = cf->load(p_config_path);
+ ERR_FAIL_COND(err != OK);
name_edit->set_text(cf->get_value("plugin", "name", ""));
subfolder_edit->set_text(p_config_path.get_base_dir().get_basename().get_file());
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 2931678c80..7f023af848 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;
@@ -573,7 +571,8 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
return;
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
- const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
+ // All polygon points are sharp, so use the sharp handle icon
+ const Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
const Vertex active_point = get_active_point();
const int n_polygons = _get_polygon_count();
@@ -612,7 +611,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 +635,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/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 97244fa4e9..a00cdd0cf6 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -36,9 +36,6 @@
#include "scene/2d/polygon_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class AbstractPolygon2DEditor : public HBoxContainer {
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 74186791e1..850a6201bb 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 65282ccfc2..235c204265 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -249,6 +249,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
node->add_color_override("title_color", c);
c.a = 0.7;
node->add_color_override("close_color", c);
+ node->add_color_override("resizer_color", c);
}
}
@@ -878,9 +879,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_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index cb40159a40..77b57a50d0 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 5163b372b2..d7451849a1 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -32,12 +32,13 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/animation_track_editor.h"
#include "editor/editor_settings.h"
-// For onion skinning
+// For onion skinning.
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "scene/main/viewport.h"
@@ -293,10 +294,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
}
}
frame->set_max(anim->get_length());
- if (anim->get_step())
- frame->set_step(anim->get_step());
- else
- frame->set_step(0.00001);
} else {
track_editor->set_animation(Ref<Animation>());
@@ -480,6 +477,19 @@ void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) {
_animation_selected(idx);
}
+double AnimationPlayerEditor::_get_editor_step() const {
+
+ // Returns the effective snapping value depending on snapping modifiers, or 0 if snapping is disabled.
+ if (track_editor->is_snap_enabled()) {
+ const String current = player->get_assigned_animation();
+ const Ref<Animation> anim = player->get_animation(current);
+ // Use more precise snapping when holding Shift
+ return Input::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
+ }
+
+ return 0.0;
+}
+
void AnimationPlayerEditor::_animation_name_edited() {
player->stop();
@@ -680,8 +690,10 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
if (p_state.has("animation")) {
String anim = p_state["animation"];
- _select_anim_by_name(anim);
- _animation_edit();
+ if (!anim.empty() && player->has_animation(anim)) {
+ _select_anim_by_name(anim);
+ _animation_edit();
+ }
}
}
}
@@ -1008,7 +1020,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
};
updating = true;
- String current = player->get_assigned_animation(); //animation->get_item_text( animation->get_selected() );
+ String current = player->get_assigned_animation();
if (current == "" || !player->has_animation(current)) {
updating = false;
current = "";
@@ -1018,14 +1030,9 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
Ref<Animation> anim;
anim = player->get_animation(current);
- float pos = anim->get_length() * (p_value / frame->get_max());
- float step = anim->get_step();
- if (step) {
- pos = Math::stepify(pos, step);
- if (pos < 0)
- pos = 0;
- if (pos >= anim->get_length())
- pos = anim->get_length();
+ float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length());
+ if (track_editor->is_snap_enabled()) {
+ pos = Math::stepify(pos, _get_editor_step());
}
if (player->is_valid() && !p_set) {
@@ -1063,14 +1070,6 @@ void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len)
frame->set_max(p_len);
}
-void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) {
-
- if (p_len)
- frame->set_step(p_len);
- else
- frame->set_step(0.00001);
-}
-
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) {
if (!is_visible_in_tree())
@@ -1081,28 +1080,16 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
if (player->is_playing())
return;
+ Ref<Animation> anim = player->get_animation(player->get_assigned_animation());
+
updating = true;
- frame->set_value(p_pos);
+ frame->set_value(Math::stepify(p_pos, _get_editor_step()));
updating = false;
_seek_value_changed(p_pos, !p_drag);
EditorNode::get_singleton()->get_inspector()->refresh();
}
-void AnimationPlayerEditor::_hide_anim_editors() {
-
- player = NULL;
- hide();
- set_process(false);
-
- track_editor->set_animation(Ref<Animation>());
- track_editor->set_root(NULL);
- track_editor->show_select_node_warning(true);
-}
-
-void AnimationPlayerEditor::_animation_about_to_show_menu() {
-}
-
void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
String current;
@@ -1490,7 +1477,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
player->seek(cpos, false);
player->restore_animated_values(values_backup);
- // Restor state of main editors.
+ // Restore state of main editors.
if (SpatialEditor::get_singleton()->is_visible()) {
// 3D
SpatialEditor::get_singleton()->set_state(spatial_edit_state);
@@ -1520,7 +1507,7 @@ void AnimationPlayerEditor::_stop_onion_skinning() {
_free_onion_layers();
- // Clean up the overlay
+ // Clean up the overlay.
onion.can_overlay = false;
plugin->update_overlays();
}
@@ -1558,8 +1545,6 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek);
ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed);
- ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_step_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_step_changed);
- ClassDB::bind_method(D_METHOD("_hide_anim_editors"), &AnimationPlayerEditor::_hide_anim_editors);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &AnimationPlayerEditor::_unhandled_key_input);
@@ -1621,6 +1606,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
hb->add_child(frame);
frame->set_custom_minimum_size(Size2(60, 0));
frame->set_stretch_ratio(2);
+ frame->set_step(0.0001);
frame->set_tooltip(TTR("Animation position (in seconds)."));
hb->add_child(memnew(VSeparator));
@@ -1774,11 +1760,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
track_editor->set_v_size_flags(SIZE_EXPAND_FILL);
track_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
track_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
- track_editor->connect("animation_step_changed", this, "_animation_key_editor_anim_step_changed");
_update_player();
- // Onion skinning
+ // Onion skinning.
track_editor->connect("visibility_changed", this, "_editor_visibility_changed");
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 398ef6ff14..eed7344395 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTrackEditor;
class AnimationPlayerEditorPlugin;
@@ -133,9 +130,9 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationTrackEditor *track_editor;
- // Onion skinning
+ // Onion skinning.
struct {
- // Settings
+ // Settings.
bool enabled;
bool past;
bool future;
@@ -145,11 +142,11 @@ class AnimationPlayerEditor : public VBoxContainer {
bool include_gizmos;
int get_needed_capture_count() const {
- // 'Differences only' needs a capture of the present
+ // 'Differences only' needs a capture of the present.
return (past && future ? 2 * steps : steps) + (differences_only ? 1 : 0);
}
- // Rendering
+ // Rendering.
int64_t last_frame;
int can_overlay;
Size2 capture_size;
@@ -164,6 +161,7 @@ class AnimationPlayerEditor : public VBoxContainer {
} onion;
void _select_anim_by_name(const String &p_anim);
+ double _get_editor_step() const;
void _play_pressed();
void _play_from_pressed();
void _play_bw_pressed();
@@ -197,18 +195,14 @@ class AnimationPlayerEditor : public VBoxContainer {
void _update_player();
void _blend_edited();
- void _hide_anim_editors();
-
void _animation_player_changed(Object *p_pl);
void _animation_key_editor_seek(float p_pos, bool p_drag);
void _animation_key_editor_anim_len_changed(float p_len);
- void _animation_key_editor_anim_step_changed(float p_len);
void _unhandled_key_input(const Ref<InputEvent> &p_ev);
void _animation_tool_menu(int p_option);
void _onion_skinning_menu(int p_option);
- void _animation_about_to_show_menu();
void _editor_visibility_changed();
bool _are_onion_layers_valid();
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/animation_tree_player_editor_plugin.h b/editor/plugins/animation_tree_player_editor_plugin.h
index f4bfe58909..03bc559b86 100644
--- a/editor/plugins/animation_tree_player_editor_plugin.h
+++ b/editor/plugins/animation_tree_player_editor_plugin.h
@@ -38,9 +38,6 @@
#include "scene/gui/button.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTreePlayerEditor : public Control {
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 1503258ff5..3d161dc5b9 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -101,7 +101,7 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
add_style_override("panel", border);
HBoxContainer *hb = memnew(HBoxContainer);
- // Add some spacing to visually separate the icon from the asset details
+ // Add some spacing to visually separate the icon from the asset details.
hb->add_constant_override("separation", 15 * EDSCALE);
add_child(hb);
@@ -118,25 +118,21 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
vb->set_h_size_flags(SIZE_EXPAND_FILL);
title = memnew(LinkButton);
- title->set_text("My Awesome Addon");
title->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
title->connect("pressed", this, "_asset_clicked");
vb->add_child(title);
category = memnew(LinkButton);
- category->set_text("Editor Tools");
category->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
category->connect("pressed", this, "_category_clicked");
vb->add_child(category);
author = memnew(LinkButton);
- author->set_text("Johny Tolengo");
author->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
author->connect("pressed", this, "_author_clicked");
vb->add_child(author);
price = memnew(Label);
- price->set_text(TTR("Free"));
vb->add_child(price);
set_custom_minimum_size(Size2(250, 100) * EDSCALE);
@@ -177,6 +173,8 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
tex->create_from_image(thumbnail);
preview_images[i].button->set_icon(tex);
+ // Make it clearer that clicking it will open an external link
+ preview_images[i].button->set_default_cursor_shape(CURSOR_POINTING_HAND);
} else {
preview_images[i].button->set_icon(p_image);
}
@@ -198,14 +196,15 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
} break;
}
}
+
void EditorAssetLibraryItemDescription::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
previews_bg->add_style_override("panel", get_stylebox("normal", "TextEdit"));
- desc_bg->add_style_override("panel", get_stylebox("normal", "TextEdit"));
} break;
}
}
+
void EditorAssetLibraryItemDescription::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_image"), &EditorAssetLibraryItemDescription::set_image);
ClassDB::bind_method(D_METHOD("_link_click"), &EditorAssetLibraryItemDescription::_link_click);
@@ -268,20 +267,16 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
if (!p_video) {
preview.image = get_icon("ThumbnailWait", "EditorIcons");
}
- if (preview_images.size() == 0 && !p_video) {
+ preview_images.push_back(preview);
+ if (preview_images.size() == 1 && !p_video) {
_preview_click(p_id);
}
- preview_images.push_back(preview);
}
EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
- VBoxContainer *vbox = memnew(VBoxContainer);
- add_child(vbox);
-
HBoxContainer *hbox = memnew(HBoxContainer);
- vbox->add_child(hbox);
- vbox->add_constant_override("separation", 15 * EDSCALE);
+ add_child(hbox);
VBoxContainer *desc_vbox = memnew(VBoxContainer);
hbox->add_child(desc_vbox);
hbox->add_constant_override("separation", 15 * EDSCALE);
@@ -289,24 +284,24 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
item = memnew(EditorAssetLibraryItem);
desc_vbox->add_child(item);
- desc_vbox->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
-
- desc_bg = memnew(PanelContainer);
- desc_vbox->add_child(desc_bg);
- desc_bg->set_v_size_flags(SIZE_EXPAND_FILL);
+ desc_vbox->set_custom_minimum_size(Size2(440 * EDSCALE, 0));
description = memnew(RichTextLabel);
+ desc_vbox->add_child(description);
+ description->set_v_size_flags(SIZE_EXPAND_FILL);
description->connect("meta_clicked", this, "_link_click");
- description->set_custom_minimum_size(Size2(440 * EDSCALE, 300 * EDSCALE));
- desc_bg->add_child(description);
+ description->add_constant_override("line_separation", Math::round(5 * EDSCALE));
VBoxContainer *previews_vbox = memnew(VBoxContainer);
hbox->add_child(previews_vbox);
previews_vbox->add_constant_override("separation", 15 * EDSCALE);
+ previews_vbox->set_v_size_flags(SIZE_EXPAND_FILL);
preview = memnew(TextureRect);
- preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE));
previews_vbox->add_child(preview);
+ preview->set_expand(true);
+ preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE));
previews_bg = memnew(PanelContainer);
previews_vbox->add_child(previews_bg);
@@ -331,18 +326,14 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
switch (p_status) {
- case HTTPRequest::RESULT_CANT_RESOLVE: {
- error_text = TTR("Can't resolve hostname:") + " " + host;
- status->set_text(TTR("Can't resolve."));
- } break;
- case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
+ case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH:
case HTTPRequest::RESULT_CONNECTION_ERROR:
- case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
+ case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: {
error_text = TTR("Connection error, please try again.");
status->set_text(TTR("Can't connect."));
} break;
- case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
- case HTTPRequest::RESULT_CANT_CONNECT: {
+ case HTTPRequest::RESULT_CANT_CONNECT:
+ case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR: {
error_text = TTR("Can't connect to host:") + " " + host;
status->set_text(TTR("Can't connect."));
} break;
@@ -350,13 +341,26 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
error_text = TTR("No response from host:") + " " + host;
status->set_text(TTR("No response."));
} break;
+ case HTTPRequest::RESULT_CANT_RESOLVE: {
+ error_text = TTR("Can't resolve hostname:") + " " + host;
+ status->set_text(TTR("Can't resolve."));
+ } break;
case HTTPRequest::RESULT_REQUEST_FAILED: {
error_text = TTR("Request failed, return code:") + " " + itos(p_code);
- status->set_text(TTR("Request Failed."));
+ status->set_text(TTR("Request failed."));
+ } break;
+ case HTTPRequest::RESULT_DOWNLOAD_FILE_CANT_OPEN:
+ case HTTPRequest::RESULT_DOWNLOAD_FILE_WRITE_ERROR: {
+ error_text = TTR("Cannot save response to:") + " " + download->get_download_file();
+ status->set_text(TTR("Write error."));
} break;
case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
error_text = TTR("Request failed, too many redirects");
- status->set_text(TTR("Redirect Loop."));
+ status->set_text(TTR("Redirect loop."));
+ } break;
+ case HTTPRequest::RESULT_TIMEOUT: {
+ error_text = TTR("Request failed, timeout");
+ status->set_text(TTR("Timeout."));
} break;
default: {
if (p_code != 200) {
@@ -381,7 +385,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
install->set_disabled(false);
status->set_text(TTR("Success!"));
- // Make the progress bar invisible but don't reflow other Controls around it
+ // Make the progress bar invisible but don't reflow other Controls around it.
progress->set_modulate(Color(0, 0, 0, 0));
set_process(false);
@@ -393,71 +397,76 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse
icon->set_texture(p_preview);
asset_id = p_asset_id;
if (!p_preview.is_valid())
- icon->set_texture(get_icon("DefaultProjectIcon", "EditorIcons"));
+ icon->set_texture(get_icon("FileBrokenBigThumb", "EditorIcons"));
host = p_download_url;
sha256 = p_sha256_hash;
- asset_installer->connect("confirmed", this, "_close");
- dismiss->set_normal_texture(get_icon("Close", "EditorIcons"));
_make_request();
}
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));
+ // FIXME: The editor crashes if 'NOTICATION_THEME_CHANGED' is used.
+ case NOTIFICATION_ENTER_TREE: {
- 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"));
+ dismiss->set_normal_texture(get_icon("Close", "EditorIcons"));
+ } 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() {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->remove(download->get_download_file()); //clean up removed file
- memdelete(da);
+ // Clean up downloaded file.
+ DirAccess::remove_file_or_error(download->get_download_file());
queue_delete();
}
@@ -531,7 +540,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");
@@ -554,6 +563,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
asset_installer = memnew(EditorAssetInstaller);
add_child(asset_installer);
+ asset_installer->connect("confirmed", this, "_close");
prev_status = -1;
@@ -564,53 +574,33 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
void EditorAssetLibrary::_notification(int p_what) {
switch (p_what) {
+
case NOTIFICATION_READY: {
error_tr->set_texture(get_icon("Error", "EditorIcons"));
- reverse->set_icon(get_icon("Sort", "EditorIcons"));
filter->set_right_icon(get_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
error_label->raise();
} break;
-
case NOTIFICATION_VISIBILITY_CHANGED: {
- if (is_visible()) {
- _repository_changed(0); // Update when shown for the first time
+ if (is_visible() && initial_loading) {
+ _repository_changed(0); // Update when shown for the first time.
}
} break;
-
case NOTIFICATION_PROCESS: {
HTTPClient::Status s = request->get_http_client_status();
- bool visible = s != HTTPClient::STATUS_DISCONNECTED;
-
- if (visible != load_status->is_visible()) {
- load_status->set_visible(visible);
- }
-
- if (visible) {
- switch (s) {
+ const bool loading = s != HTTPClient::STATUS_DISCONNECTED;
- case HTTPClient::STATUS_RESOLVING: {
- load_status->set_value(0.1);
- } break;
- case HTTPClient::STATUS_CONNECTING: {
- load_status->set_value(0.2);
- } break;
- case HTTPClient::STATUS_REQUESTING: {
- load_status->set_value(0.3);
- } break;
- case HTTPClient::STATUS_BODY: {
- load_status->set_value(0.4);
- } break;
- default: {
- }
- }
+ if (loading) {
+ library_scroll->set_modulate(Color(1, 1, 1, 0.5));
+ } else {
+ library_scroll->set_modulate(Color(1, 1, 1, 1));
}
- bool no_downloads = downloads_hb->get_child_count() == 0;
+ const bool no_downloads = downloads_hb->get_child_count() == 0;
if (no_downloads == downloads_scroll->is_visible()) {
downloads_scroll->set_visible(!no_downloads);
}
@@ -619,8 +609,8 @@ 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"));
filter->set_clear_button_enabled(true);
} break;
@@ -653,28 +643,32 @@ void EditorAssetLibrary::_install_asset() {
}
const char *EditorAssetLibrary::sort_key[SORT_MAX] = {
- "downloads",
+ "updated",
+ "updated",
+ "name",
"name",
"cost",
- "updated"
+ "cost",
};
const char *EditorAssetLibrary::sort_text[SORT_MAX] = {
- "Downloads",
- "Name",
- "License", // "cost" stores the SPDX license name in the Godot Asset Library
- "Updated"
+ "Recently Updated",
+ "Least Recently Updated",
+ "Name (A-Z)",
+ "Name (Z-A)",
+ "License (A-Z)", // "cost" stores the SPDX license name in the Godot Asset Library.
+ "License (Z-A)", // "cost" stores the SPDX license name in the Godot Asset Library.
};
const char *EditorAssetLibrary::support_key[SUPPORT_MAX] = {
"official",
"community",
- "testing"
+ "testing",
};
void EditorAssetLibrary::_select_author(int p_id) {
- // Open author window
+ // Open author window.
}
void EditorAssetLibrary::_select_category(int p_id) {
@@ -741,7 +735,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
switch (image_queue[p_queue_id].image_type) {
case IMAGE_QUEUE_ICON:
- image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_CUBIC);
+ image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_LANCZOS);
break;
case IMAGE_QUEUE_THUMBNAIL: {
@@ -749,7 +743,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
float scale_ratio = max_height / (image->get_height() * EDSCALE);
if (scale_ratio < 1) {
- image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_CUBIC);
+ image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS);
}
} break;
case IMAGE_QUEUE_SCREENSHOT: {
@@ -757,7 +751,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
float scale_ratio = max_height / (image->get_height() * EDSCALE);
if (scale_ratio < 1) {
- image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_CUBIC);
+ image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS);
}
} break;
}
@@ -771,7 +765,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
}
if (!image_set && final) {
- obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_icon("DefaultProjectIcon", "EditorIcons"));
+ obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_icon("FileBrokenBigThumb", "EditorIcons"));
}
}
}
@@ -816,7 +810,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
WARN_PRINTS("Error getting image file from URL: " + image_queue[p_queue_id].image_url);
Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
if (obj) {
- obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_icon("DefaultProjectIcon", "EditorIcons"));
+ obj->call("set_image", image_queue[p_queue_id].image_type, image_queue[p_queue_id].image_index, get_icon("FileBrokenBigThumb", "EditorIcons"));
}
}
@@ -828,7 +822,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
void EditorAssetLibrary::_update_image_queue() {
- int max_images = 2;
+ const int max_images = 6;
int current_images = 0;
List<int> to_delete;
@@ -936,8 +930,8 @@ void EditorAssetLibrary::_search(int p_page) {
args += "&category=" + itos(categories->get_item_metadata(categories->get_selected()));
}
- if (reverse->is_pressed()) {
-
+ // Sorting options with an odd index are always the reverse of the previous one
+ if (sort->get_selected() % 2 == 1) {
args += "&reverse=true";
}
@@ -1140,6 +1134,12 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
_search();
} break;
case REQUESTING_SEARCH: {
+
+ initial_loading = false;
+
+ // The loading text only needs to be displayed before the first page is loaded
+ library_loading->hide();
+
if (asset_items) {
memdelete(asset_items);
}
@@ -1238,9 +1238,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);
@@ -1267,9 +1264,8 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
if (p.has("thumbnail")) {
_request_image(description->get_instance_id(), p["thumbnail"], IMAGE_QUEUE_THUMBNAIL, i);
}
- if (is_video) {
- //_request_image(description->get_instance_id(),p["link"],IMAGE_QUEUE_SCREENSHOT,i);
- } else {
+
+ if (!is_video) {
_request_image(description->get_instance_id(), p["link"], IMAGE_QUEUE_SCREENSHOT, i);
}
}
@@ -1336,6 +1332,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
requesting = REQUESTING_NONE;
templates_only = p_templates_only;
+ initial_loading = true;
VBoxContainer *library_main = memnew(VBoxContainer);
@@ -1346,7 +1343,6 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_main->add_child(search_hb);
library_main->add_constant_override("separation", 10 * EDSCALE);
- search_hb->add_child(memnew(Label(TTR("Search:") + " ")));
filter = memnew(LineEdit);
search_hb->add_child(filter);
filter->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1359,12 +1355,12 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
search_hb->add_child(memnew(VSeparator));
Button *open_asset = memnew(Button);
- open_asset->set_text(TTR("Import"));
+ open_asset->set_text(TTR("Import..."));
search_hb->add_child(open_asset);
open_asset->connect("pressed", this, "_asset_open");
Button *plugins = memnew(Button);
- plugins->set_text(TTR("Plugins"));
+ plugins->set_text(TTR("Plugins..."));
search_hb->add_child(plugins);
plugins->connect("pressed", this, "_manage_plugins");
@@ -1387,22 +1383,13 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
sort->set_h_size_flags(SIZE_EXPAND_FILL);
sort->connect("item_selected", this, "_rerun_search");
- reverse = memnew(ToolButton);
- reverse->set_toggle_mode(true);
- reverse->connect("toggled", this, "_rerun_search");
- //reverse->set_text(TTR("Reverse"));
- 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));
@@ -1424,7 +1411,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
support = memnew(MenuButton);
search_hb2->add_child(support);
- support->set_text(TTR("Support..."));
+ support->set_text(TTR("Support"));
support->get_popup()->add_check_item(TTR("Official"), SUPPORT_OFFICIAL);
support->get_popup()->add_check_item(TTR("Community"), SUPPORT_COMMUNITY);
support->get_popup()->add_check_item(TTR("Testing"), SUPPORT_TESTING);
@@ -1462,6 +1449,10 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_vb_border->add_child(library_vb);
+ library_loading = memnew(Label(TTR("Loading...")));
+ library_loading->set_align(Label::ALIGN_CENTER);
+ library_vb->add_child(library_loading);
+
asset_top_page = memnew(HBoxContainer);
library_vb->add_child(asset_top_page);
@@ -1484,12 +1475,6 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_vb->add_constant_override("separation", 20 * EDSCALE);
- load_status = memnew(ProgressBar);
- load_status->set_min(0);
- load_status->set_max(1);
- load_status->set_step(0.001);
- library_main->add_child(load_status);
-
error_hb = memnew(HBoxContainer);
library_main->add_child(error_hb);
error_label = memnew(Label);
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index 81288ae831..7e934ac6cb 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -91,7 +91,6 @@ class EditorAssetLibraryItemDescription : public ConfirmationDialog {
ScrollContainer *previews;
HBoxContainer *preview_hb;
PanelContainer *previews_bg;
- PanelContainer *desc_bg;
struct Preview {
int id;
@@ -186,13 +185,12 @@ class EditorAssetLibrary : public PanelContainer {
PanelContainer *library_scroll_bg;
ScrollContainer *library_scroll;
VBoxContainer *library_vb;
+ Label *library_loading;
LineEdit *filter;
OptionButton *categories;
OptionButton *repository;
OptionButton *sort;
- ToolButton *reverse;
Button *search;
- ProgressBar *load_status;
HBoxContainer *error_hb;
TextureRect *error_tr;
Label *error_label;
@@ -207,6 +205,7 @@ class EditorAssetLibrary : public PanelContainer {
HTTPRequest *request;
bool templates_only;
+ bool initial_loading;
enum Support {
SUPPORT_OFFICIAL,
@@ -216,10 +215,12 @@ class EditorAssetLibrary : public PanelContainer {
};
enum SortOrder {
- SORT_DOWNLOADS,
+ SORT_UPDATED,
+ SORT_UPDATED_REVERSE,
SORT_NAME,
+ SORT_NAME_REVERSE,
SORT_COST,
- SORT_UPDATED,
+ SORT_COST_REVERSE,
SORT_MAX
};
diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h
index eac9acab93..400aee132d 100644
--- a/editor/plugins/camera_editor_plugin.h
+++ b/editor/plugins/camera_editor_plugin.h
@@ -35,10 +35,6 @@
#include "editor/editor_plugin.h"
#include "scene/3d/camera.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CameraEditor : public Control {
GDCLASS(CameraEditor, Control);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index e0e9d4af52..6f612b5c79 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -174,15 +174,6 @@ public:
}
};
-void CanvasItemEditor::_snap_if_closer_float(float p_value, float p_target_snap, float &r_current_snap, bool &r_snapped, float p_radius) {
- float radius = p_radius / zoom;
- float dist = Math::abs(p_value - p_target_snap);
- if ((p_radius < 0 || dist < radius) && (!r_snapped || dist < Math::abs(r_current_snap - p_value))) {
- r_current_snap = p_target_snap;
- r_snapped = true;
- }
-}
-
bool CanvasItemEditor::_is_node_locked(const Node *p_node) {
return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
}
@@ -200,108 +191,174 @@ bool CanvasItemEditor::_is_node_movable(const Node *p_node, bool p_popup_warning
return true;
}
-void CanvasItemEditor::_snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) {
+void CanvasItemEditor::_snap_if_closer_float(
+ float p_value,
+ float &r_current_snap, SnapTarget &r_current_snap_target,
+ float p_target_value, SnapTarget p_snap_target,
+ float p_radius) {
+
+ float radius = p_radius / zoom;
+ float dist = Math::abs(p_value - p_target_value);
+ if ((p_radius < 0 || dist < radius) && (r_current_snap_target == SNAP_TARGET_NONE || dist < Math::abs(r_current_snap - p_value))) {
+ r_current_snap = p_target_value;
+ r_current_snap_target = p_snap_target;
+ }
+}
+
+void CanvasItemEditor::_snap_if_closer_point(
+ Point2 p_value,
+ Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
+ Point2 p_target_value, SnapTarget p_snap_target,
+ real_t rotation,
+ float p_radius) {
+
Transform2D rot_trans = Transform2D(rotation, Point2());
p_value = rot_trans.inverse().xform(p_value);
- p_target_snap = rot_trans.inverse().xform(p_target_snap);
+ p_target_value = rot_trans.inverse().xform(p_target_value);
r_current_snap = rot_trans.inverse().xform(r_current_snap);
- _snap_if_closer_float(p_value.x, p_target_snap.x, r_current_snap.x, r_snapped[0], p_radius);
- _snap_if_closer_float(p_value.y, p_target_snap.y, r_current_snap.y, r_snapped[1], p_radius);
+ _snap_if_closer_float(
+ p_value.x,
+ r_current_snap.x,
+ r_current_snap_target[0],
+ p_target_value.x,
+ p_snap_target,
+ p_radius);
+
+ _snap_if_closer_float(
+ p_value.y,
+ r_current_snap.y,
+ r_current_snap_target[1],
+ p_target_value.y,
+ p_snap_target,
+ p_radius);
r_current_snap = rot_trans.xform(r_current_snap);
}
-void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap) {
+void CanvasItemEditor::_snap_other_nodes(
+ const Point2 p_value,
+ const Transform2D p_transform_to_snap,
+ Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
+ const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions,
+ const Node *p_current) {
const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_current);
- if (canvas_item && (!p_to_snap || p_current != p_to_snap)) {
+
+ // Check if the element is in the exception
+ bool exception = false;
+ for (List<const CanvasItem *>::Element *E = p_exceptions.front(); E; E = E->next()) {
+ if (E->get() == p_current) {
+ exception = true;
+ break;
+ }
+ };
+
+ if (canvas_item && !exception) {
Transform2D ci_transform = canvas_item->get_global_transform_with_canvas();
- Transform2D to_snap_transform = p_to_snap ? p_to_snap->get_global_transform_with_canvas() : Transform2D();
- if (fmod(ci_transform.get_rotation() - to_snap_transform.get_rotation(), (real_t)360.0) == 0.0) {
+ if (fmod(ci_transform.get_rotation() - p_transform_to_snap.get_rotation(), (real_t)360.0) == 0.0) {
if (canvas_item->_edit_use_rect()) {
Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position());
Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size());
- _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation());
- _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation());
+
+ _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, begin, p_snap_target, ci_transform.get_rotation());
+ _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, end, p_snap_target, ci_transform.get_rotation());
} else {
Point2 position = ci_transform.xform(Point2());
- _snap_if_closer_point(p_value, position, r_current_snap, r_snapped, ci_transform.get_rotation());
+ _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, position, p_snap_target, ci_transform.get_rotation());
}
}
}
for (int i = 0; i < p_current->get_child_count(); i++) {
- _snap_other_nodes(p_value, r_current_snap, r_snapped, p_current->get_child(i), p_to_snap);
+ _snap_other_nodes(p_value, p_transform_to_snap, r_current_snap, r_current_snap_target, p_snap_target, p_exceptions, p_current->get_child(i));
}
}
-Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) {
- bool snapped[2] = { false, false };
+Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsigned int p_forced_modes, const CanvasItem *p_self_canvas_item, List<CanvasItem *> p_other_nodes_exceptions) {
+
+ snap_target[0] = SNAP_TARGET_NONE;
+ snap_target[1] = SNAP_TARGET_NONE;
+
bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
// Smart snap using the canvas position
Vector2 output = p_target;
real_t rotation = 0.0;
- if (p_canvas_item) {
- rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation();
+ if (p_self_canvas_item) {
+ rotation = p_self_canvas_item->get_global_transform_with_canvas().get_rotation();
// Parent sides and center
if ((is_snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) {
- if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
- Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0)));
- Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1)));
- _snap_if_closer_point(p_target, begin, output, snapped, rotation);
- _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation);
- _snap_if_closer_point(p_target, end, output, snapped, rotation);
- } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) {
+ if (const Control *c = Object::cast_to<Control>(p_self_canvas_item)) {
+ Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0)));
+ Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1)));
+ _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_PARENT, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, (begin + end) / 2.0, SNAP_TARGET_PARENT, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_PARENT, rotation);
+ } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_self_canvas_item->get_parent())) {
if (parent_ci->_edit_use_rect()) {
- Point2 begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position());
- Point2 end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size());
- _snap_if_closer_point(p_target, begin, output, snapped, rotation);
- _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation);
- _snap_if_closer_point(p_target, end, output, snapped, rotation);
+ Point2 begin = p_self_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position());
+ Point2 end = p_self_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size());
+ _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_PARENT, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, (begin + end) / 2.0, SNAP_TARGET_PARENT, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_PARENT, rotation);
} else {
- Point2 position = p_canvas_item->get_transform().affine_inverse().xform(Point2());
- _snap_if_closer_point(p_target, position, output, snapped, rotation);
+ Point2 position = p_self_canvas_item->get_transform().affine_inverse().xform(Point2());
+ _snap_if_closer_point(p_target, output, snap_target, position, SNAP_TARGET_PARENT, rotation);
}
}
}
// Self anchors
if ((is_snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) {
- if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
- Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP))));
- Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM))));
- _snap_if_closer_point(p_target, begin, output, snapped, rotation);
- _snap_if_closer_point(p_target, end, output, snapped, rotation);
+ if (const Control *c = Object::cast_to<Control>(p_self_canvas_item)) {
+ Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP))));
+ Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM))));
+ _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_SELF_ANCHORS, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_SELF_ANCHORS, rotation);
}
}
// Self sides
if ((is_snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) {
- if (p_canvas_item->_edit_use_rect()) {
- Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position());
- Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size());
- _snap_if_closer_point(p_target, begin, output, snapped, rotation);
- _snap_if_closer_point(p_target, end, output, snapped, rotation);
+ if (p_self_canvas_item->_edit_use_rect()) {
+ Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position());
+ Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position() + p_self_canvas_item->_edit_get_rect().get_size());
+ _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_SELF, rotation);
+ _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_SELF, rotation);
}
}
// Self center
if ((is_snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) {
- if (p_canvas_item->_edit_use_rect()) {
- Point2 center = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size() / 2.0);
- _snap_if_closer_point(p_target, center, output, snapped, rotation);
+ if (p_self_canvas_item->_edit_use_rect()) {
+ Point2 center = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position() + p_self_canvas_item->_edit_get_rect().get_size() / 2.0);
+ _snap_if_closer_point(p_target, output, snap_target, center, SNAP_TARGET_SELF, rotation);
} else {
- Point2 position = p_canvas_item->get_global_transform_with_canvas().xform(Point2());
- _snap_if_closer_point(p_target, position, output, snapped, rotation);
+ Point2 position = p_self_canvas_item->get_global_transform_with_canvas().xform(Point2());
+ _snap_if_closer_point(p_target, output, snap_target, position, SNAP_TARGET_SELF, rotation);
}
}
}
// Other nodes sides
if ((is_snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) {
- _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item);
+ Transform2D to_snap_transform = Transform2D();
+ List<const CanvasItem *> exceptions = List<const CanvasItem *>();
+ for (List<CanvasItem *>::Element *E = p_other_nodes_exceptions.front(); E; E = E->next()) {
+ exceptions.push_back(E->get());
+ }
+ if (p_self_canvas_item) {
+ exceptions.push_back(p_self_canvas_item);
+ to_snap_transform = p_self_canvas_item->get_global_transform_with_canvas();
+ }
+
+ _snap_other_nodes(
+ p_target, to_snap_transform,
+ output, snap_target,
+ SNAP_TARGET_OTHER_NODE,
+ exceptions,
+ get_tree()->get_edited_scene_root());
}
if (((is_snap_active && snap_guides && (p_modes & SNAP_GUIDES)) || (p_forced_modes & SNAP_GUIDES)) && fmod(rotation, (real_t)360.0) == 0.0) {
@@ -309,14 +366,14 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const
if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
for (int i = 0; i < vguides.size(); i++) {
- _snap_if_closer_float(p_target.x, vguides[i], output.x, snapped[0]);
+ _snap_if_closer_float(p_target.x, output.x, snap_target[0], vguides[i], SNAP_TARGET_GUIDE);
}
}
if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
for (int i = 0; i < hguides.size(); i++) {
- _snap_if_closer_float(p_target.y, hguides[i], output.y, snapped[1]);
+ _snap_if_closer_float(p_target.y, output.y, snap_target[1], hguides[i], SNAP_TARGET_GUIDE);
}
}
}
@@ -335,7 +392,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const
Point2 grid_output;
grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x;
grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y;
- _snap_if_closer_point(p_target, grid_output, output, snapped, 0.0, -1.0);
+ _snap_if_closer_point(p_target, output, snap_target, grid_output, SNAP_TARGET_GRID, 0.0, -1.0);
}
if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) {
@@ -343,6 +400,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const
output = output.snapped(Size2(1, 1));
}
+ snap_transform = Transform2D(rotation, output);
+
return output;
}
@@ -860,20 +919,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 +969,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 +986,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 +1040,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 +1056,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 +1069,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 +1085,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 +1099,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);
@@ -1033,12 +1117,14 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
return false;
}
-bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
+bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bool p_already_accepted) {
Ref<InputEventMouseButton> b = p_event;
- if (b.is_valid()) {
+ if (b.is_valid() && !p_already_accepted) {
+ bool pan_on_scroll = bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan")) && !b->get_control();
+
if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_DOWN) {
// Scroll or pan down
- if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+ if (pan_on_scroll) {
view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
} else {
@@ -1049,7 +1135,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_UP) {
// Scroll or pan up
- if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+ if (pan_on_scroll) {
view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
} else {
@@ -1060,7 +1146,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_LEFT) {
// Pan left
- if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+ if (pan_on_scroll) {
view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
return true;
@@ -1069,7 +1155,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
if (b->is_pressed() && b->get_button_index() == BUTTON_WHEEL_RIGHT) {
// Pan right
- if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+ if (pan_on_scroll) {
view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
update_viewport();
return true;
@@ -1079,6 +1165,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
if (!panning) {
if (b->is_pressed() &&
(b->get_button_index() == BUTTON_MIDDLE ||
+ b->get_button_index() == BUTTON_RIGHT ||
(b->get_button_index() == BUTTON_LEFT && tool == TOOL_PAN) ||
(b->get_button_index() == BUTTON_LEFT && !EditorSettings::get_singleton()->get("editors/2d/simple_panning") && pan_pressed))) {
// Pan the viewport
@@ -1134,14 +1221,14 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMagnifyGesture> magnify_gesture = p_event;
- if (magnify_gesture.is_valid()) {
+ if (magnify_gesture.is_valid() && !p_already_accepted) {
// Zoom gesture
_zoom_on_position(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position());
return true;
}
Ref<InputEventPanGesture> pan_gesture = p_event;
- if (pan_gesture.is_valid()) {
+ if (pan_gesture.is_valid() && !p_already_accepted) {
// Pan gesture
const Vector2 delta = (int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom) * pan_gesture->get_delta();
view_offset.x += delta.x;
@@ -1177,10 +1264,11 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
if (drag_selection.size() > 0) {
drag_from = transform.affine_inverse().xform((b.is_valid()) ? b->get_position() : viewport->get_local_mouse_position());
Vector2 new_pos;
- if (drag_selection.size() == 1)
- new_pos = snap_point(drag_from, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, drag_selection[0]);
- else
- new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL);
+ if (drag_selection.size() == 1) {
+ new_pos = snap_point(drag_from, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]);
+ } else {
+ new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, NULL, drag_selection);
+ }
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos));
@@ -1200,7 +1288,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
_restore_canvas_item_state(drag_selection);
Vector2 new_pos;
if (drag_selection.size() == 1)
- new_pos = snap_point(drag_to, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, drag_selection[0]);
+ new_pos = snap_point(drag_to, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]);
else
new_pos = snap_point(drag_to, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL);
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
@@ -1406,7 +1494,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
for (int i = 0; i < 4; i++) {
anchor_pos[i] = (transform * control->get_global_transform_with_canvas()).xform(_anchor_to_position(control, anchor_pos[i]));
anchor_rects[i] = Rect2(anchor_pos[i], anchor_handle->get_size());
- anchor_rects[i].position -= anchor_handle->get_size() * Vector2(i == 0 || i == 3, i <= 1);
+ anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 0 || i == 3), float(i <= 1));
}
DragType dragger[] = {
@@ -1450,7 +1538,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
previous_anchor.y = (drag_type == DRAG_ANCHOR_TOP_LEFT || drag_type == DRAG_ANCHOR_TOP_RIGHT) ? control->get_anchor(MARGIN_TOP) : control->get_anchor(MARGIN_BOTTOM);
previous_anchor = xform.affine_inverse().xform(_anchor_to_position(control, previous_anchor));
- Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, control, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER));
+ Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER, control));
new_anchor = _position_to_anchor(control, new_anchor).snapped(Vector2(0.001, 0.001));
bool use_single_axis = m->get_shift();
@@ -1596,8 +1684,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse();
- Point2 drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, canvas_item);
- Point2 drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, canvas_item);
+ Point2 drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item);
+ Point2 drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item);
Point2 drag_begin = xform.xform(drag_to_snapped_begin);
Point2 drag_end = xform.xform(drag_to_snapped_end);
@@ -1838,7 +1926,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
} else {
previous_pos = _get_encompassing_rect_from_list(drag_selection).position;
}
- Point2 new_pos = snap_point(previous_pos + (drag_to - drag_from), SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL | SNAP_NODE_PARENT | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES);
+ Point2 new_pos = snap_point(previous_pos + (drag_to - drag_from), SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL | SNAP_NODE_PARENT | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES, 0, NULL, drag_selection);
bool single_axis = m->get_shift();
if (single_axis) {
if (ABS(new_pos.x - previous_pos.x) > ABS(new_pos.y - previous_pos.y)) {
@@ -2158,6 +2246,40 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
return false;
}
+bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) {
+
+ if (tool != TOOL_RULER)
+ return false;
+
+ Ref<InputEventMouseButton> b = p_event;
+ Ref<InputEventMouseMotion> m = p_event;
+
+ Point2 previous_origin = ruler_tool_origin;
+ if (!ruler_tool_active)
+ ruler_tool_origin = snap_point(viewport->get_local_mouse_position() / zoom + view_offset) * zoom;
+
+ if (b.is_valid() && b->get_button_index() == BUTTON_LEFT) {
+ if (b->is_pressed()) {
+ ruler_tool_active = true;
+ } else {
+ ruler_tool_active = false;
+ }
+
+ viewport->update();
+ return true;
+ }
+
+ bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+
+ if (m.is_valid() && (ruler_tool_active || (is_snap_active && previous_origin != ruler_tool_origin))) {
+
+ viewport->update();
+ return true;
+ }
+
+ return false;
+}
+
bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> m = p_event;
@@ -2221,8 +2343,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,14 +2353,18 @@ 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 if ((accepted = _gui_input_ruler_tool(p_event))) {
+ //printf("Measure\n");
} else {
//printf("Not accepted\n");
}
}
- accepted = (_gui_input_zoom_or_pan(p_event) || accepted);
+ accepted = (_gui_input_zoom_or_pan(p_event, accepted) || accepted);
if (accepted)
accept_event();
@@ -2262,20 +2386,26 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
case TOOL_PAN:
c = CURSOR_DRAG;
break;
+ case TOOL_RULER:
+ c = CURSOR_CROSS;
+ break;
default:
break;
}
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 +2418,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 +2487,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 +2497,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 +2509,28 @@ 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));
+ }
+}
+
+void CanvasItemEditor::_draw_smart_snapping() {
+ Color line_color = EditorSettings::get_singleton()->get("editors/2d/smart_snapping_line_color");
+ if (snap_target[0] != SNAP_TARGET_NONE && snap_target[0] != SNAP_TARGET_GRID) {
+ viewport->draw_set_transform_matrix(viewport->get_transform() * transform * snap_transform);
+ viewport->draw_line(Point2(0, -1.0e+10F), Point2(0, 1.0e+10F), line_color);
+ viewport->draw_set_transform_matrix(viewport->get_transform());
+ }
+ if (snap_target[1] != SNAP_TARGET_NONE && snap_target[1] != SNAP_TARGET_GRID) {
+ viewport->draw_set_transform_matrix(viewport->get_transform() * transform * snap_transform);
+ viewport->draw_line(Point2(-1.0e+10F, 0), Point2(1.0e+10F, 0), line_color);
+ viewport->draw_set_transform_matrix(viewport->get_transform());
}
}
@@ -2435,14 +2585,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 +2602,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,12 +2612,14 @@ 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));
}
}
}
+
+ // Draw the top left corner
viewport->draw_rect(Rect2(Point2(), Size2(RULER_WIDTH, RULER_WIDTH)), graduation_color);
}
@@ -2495,7 +2647,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,13 +2658,90 @@ 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;
}
}
}
}
+void CanvasItemEditor::_draw_ruler_tool() {
+
+ if (tool != TOOL_RULER)
+ return;
+
+ bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+
+ if (ruler_tool_active) {
+ Color ruler_primary_color = get_color("accent_color", "Editor");
+ Color ruler_secondary_color = ruler_primary_color;
+ ruler_secondary_color.a = 0.5;
+
+ Point2 begin = ruler_tool_origin - view_offset * zoom;
+ Point2 end = snap_point(viewport->get_local_mouse_position() / zoom + view_offset) * zoom - view_offset * zoom;
+ Point2 corner = Point2(begin.x, end.y);
+ Vector2 length_vector = (begin - end).abs() / zoom;
+
+ bool draw_secondary_lines = (begin.y != corner.y && end.x != corner.x);
+
+ viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3), true);
+ if (draw_secondary_lines) {
+ viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE));
+ viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE));
+ }
+
+ Ref<Font> font = get_font("bold", "EditorFonts");
+ Color font_color = get_color("font_color", "Editor");
+ Color font_secondary_color = font_color;
+ font_secondary_color.a = 0.5;
+ float text_height = font->get_height();
+ const float text_width = 76;
+
+ Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2);
+ text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5);
+ text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5);
+ viewport->draw_string(font, text_pos, vformat("%.2f px", length_vector.length()), font_color);
+
+ if (draw_secondary_lines) {
+
+ Point2 text_pos2 = text_pos;
+ text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
+ viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.y), font_secondary_color);
+
+ text_pos2 = text_pos;
+ text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2);
+ viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.x), font_secondary_color);
+ }
+
+ if (is_snap_active) {
+
+ text_pos = (begin + end) / 2 + Vector2(-text_width / 2, text_height / 2);
+ text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5);
+ text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2);
+
+ if (draw_secondary_lines) {
+ viewport->draw_string(font, text_pos, vformat("%.2f units", (length_vector / grid_step).length()), font_color);
+
+ Point2 text_pos2 = text_pos;
+ text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2);
+ viewport->draw_string(font, text_pos2, vformat("%d units", (int)(length_vector.y / grid_step.y)), font_secondary_color);
+
+ text_pos2 = text_pos;
+ text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2);
+ viewport->draw_string(font, text_pos2, vformat("%d units", (int)(length_vector.x / grid_step.x)), font_secondary_color);
+ } else {
+ viewport->draw_string(font, text_pos, vformat("%d units", roundf((length_vector / grid_step).length())), font_color);
+ }
+ }
+ } else {
+
+ if (is_snap_active) {
+ Ref<Texture> position_icon = get_icon("EditorPosition", "EditorIcons");
+ viewport->draw_texture(get_icon("EditorPosition", "EditorIcons"), ruler_tool_origin - view_offset * zoom - position_icon->get_size() / 2);
+ }
+ }
+}
+
void CanvasItemEditor::_draw_control_anchors(Control *control) {
Transform2D xform = transform * control->get_global_transform_with_canvas();
RID ci = viewport->get_canvas_item();
@@ -2586,7 +2815,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
if (dragged_anchor >= 0) {
// Draw the 4 lines when dragged
- bool snapped;
+ bool anchor_snapped;
Color color_snapped = Color(0.64, 0.93, 0.67, 0.5);
Vector2 corners_pos[4];
@@ -2600,8 +2829,8 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
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);
+ anchor_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], anchor_snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
}
// Display the percentages next to the lines
@@ -2646,7 +2875,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 +2890,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 +2905,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 +2920,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 +2939,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 +2980,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 +3002,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 +3082,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());
}
@@ -2877,10 +3104,15 @@ void CanvasItemEditor::_draw_selection() {
Point2 bsfrom = transform.xform(drag_from);
Point2 bsto = transform.xform(box_selecting_to);
- VisualServer::get_singleton()->canvas_item_add_rect(
- ci,
+ viewport->draw_rect(
+ Rect2(bsfrom, bsto - bsfrom),
+ get_color("box_selection_fill_color", "Editor"));
+
+ viewport->draw_rect(
Rect2(bsfrom, bsto - bsfrom),
- get_color("accent_color", "Editor") * Color(1, 1, 1, 0.375));
+ get_color("box_selection_stroke_color", "Editor"),
+ false,
+ Math::round(EDSCALE));
}
if (drag_type == DRAG_ROTATE) {
@@ -3242,6 +3474,7 @@ void CanvasItemEditor::_draw_viewport() {
info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
_draw_grid();
+ _draw_ruler_tool();
_draw_selection();
_draw_axis();
if (editor->get_edited_scene()) {
@@ -3266,6 +3499,7 @@ void CanvasItemEditor::_draw_viewport() {
_draw_rulers();
if (show_guides)
_draw_guides();
+ _draw_smart_snapping();
_draw_focus();
_draw_hover();
}
@@ -3275,6 +3509,10 @@ void CanvasItemEditor::update_viewport() {
viewport->update();
}
+void CanvasItemEditor::set_current_tool(Tool p_tool) {
+ _button_tool_select(p_tool);
+}
+
void CanvasItemEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
@@ -3425,6 +3663,7 @@ void CanvasItemEditor::_notification(int p_what) {
snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
+ ruler_button->set_icon(get_icon("Ruler", "EditorIcons"));
pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
select_handle = get_icon("EditorHandle", "EditorIcons");
anchor_handle = get_icon("EditorControlAnchor", "EditorIcons");
@@ -3439,7 +3678,6 @@ void CanvasItemEditor::_notification(int p_what) {
key_auto_insert_button->set_icon(get_icon("AutoKey", "EditorIcons"));
zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons"));
- zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons"));
presets_menu->set_icon(get_icon("ControlLayout", "EditorIcons"));
@@ -3797,11 +4035,24 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
view_offset.x = Math::round(view_offset.x + ofs.x);
view_offset.y = Math::round(view_offset.y + ofs.y);
+ _update_zoom_label();
update_viewport();
}
+void CanvasItemEditor::_update_zoom_label() {
+ String zoom_text;
+ if (zoom >= 10) {
+ // Don't show a decimal when the zoom level is higher than 1000 %
+ zoom_text = rtos(Math::round(zoom * 100)) + " %";
+ } else {
+ zoom_text = rtos(Math::stepify(zoom * 100, 0.1)) + " %";
+ }
+
+ zoom_reset->set_text(zoom_text);
+}
+
void CanvasItemEditor::_button_zoom_minus() {
- _zoom_on_position(zoom / 1.5, viewport_scrollable->get_size() / 2.0);
+ _zoom_on_position(zoom / Math_SQRT2, viewport_scrollable->get_size() / 2.0);
}
void CanvasItemEditor::_button_zoom_reset() {
@@ -3809,7 +4060,7 @@ void CanvasItemEditor::_button_zoom_reset() {
}
void CanvasItemEditor::_button_zoom_plus() {
- _zoom_on_position(zoom * 1.5, viewport_scrollable->get_size() / 2.0);
+ _zoom_on_position(zoom * Math_SQRT2, viewport_scrollable->get_size() / 2.0);
}
void CanvasItemEditor::_button_toggle_snap(bool p_status) {
@@ -3819,13 +4070,13 @@ void CanvasItemEditor::_button_toggle_snap(bool p_status) {
void CanvasItemEditor::_button_tool_select(int p_index) {
- ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button };
+ ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button, ruler_button };
for (int i = 0; i < TOOL_MAX; i++) {
tb[i]->set_pressed(i == p_index);
}
- viewport->update();
tool = (Tool)p_index;
+ viewport->update();
}
void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, bool p_scale, bool p_on_existing) {
@@ -4308,6 +4559,27 @@ void CanvasItemEditor::_popup_callback(int p_op) {
}
} break;
+ case CLEAR_GUIDES: {
+
+ if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_") || EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
+ undo_redo->create_action(TTR("Clear Guides"));
+ if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
+ Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
+
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", Array());
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
+ }
+ if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
+ Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
+
+ undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", Array());
+ undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
+ }
+ undo_redo->add_undo_method(viewport, "update");
+ undo_redo->commit_action();
+ }
+
+ } break;
case VIEW_CENTER_TO_SELECTION:
case VIEW_FRAME_TO_SELECTION: {
@@ -4551,6 +4823,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
Dictionary state = p_state;
if (state.has("zoom")) {
zoom = p_state["zoom"];
+ _update_zoom_label();
}
if (state.has("ofs")) {
@@ -4784,6 +5057,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
panning = false;
pan_pressed = false;
+ ruler_tool_active = false;
+ ruler_tool_origin = Point2();
+
bone_last_frame = 0;
bone_list_dirty = false;
@@ -4865,6 +5141,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
zoom_hb = memnew(HBoxContainer);
viewport->add_child(zoom_hb);
zoom_hb->set_begin(Point2(5, 5));
+ // Bring the zoom percentage closer to the zoom buttons
+ zoom_hb->add_constant_override("separation", Math::round(-8 * EDSCALE));
zoom_minus = memnew(ToolButton);
zoom_hb->add_child(zoom_minus);
@@ -4877,6 +5155,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
zoom_reset->connect("pressed", this, "_button_zoom_reset");
zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0));
zoom_reset->set_focus_mode(FOCUS_NONE);
+ zoom_reset->set_text_align(Button::TextAlign::ALIGN_CENTER);
+ // Prevent the button's size from changing when the text size changes
+ zoom_reset->set_custom_minimum_size(Size2(75 * EDSCALE, 0));
zoom_plus = memnew(ToolButton);
zoom_hb->add_child(zoom_plus);
@@ -4937,6 +5218,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
pan_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PAN));
pan_button->set_tooltip(TTR("Pan Mode"));
+ ruler_button = memnew(ToolButton);
+ hb->add_child(ruler_button);
+ ruler_button->set_toggle_mode(true);
+ ruler_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_RULER));
+ ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), KEY_R));
+ ruler_button->set_tooltip(TTR("Ruler Mode"));
+
hb->add_child(memnew(VSeparator));
snap_button = memnew(ToolButton);
@@ -4957,11 +5245,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to Grid")), SNAP_USE_GRID);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
+
smartsnap_config_popup = memnew(PopupMenu);
p->add_child(smartsnap_config_popup);
smartsnap_config_popup->set_name("SmartSnapping");
@@ -5027,7 +5317,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SHOW_GRID);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show Helpers"), KEY_H), SHOW_HELPERS);
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers"), KEY_R), SHOW_RULERS);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers"), KEY_MASK_CMD | KEY_R), SHOW_RULERS);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT);
@@ -5036,6 +5326,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/clear_guides", TTR("Clear Guides")), CLEAR_GUIDES);
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_P), PREVIEW_CANVAS_SCALE);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index a46682d494..6cce1ca10e 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/label.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditorViewport;
@@ -83,12 +80,24 @@ public:
TOOL_ROTATE,
TOOL_EDIT_PIVOT,
TOOL_PAN,
+ TOOL_RULER,
TOOL_MAX
};
private:
EditorNode *editor;
+ enum SnapTarget {
+ SNAP_TARGET_NONE = 0,
+ SNAP_TARGET_PARENT,
+ SNAP_TARGET_SELF_ANCHORS,
+ SNAP_TARGET_SELF,
+ SNAP_TARGET_OTHER_NODE,
+ SNAP_TARGET_GUIDE,
+ SNAP_TARGET_GRID,
+ SNAP_TARGET_PIXEL
+ };
+
enum MenuOption {
SNAP_USE,
SNAP_USE_NODE_PARENT,
@@ -170,6 +179,7 @@ private:
ANIM_COPY_POSE,
ANIM_PASTE_POSE,
ANIM_CLEAR_POSE,
+ CLEAR_GUIDES,
VIEW_CENTER_TO_SELECTION,
VIEW_FRAME_TO_SELECTION,
PREVIEW_CANVAS_SCALE,
@@ -267,6 +277,9 @@ private:
bool panning;
bool pan_pressed;
+ bool ruler_tool_active;
+ Point2 ruler_tool_origin;
+
MenuOption last_option;
struct _SelectResult {
@@ -332,6 +345,8 @@ private:
ToolButton *pivot_button;
ToolButton *pan_button;
+ ToolButton *ruler_button;
+
ToolButton *snap_button;
MenuButton *snap_config_menu;
PopupMenu *smartsnap_config_popup;
@@ -371,6 +386,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;
@@ -441,10 +458,12 @@ private:
void _draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side);
void _draw_straight_line(Point2 p_from, Point2 p_to, Color p_color);
+ void _draw_smart_snapping();
void _draw_rulers();
void _draw_guides();
void _draw_focus();
void _draw_grid();
+ void _draw_ruler_tool();
void _draw_control_anchors(Control *control);
void _draw_control_helpers(Control *control);
void _draw_selection();
@@ -464,7 +483,8 @@ private:
bool _gui_input_resize(const Ref<InputEvent> &p_event);
bool _gui_input_rotate(const Ref<InputEvent> &p_event);
bool _gui_input_select(const Ref<InputEvent> &p_event);
- bool _gui_input_zoom_or_pan(const Ref<InputEvent> &p_event);
+ bool _gui_input_ruler_tool(const Ref<InputEvent> &p_event);
+ bool _gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bool p_already_accepted);
bool _gui_input_rulers_and_guides(const Ref<InputEvent> &p_event);
bool _gui_input_hover(const Ref<InputEvent> &p_event);
@@ -476,9 +496,25 @@ private:
void _solve_IK(Node2D *leaf_node, Point2 target_position);
- void _snap_if_closer_float(float p_value, float p_target_snap, float &r_current_snap, bool &r_snapped, float p_radius = 10.0);
- void _snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation = 0.0, float p_radius = 10.0);
- void _snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap = NULL);
+ SnapTarget snap_target[2];
+ Transform2D snap_transform;
+ void _snap_if_closer_float(
+ float p_value,
+ float &r_current_snap, SnapTarget &r_current_snap_target,
+ float p_target_value, SnapTarget p_snap_target,
+ float p_radius = 10.0);
+ void _snap_if_closer_point(
+ Point2 p_value,
+ Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
+ Point2 p_target_value, SnapTarget p_snap_target,
+ real_t rotation = 0.0,
+ float p_radius = 10.0);
+ void _snap_other_nodes(
+ const Point2 p_value,
+ const Transform2D p_transform_to_snap,
+ Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
+ const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions,
+ const Node *p_current);
void _set_anchors_preset(Control::LayoutPreset p_preset);
void _set_margins_preset(Control::LayoutPreset p_preset);
@@ -489,6 +525,7 @@ private:
HBoxContainer *zoom_hb;
void _zoom_on_position(float p_zoom, Point2 p_position = Point2());
+ void _update_zoom_label();
void _button_zoom_minus();
void _button_zoom_reset();
void _button_zoom_plus();
@@ -559,7 +596,7 @@ public:
SNAP_DEFAULT = SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL,
};
- Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, const CanvasItem *p_canvas_item = NULL, unsigned int p_forced_modes = 0);
+ Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, unsigned int p_forced_modes = 0, const CanvasItem *p_self_canvas_item = NULL, List<CanvasItem *> p_other_nodes_exceptions = List<CanvasItem *>());
float snap_angle(float p_target, float p_start = 0) const;
Transform2D get_canvas_transform() const { return transform; }
@@ -582,6 +619,7 @@ public:
void update_viewport();
Tool get_current_tool() { return tool; }
+ void set_current_tool(Tool p_tool);
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void edit(CanvasItem *p_canvas_item);
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index e15360d4e5..3f0734fb19 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/collision_polygon_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CollisionPolygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(CollisionPolygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index a699641aba..2a904a53ba 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -38,10 +38,6 @@
#include "scene/3d/mesh_instance.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CanvasItemEditor;
class Polygon3DEditor : public HBoxContainer {
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 7c2116f06b..9d625af959 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -87,8 +87,7 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
Ref<Image> img;
img.instance();
Error err = ImageLoader::load_image(source_emission_file, img);
- ERR_EXPLAIN(TTR("Error loading image:") + " " + source_emission_file);
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Error loading image: " + source_emission_file + ".");
if (img->is_compressed()) {
img->decompress();
@@ -196,8 +195,7 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
valid_normals.resize(vpc);
}
- ERR_EXPLAIN(TTR("No pixels with transparency > 128 in image..."));
- ERR_FAIL_COND(valid_positions.size() == 0);
+ ERR_FAIL_COND_MSG(valid_positions.size() == 0, "No pixels with transparency > 128 in image...");
if (capture_colors) {
PoolColorArray pca;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 5d3cef4c34..c2b6031e60 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -167,10 +167,20 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
_has_undo_data = true;
}
+ const float curve_amplitude = curve.get_max_value() - curve.get_min_value();
+ // Snap to "round" coordinates when holding Ctrl.
+ // Be more precise when holding Shift as well.
+ float snap_threshold;
+ if (mm.get_control()) {
+ snap_threshold = mm.get_shift() ? 0.025 : 0.1;
+ } else {
+ snap_threshold = 0.0;
+ }
+
if (_selected_tangent == TANGENT_NONE) {
// Drag point
- Vector2 point_pos = get_world_pos(mpos);
+ Vector2 point_pos = get_world_pos(mpos).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude));
int i = curve.set_point_offset(_selected_point, point_pos.x);
// The index may change if the point is dragged across another one
@@ -188,8 +198,8 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
} else {
// Drag tangent
- Vector2 point_pos = curve.get_point_position(_selected_point);
- Vector2 control_pos = get_world_pos(mpos);
+ const Vector2 point_pos = curve.get_point_position(_selected_point);
+ const Vector2 control_pos = get_world_pos(mpos).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude));
Vector2 dir = (control_pos - point_pos).normalized();
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index c8ffc2744a..8acc41a2c7 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -624,6 +624,7 @@ Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const S
uint8_t *imgw = imgdata.ptr();
Ref<AudioStreamPlayback> playback = stream->instance_playback();
+ ERR_FAIL_COND_V(playback.is_null(), Ref<Texture>());
float len_s = stream->get_length();
if (len_s == 0) {
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index 701632e576..78b176620e 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -39,10 +39,6 @@
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ItemListPlugin : public Object {
GDCLASS(ItemListPlugin, Object);
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 633fda7091..95fa0df2c1 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/light_occluder_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class LightOccluder2DEditor : public AbstractPolygon2DEditor {
GDCLASS(LightOccluder2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index ebacccb03c..e125c18ef1 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -34,9 +34,6 @@
void MaterialEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
- }
-
if (p_what == NOTIFICATION_READY) {
//get_scene()->connect("node_removed",this,"_node_removed");
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 6203035e25..442110cc84 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -48,9 +48,6 @@ void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
void MeshEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
- }
-
if (p_what == NOTIFICATION_READY) {
//get_scene()->connect("node_removed",this,"_node_removed");
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index e582f6ded2..1fc6dae978 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -201,6 +201,8 @@ void MeshLibraryEditor::_import_scene_cbk(const String &p_str) {
ERR_FAIL_COND(ps.is_null());
Node *scene = ps->instance();
+ ERR_FAIL_COND(!scene);
+
_import_scene(scene, mesh_library, option == MENU_OPTION_UPDATE_FROM_SCENE);
memdelete(scene);
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index d59efe49e7..3ea014a38d 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -147,9 +147,8 @@ void MultiMeshEditor::_populate() {
w.release();
PoolVector<Face3> faces = geometry;
- ERR_EXPLAIN(TTR("Parent has no solid faces to populate."));
int facecount = faces.size();
- ERR_FAIL_COND(!facecount);
+ ERR_FAIL_COND_MSG(!facecount, "Parent has no solid faces to populate.");
PoolVector<Face3>::Read r = faces.read();
@@ -164,10 +163,8 @@ void MultiMeshEditor::_populate() {
area_accum += area;
}
- ERR_EXPLAIN(TTR("Couldn't map area."));
- ERR_FAIL_COND(triangle_area_map.size() == 0);
- ERR_EXPLAIN(TTR("Couldn't map area."));
- ERR_FAIL_COND(area_accum == 0);
+ ERR_FAIL_COND_MSG(triangle_area_map.size() == 0, "Couldn't map area.");
+ ERR_FAIL_COND_MSG(area_accum == 0, "Couldn't map area.");
Ref<MultiMesh> multimesh = memnew(MultiMesh);
multimesh->set_mesh(mesh);
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index fe87a2b9cb..5323441bd8 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/multimesh_instance.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MultiMeshEditor : public Control {
GDCLASS(MultiMeshEditor, Control);
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 336c28d642..2a387a8b1e 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/navigation_polygon.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class NavigationPolygonEditor : public AbstractPolygon2DEditor {
GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index e68bca55cb..8025e12885 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -160,8 +160,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
Ref<Image> img;
img.instance();
Error err = ImageLoader::load_image(source_emission_file, img);
- ERR_EXPLAIN(TTR("Error loading image:") + " " + source_emission_file);
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Error loading image: " + source_emission_file + ".");
if (img->is_compressed()) {
img->decompress();
@@ -269,8 +268,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
valid_normals.resize(vpc);
}
- ERR_EXPLAIN(TTR("No pixels with transparency > 128 in image..."));
- ERR_FAIL_COND(valid_positions.size() == 0);
+ ERR_FAIL_COND_MSG(valid_positions.size() == 0, "No pixels with transparency > 128 in image...");
PoolVector<uint8_t> texdata;
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index 75d31459e8..31b0539bfe 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -55,8 +55,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (!triangle_area_map.size() || area_accum == 0) {
- err_dialog->set_text(TTR("Faces contain no area!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry's faces don't contain any area."));
return false;
}
@@ -90,8 +89,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (gcount == 0) {
- err_dialog->set_text(TTR("No faces!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry doesn't contain any faces."));
return false;
}
@@ -169,11 +167,16 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (!sel)
return;
+ if (!sel->is_class("Spatial")) {
+
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't inherit from Spatial."), sel->get_name()));
+ return;
+ }
+
VisualInstance *vi = Object::cast_to<VisualInstance>(sel);
if (!vi) {
- err_dialog->set_text(TTR("Node does not contain geometry."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain geometry."), sel->get_name()));
return;
}
@@ -181,8 +184,7 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (geometry.size() == 0) {
- err_dialog->set_text(TTR("Node does not contain geometry (faces)."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain face geometry."), sel->get_name()));
return;
}
@@ -231,9 +233,6 @@ ParticlesEditorBase::ParticlesEditorBase() {
emission_dialog->get_ok()->set_text(TTR("Create"));
emission_dialog->connect("confirmed", this, "_generate_emission_points");
- err_dialog = memnew(ConfirmationDialog);
- add_child(err_dialog);
-
emission_file_dialog = memnew(EditorFileDialog);
add_child(emission_file_dialog);
emission_file_dialog->connect("file_selected", this, "_resource_seleted");
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 5d05fbd4ac..1b3a1877a4 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/particles.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ParticlesEditorBase : public Control {
GDCLASS(ParticlesEditorBase, Control);
@@ -53,8 +49,6 @@ protected:
EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
- ConfirmationDialog *err_dialog;
-
ConfirmationDialog *emission_dialog;
SpinBox *emission_amount;
OptionButton *emission_fill;
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index b87bd29cbd..f02dc0bd6d 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -367,18 +367,18 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
- if (!node)
+ if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid())
return;
- if (!node->is_visible_in_tree())
- return;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- if (!node->get_curve().is_valid())
- return;
+ const Ref<Texture> path_sharp_handle = get_icon("EditorPathSharpHandle", "EditorIcons");
+ const Ref<Texture> path_smooth_handle = get_icon("EditorPathSmoothHandle", "EditorIcons");
+ // Both handle icons must be of the same size
+ const Size2 handle_size = path_sharp_handle->get_size();
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Size2 handle_size = handle->get_size();
+ const Ref<Texture> curve_handle = get_icon("EditorCurveHandle", "EditorIcons");
+ const Size2 curve_handle_size = curve_handle->get_size();
Ref<Curve2D> curve = node->get_curve();
@@ -387,19 +387,35 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < len; i++) {
Vector2 point = xform.xform(curve->get_point_position(i));
- vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false, Color(1, 1, 1, 1));
+ // Determines the point icon to be used
+ bool smooth = false;
if (i < len - 1) {
Vector2 pointout = xform.xform(curve->get_point_position(i) + curve->get_point_out(i));
- vpc->draw_line(point, pointout, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointout - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointout) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointout, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointout, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointout - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
if (i > 0) {
Vector2 pointin = xform.xform(curve->get_point_position(i) + curve->get_point_in(i));
- vpc->draw_line(point, pointin, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointin - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointin) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointin, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointin, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointin - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
+
+ vpc->draw_texture_rect(
+ smooth ? path_smooth_handle : path_sharp_handle,
+ Rect2(point - handle_size * 0.5, handle_size),
+ false);
}
if (on_edge) {
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 44472f7a81..ecec5f5253 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -36,9 +36,6 @@
#include "scene/2d/path_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class Path2DEditor : public HBoxContainer {
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 1ae5acc5ff..2493380585 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -652,7 +652,6 @@ PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
- path_color.a = 0.4;
- create_material("path_thin_material", path_color);
+ create_material("path_thin_material", Color(0.5, 0.5, 0.5));
create_handle_material("handles");
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 712b1a0ae4..bd532a6418 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;
}
}
@@ -1045,8 +1045,8 @@ void Polygon2DEditor::_uv_draw() {
}
}
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Ref<Texture> internal_handle = get_icon("EditorInternalHandle", "EditorIcons");
+ // All UV points are sharp, so use the sharp handle icon
+ Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
Color poly_line_color = Color(0.9, 0.5, 0.5);
if (polygons.size() || polygon_create.size()) {
@@ -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,12 +1115,13 @@ 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);
} else {
- uv_edit_draw->draw_texture(internal_handle, mtx.xform(uvs[i]) - internal_handle->get_size() * 0.5);
+ // Internal vertex
+ uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
}
}
}
@@ -1129,21 +1130,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 +1172,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 +1182,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/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 24ca2ea3f4..009501a70c 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -33,9 +33,7 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/gui/scroll_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index b8d95efd49..620bf28415 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -39,9 +39,6 @@ void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
void ResourcePreloaderEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
- }
-
if (p_what == NOTIFICATION_ENTER_TREE) {
load->set_icon(get_icon("Folder", "EditorIcons"));
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index d999f3189e..4c22138a20 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -44,6 +44,7 @@
#include "editor/script_editor_debugger.h"
#include "scene/main/viewport.h"
#include "script_text_editor.h"
+#include "text_editor.h"
/*** SCRIPT EDITOR ****/
@@ -55,7 +56,7 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("request_save_history"));
ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
- // TODO This signal is no use for VisualScript...
+ // TODO: This signal is no use for VisualScript.
ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
}
@@ -204,11 +205,13 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
connect("confirmed", this, "_confirmed");
- search_box->set_right_icon(get_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
+ FALLTHROUGH;
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
} break;
case NOTIFICATION_EXIT_TREE: {
disconnect("confirmed", this, "_confirmed");
@@ -241,6 +244,8 @@ ScriptEditorQuickOpen::ScriptEditorQuickOpen() {
set_hide_on_ok(false);
search_options->connect("item_activated", this, "_confirmed");
search_options->set_hide_root(true);
+ search_options->set_hide_folding(true);
+ search_options->add_constant_override("draw_guides", 1);
}
/////////////////////////////////
@@ -485,9 +490,6 @@ void ScriptEditor::_update_recent_scripts() {
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
recent_scripts->clear();
- recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T));
- recent_scripts->add_separator();
-
String path;
for (int i = 0; i < rc.size(); i++) {
@@ -510,11 +512,6 @@ void ScriptEditor::_open_recent_script(int p_idx) {
return;
}
- // take two for the open recent button
- if (p_idx > 0) {
- p_idx -= 2;
- }
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
ERR_FAIL_INDEX(p_idx, rc.size());
@@ -541,6 +538,14 @@ void ScriptEditor::_open_recent_script(int p_idx) {
// if it's a path then it's most likely a deleted file not help
} else if (path.find("::") != -1) {
// built-in script
+ String res_path = path.get_slice("::", 0);
+ if (ResourceLoader::get_resource_type(res_path) == "PackedScene") {
+ if (!EditorNode::get_singleton()->is_scene_open(res_path)) {
+ EditorNode::get_singleton()->load_scene(res_path);
+ }
+ } else {
+ EditorNode::get_singleton()->load_resource(res_path);
+ }
Ref<Script> script = ResourceLoader::load(path);
if (script.is_valid()) {
edit(script, true);
@@ -579,6 +584,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
Ref<Script> script = current->get_edited_resource();
if (script != NULL) {
+ previous_scripts.push_back(script->get_path());
notify_script_close(script);
}
}
@@ -907,7 +913,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
if (extensions.find(p_file.get_extension())) {
Ref<Script> scr = ResourceLoader::load(p_file);
if (!scr.is_valid()) {
- editor->show_warning(TTR("Error: could not load file."), TTR("Error!"));
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
file_dialog_option = -1;
return;
}
@@ -920,7 +926,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
Error error;
Ref<TextFile> text_file = _load_text_file(p_file, &error);
if (error != OK) {
- editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
}
if (text_file.is_valid()) {
@@ -994,7 +1000,7 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->clear_filters();
file_dialog->popup_centered_ratio();
- file_dialog->set_title(TTR("New TextFile..."));
+ file_dialog->set_title(TTR("New Text File..."));
} break;
case FILE_OPEN: {
file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -1012,6 +1018,56 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->set_title(TTR("Open File"));
return;
} break;
+ case FILE_REOPEN_CLOSED: {
+
+ if (previous_scripts.empty())
+ return;
+
+ String path = previous_scripts.back()->get();
+ previous_scripts.pop_back();
+
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ bool built_in = !path.is_resource_file();
+
+ if (extensions.find(path.get_extension()) || built_in) {
+ if (built_in) {
+ String res_path = path.get_slice("::", 0);
+ if (ResourceLoader::get_resource_type(res_path) == "PackedScene") {
+ if (!EditorNode::get_singleton()->is_scene_open(res_path)) {
+ EditorNode::get_singleton()->load_scene(res_path);
+ script_editor->call_deferred("_menu_option", p_option);
+ previous_scripts.push_back(path); //repeat the operation
+ return;
+ }
+ } else {
+ EditorNode::get_singleton()->load_resource(res_path);
+ }
+ }
+
+ Ref<Script> scr = ResourceLoader::load(path);
+ if (!scr.is_valid()) {
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+ file_dialog_option = -1;
+ return;
+ }
+
+ edit(scr);
+ file_dialog_option = -1;
+ return;
+ } else {
+ Error error;
+ Ref<TextFile> text_file = _load_text_file(path, &error);
+ if (error != OK)
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+
+ if (text_file.is_valid()) {
+ edit(text_file);
+ file_dialog_option = -1;
+ return;
+ }
+ }
+ } break;
case FILE_SAVE_ALL: {
if (_test_script_times_on_disk())
@@ -1020,6 +1076,7 @@ void ScriptEditor::_menu_option(int p_option) {
save_all_scripts();
} break;
case SEARCH_IN_FILES: {
+
_on_find_in_files_requested("");
} break;
case SEARCH_HELP: {
@@ -1372,15 +1429,25 @@ void ScriptEditor::_notification(int p_what) {
}
EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed");
+ FALLTHROUGH;
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+
help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
site_search->set_icon(get_icon("Instance", "EditorIcons"));
request_docs->set_icon(get_icon("Issue", "EditorIcons"));
script_forward->set_icon(get_icon("Forward", "EditorIcons"));
script_back->set_icon(get_icon("Back", "EditorIcons"));
+
members_overview_alphabeta_sort_button->set_icon(get_icon("Sort", "EditorIcons"));
+
filter_scripts->set_right_icon(get_icon("Search", "EditorIcons"));
filter_methods->set_right_icon(get_icon("Search", "EditorIcons"));
+
+ filename->add_style_override("normal", editor->get_gui_base()->get_stylebox("normal", "LineEdit"));
+
+ recent_scripts->set_as_minsize();
} break;
case NOTIFICATION_READY: {
@@ -1403,20 +1470,6 @@ void ScriptEditor::_notification(int p_what) {
_update_modified_scripts_for_external_editor();
} break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
- help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
- site_search->set_icon(get_icon("Instance", "EditorIcons"));
-
- script_forward->set_icon(get_icon("Forward", "EditorIcons"));
- script_back->set_icon(get_icon("Back", "EditorIcons"));
-
- members_overview_alphabeta_sort_button->set_icon(get_icon("Sort", "EditorIcons"));
- filename->add_style_override("normal", editor->get_gui_base()->get_stylebox("normal", "LineEdit"));
-
- recent_scripts->set_as_minsize();
- } break;
-
case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
@@ -1700,10 +1753,10 @@ void ScriptEditor::_update_help_overview() {
void ScriptEditor::_update_script_colors() {
- bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled");
- bool highlight_current = EditorSettings::get_singleton()->get("text_editor/open_scripts/highlight_current_script");
+ bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_enabled");
+ bool highlight_current = EditorSettings::get_singleton()->get("text_editor/script_list/highlight_current_script");
- int hist_size = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_history_size");
+ int hist_size = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_history_size");
Color hot_color = get_color("accent_color", "Editor");
Color cold_color = get_color("font_color", "Editor");
@@ -1718,7 +1771,7 @@ void ScriptEditor::_update_script_colors() {
bool current = tab_container->get_current_tab() == c;
if (current && highlight_current) {
- script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/open_scripts/current_script_background_color"));
+ script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/script_list/current_script_background_color"));
} else if (script_temperature_enabled) {
@@ -1751,9 +1804,9 @@ void ScriptEditor::_update_script_names() {
}
script_list->clear();
- bool split_script_help = EditorSettings::get_singleton()->get("text_editor/open_scripts/group_help_pages");
- ScriptSortBy sort_by = (ScriptSortBy)(int)EditorSettings::get_singleton()->get("text_editor/open_scripts/sort_scripts_by");
- ScriptListName display_as = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/open_scripts/list_script_names_as");
+ bool split_script_help = EditorSettings::get_singleton()->get("text_editor/script_list/group_help_pages");
+ ScriptSortBy sort_by = (ScriptSortBy)(int)EditorSettings::get_singleton()->get("text_editor/script_list/sort_scripts_by");
+ ScriptListName display_as = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as");
Vector<_ScriptEditorItemData> sedata;
@@ -1894,6 +1947,8 @@ void ScriptEditor::_update_script_names() {
_update_members_overview_visibility();
_update_help_overview_visibility();
_update_script_colors();
+
+ file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.empty());
}
void ScriptEditor::_update_script_connections() {
@@ -2088,16 +2143,18 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
}
ERR_FAIL_COND_V(!se, false);
- bool highlighter_set = false;
- for (int i = 0; i < syntax_highlighters_func_count; i++) {
- SyntaxHighlighter *highlighter = syntax_highlighters_funcs[i]();
- se->add_syntax_highlighter(highlighter);
-
- if (script != NULL && !highlighter_set) {
- List<String> languages = highlighter->get_supported_languages();
- if (languages.find(script->get_language()->get_name())) {
- se->set_syntax_highlighter(highlighter);
- highlighter_set = true;
+ if (p_resource->get_class_name() != StringName("VisualScript")) {
+ bool highlighter_set = false;
+ for (int i = 0; i < syntax_highlighters_func_count; i++) {
+ SyntaxHighlighter *highlighter = syntax_highlighters_funcs[i]();
+ se->add_syntax_highlighter(highlighter);
+
+ if (script != NULL && !highlighter_set) {
+ List<String> languages = highlighter->get_supported_languages();
+ if (languages.find(script->get_language()->get_name())) {
+ se->set_syntax_highlighter(highlighter);
+ highlighter_set = true;
+ }
}
}
}
@@ -2273,7 +2330,7 @@ void ScriptEditor::_editor_settings_changed() {
convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save");
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type");
- members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
+ members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/show_members_overview");
help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index");
_update_members_overview_visibility();
_update_help_overview_visibility();
@@ -2937,18 +2994,38 @@ void ScriptEditor::_on_find_in_files_requested(String text) {
void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) {
- RES res = ResourceLoader::load(fpath);
- if (fpath.get_extension() == "shader") {
- ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
- shader_editor->edit(res.ptr());
- shader_editor->make_visible(true);
- shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
- } else {
- edit(res);
+ if (ResourceLoader::exists(fpath)) {
+ RES res = ResourceLoader::load(fpath);
- ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor());
- if (ste) {
- ste->goto_line_selection(line_number - 1, begin, end);
+ if (fpath.get_extension() == "shader") {
+ ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
+ shader_editor->edit(res.ptr());
+ shader_editor->make_visible(true);
+ shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
+ return;
+ } else {
+ Ref<Script> script = res;
+ if (script.is_valid()) {
+ edit(script);
+
+ ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(_get_current_editor());
+ if (ste) {
+ ste->goto_line_selection(line_number - 1, begin, end);
+ }
+ return;
+ }
+ }
+ }
+
+ // If the file is not a valid resource/script, load it as a text file.
+ Error err;
+ Ref<TextFile> text_file = _load_text_file(fpath, &err);
+ if (text_file.is_valid()) {
+ edit(text_file);
+
+ TextEditor *te = Object::cast_to<TextEditor>(_get_current_editor());
+ if (te) {
+ te->goto_line_selection(line_number - 1, begin, end);
}
}
}
@@ -3064,7 +3141,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
waiting_update_names = false;
pending_auto_reload = false;
auto_reload_running_scripts = true;
- members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
+ members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/show_members_overview");
help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index");
editor = p_editor;
@@ -3168,8 +3245,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->set_switch_on_hover(true);
file_menu->get_popup()->set_hide_on_window_lose_focus(true);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script...")), FILE_NEW);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New TextFile...")), FILE_NEW_TEXTFILE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File...")), FILE_NEW_TEXTFILE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T), FILE_REOPEN_CLOSED);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
recent_scripts = memnew(PopupMenu);
@@ -3200,17 +3278,20 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
theme_submenu->connect("id_pressed", this, "_theme_option");
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme...")), THEME_IMPORT);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), THEME_RELOAD);
+
theme_submenu->add_separator();
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), THEME_SAVE);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As...")), THEME_SAVE_AS);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_other_tabs", TTR("Close Other Tabs")), CLOSE_OTHER_TABS);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X), FILE_RUN);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KEY_MASK_CMD | KEY_BACKSLASH), TOGGLE_SCRIPTS_PANEL);
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -3227,8 +3308,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
debug_menu->set_text(TTR("Debug"));
debug_menu->set_switch_on_hover(true);
debug_menu->get_popup()->set_hide_on_window_lose_focus(true);
- debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11), DEBUG_STEP);
+ debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT);
debug_menu->get_popup()->add_separator();
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/break", TTR("Break")), DEBUG_BREAK);
debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/continue", TTR("Continue"), KEY_F12), DEBUG_CONTINUE);
@@ -3390,15 +3471,18 @@ void ScriptEditorPlugin::edit(Object *p_object) {
if (Object::cast_to<Script>(p_object)) {
Script *p_script = Object::cast_to<Script>(p_object);
- String scene_path = p_script->get_path().get_slice("::", 0);
+ String res_path = p_script->get_path().get_slice("::", 0);
- if (_is_built_in_script(p_script) && !EditorNode::get_singleton()->is_scene_open(scene_path)) {
- EditorNode::get_singleton()->load_scene(scene_path);
-
- script_editor->call_deferred("edit", p_script);
- } else {
- script_editor->edit(p_script);
+ if (_is_built_in_script(p_script)) {
+ if (ResourceLoader::get_resource_type(res_path) == "PackedScene") {
+ if (!EditorNode::get_singleton()->is_scene_open(res_path)) {
+ EditorNode::get_singleton()->load_scene(res_path);
+ }
+ } else {
+ EditorNode::get_singleton()->load_resource(res_path);
+ }
}
+ script_editor->edit(p_script);
} else if (Object::cast_to<TextFile>(p_object)) {
script_editor->edit(Object::cast_to<TextFile>(p_object));
}
@@ -3485,21 +3569,21 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/files/open_dominant_script_on_scene_change", true);
EDITOR_DEF("text_editor/external/use_external_editor", false);
EDITOR_DEF("text_editor/external/exec_path", "");
- EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
- EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
- EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
- EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.3));
- EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path,None"));
- EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0);
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/list_script_names_as", PROPERTY_HINT_ENUM, "Name,Parent Directory And Name,Full Path"));
- EDITOR_DEF("text_editor/open_scripts/list_script_names_as", 0);
+ EDITOR_DEF("text_editor/script_list/script_temperature_enabled", true);
+ EDITOR_DEF("text_editor/script_list/highlight_current_script", true);
+ EDITOR_DEF("text_editor/script_list/script_temperature_history_size", 15);
+ EDITOR_DEF("text_editor/script_list/current_script_background_color", Color(1, 1, 1, 0.3));
+ EDITOR_DEF("text_editor/script_list/group_help_pages", true);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/script_list/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path,None"));
+ EDITOR_DEF("text_editor/script_list/sort_scripts_by", 0);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/script_list/list_script_names_as", PROPERTY_HINT_ENUM, "Name,Parent Directory And Name,Full Path"));
+ EDITOR_DEF("text_editor/script_list/list_script_names_as", 0);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_path", PROPERTY_HINT_GLOBAL_FILE));
EDITOR_DEF("text_editor/external/exec_flags", "{file}");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
- ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
- ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"));
+ ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
+ ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Scripts"));
}
ScriptEditorPlugin::~ScriptEditorPlugin() {
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 4ad2156779..0c876108a5 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -139,6 +139,7 @@ class ScriptEditor : public PanelContainer {
FILE_NEW,
FILE_NEW_TEXTFILE,
FILE_OPEN,
+ FILE_REOPEN_CLOSED,
FILE_OPEN_RECENT,
FILE_SAVE,
FILE_SAVE_AS,
@@ -265,7 +266,7 @@ class ScriptEditor : public PanelContainer {
Vector<ScriptHistory> history;
int history_pos;
- Vector<String> previous_scripts;
+ List<String> previous_scripts;
void _tab_changed(int p_which);
void _menu_option(int p_option);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 438621115b..073e6f74e9 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,6 +30,7 @@
#include "script_text_editor.h"
+#include "core/math/expression.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@@ -1147,6 +1148,32 @@ void ScriptTextEditor::_edit_option(int p_op) {
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
+ case EDIT_EVALUATE: {
+
+ Expression expression;
+ Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
+ PoolStringArray results;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning
+
+ if (expression.parse(line) == OK) {
+ Variant result = expression.execute(Array(), Variant(), false);
+ if (expression.get_error_text() == "") {
+ results.append(whitespace + (String)result);
+ } else {
+ results.append(line);
+ }
+ } else {
+ results.append(line);
+ }
+ }
+
+ code_editor->get_text_edit()->begin_complex_operation(); //prevents creating a two-step undo
+ code_editor->get_text_edit()->insert_text_at_cursor(results.join("\n"));
+ code_editor->get_text_edit()->end_complex_operation();
+ } break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1170,7 +1197,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
// Yep, because it doesn't make sense to instance this dialog for every single script open...
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
-
} break;
case SEARCH_LOCATE_FUNCTION: {
@@ -1410,8 +1436,6 @@ bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_
return false;
}
-#ifdef TOOLS_ENABLED
-
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
@@ -1431,14 +1455,6 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
return NULL;
}
-#else
-
-static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- return NULL;
-}
-#endif
-
void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
Dictionary d = p_data;
@@ -1516,91 +1532,98 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
Ref<InputEventMouseButton> mb = ev;
+ Ref<InputEventKey> k = ev;
+ Point2 local_pos;
+ bool create_menu = false;
- if (mb.is_valid()) {
-
- if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
- int col, row;
- TextEdit *tx = code_editor->get_text_edit();
- tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
- Vector2 mpos = mb->get_global_position() - tx->get_global_position();
-
- tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
- if (tx->is_right_click_moving_caret()) {
- if (tx->is_selection_active()) {
+ TextEdit *tx = code_editor->get_text_edit();
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
+ local_pos = mb->get_global_position() - tx->get_global_position();
+ create_menu = true;
+ } else if (k.is_valid() && k->get_scancode() == KEY_MENU) {
+ local_pos = tx->_get_cursor_pixel_pos();
+ create_menu = true;
+ }
- int from_line = tx->get_selection_from_line();
- int to_line = tx->get_selection_to_line();
- int from_column = tx->get_selection_from_column();
- int to_column = tx->get_selection_to_column();
+ if (create_menu) {
+ int col, row;
+ tx->_get_mouse_pos(local_pos, row, col);
- if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
- tx->deselect();
- }
- }
- if (!tx->is_selection_active()) {
- tx->cursor_set_line(row, true, false);
- tx->cursor_set_column(col);
+ tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
+ if (tx->is_right_click_moving_caret()) {
+ if (tx->is_selection_active()) {
+ int from_line = tx->get_selection_from_line();
+ int to_line = tx->get_selection_to_line();
+ int from_column = tx->get_selection_from_column();
+ int to_column = tx->get_selection_to_column();
+
+ if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
+ // Right click is outside the selected text
+ tx->deselect();
}
}
+ if (!tx->is_selection_active()) {
+ tx->cursor_set_line(row, true, false);
+ tx->cursor_set_column(col);
+ }
+ }
- String word_at_mouse = tx->get_word_at_pos(mpos);
- if (word_at_mouse == "")
- word_at_mouse = tx->get_word_under_cursor();
- if (word_at_mouse == "")
- word_at_mouse = tx->get_selection_text();
+ String word_at_pos = tx->get_word_at_pos(local_pos);
+ if (word_at_pos == "")
+ word_at_pos = tx->get_word_under_cursor();
+ if (word_at_pos == "")
+ word_at_pos = tx->get_selection_text();
- bool has_color = (word_at_mouse == "Color");
- bool foldable = tx->can_fold(row) || tx->is_folded(row);
- bool open_docs = false;
- bool goto_definition = false;
+ bool has_color = (word_at_pos == "Color");
+ bool foldable = tx->can_fold(row) || tx->is_folded(row);
+ bool open_docs = false;
+ bool goto_definition = false;
- if (word_at_mouse.is_resource_file()) {
+ if (word_at_pos.is_resource_file()) {
+ open_docs = true;
+ } else {
+ Node *base = get_tree()->get_edited_scene_root();
+ if (base) {
+ base = _find_node_for_script(base, base, script);
+ }
+ ScriptLanguage::LookupResult result;
+ if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), word_at_pos, script->get_path(), base, result) == OK) {
open_docs = true;
- } else {
-
- Node *base = get_tree()->get_edited_scene_root();
- if (base) {
- base = _find_node_for_script(base, base, script);
- }
- ScriptLanguage::LookupResult result;
- if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), word_at_mouse, script->get_path(), base, result) == OK) {
- open_docs = true;
- }
}
+ }
- if (has_color) {
- String line = tx->get_line(row);
- color_line = row;
- int begin = 0;
- int end = 0;
- bool valid = false;
- for (int i = col; i < line.length(); i++) {
- if (line[i] == '(') {
- begin = i;
- continue;
- } else if (line[i] == ')') {
- end = i + 1;
- valid = true;
- break;
- }
+ if (has_color) {
+ String line = tx->get_line(row);
+ color_position.x = row;
+ color_position.y = col;
+
+ int begin = 0;
+ int end = 0;
+ bool valid = false;
+ for (int i = col; i < line.length(); i++) {
+ if (line[i] == '(') {
+ begin = i;
+ continue;
+ } else if (line[i] == ')') {
+ end = i + 1;
+ valid = true;
+ break;
}
- if (valid) {
- color_args = line.substr(begin, end - begin);
- String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
- Vector<float> color = stripped.split_floats(",");
- if (color.size() > 2) {
- float alpha = color.size() > 3 ? color[3] : 1.0f;
- color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
- }
- color_panel->set_position(get_global_transform().xform(get_local_mouse_position()));
- } else {
- has_color = false;
+ }
+ if (valid) {
+ color_args = line.substr(begin, end - begin);
+ String stripped = color_args.replace(" ", "").replace("(", "").replace(")", "");
+ Vector<float> color = stripped.split_floats(",");
+ if (color.size() > 2) {
+ float alpha = color.size() > 3 ? color[3] : 1.0f;
+ color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
}
+ color_panel->set_position(get_global_transform().xform(local_pos));
+ } else {
+ has_color = false;
}
- _make_context_menu(tx->is_selection_active(), has_color, foldable, open_docs, goto_definition);
}
+ _make_context_menu(tx->is_selection_active(), has_color, foldable, open_docs, goto_definition, local_pos);
}
}
@@ -1612,25 +1635,33 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
new_args = String("(" + rtos(p_color.r) + ", " + rtos(p_color.g) + ", " + rtos(p_color.b) + ", " + rtos(p_color.a) + ")");
}
- String line = code_editor->get_text_edit()->get_line(color_line);
- String new_line = line.replace(color_args, new_args);
+ String line = code_editor->get_text_edit()->get_line(color_position.x);
+ int color_args_pos = line.find(color_args, color_position.y);
+ String line_with_replaced_args = line;
+ line_with_replaced_args.erase(color_args_pos, color_args.length());
+ line_with_replaced_args = line_with_replaced_args.insert(color_args_pos, new_args);
+
color_args = new_args;
- code_editor->get_text_edit()->set_line(color_line, new_line);
+ code_editor->get_text_edit()->begin_complex_operation();
+ code_editor->get_text_edit()->set_line(color_position.x, line_with_replaced_args);
+ code_editor->get_text_edit()->end_complex_operation();
+ code_editor->get_text_edit()->update();
}
-void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
+void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) {
context_menu->clear();
- if (p_selection) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- }
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
@@ -1641,6 +1672,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
}
if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
@@ -1653,7 +1685,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
}
- context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ context_menu->set_position(get_global_transform().xform(p_pos));
context_menu->set_size(Vector2(1, 1));
context_menu->popup();
}
@@ -1710,9 +1742,17 @@ ScriptTextEditor::ScriptTextEditor() {
color_panel = memnew(PopupPanel);
add_child(color_panel);
color_picker = memnew(ColorPicker);
+ color_picker->set_deferred_mode(true);
color_panel->add_child(color_picker);
color_picker->connect("color_changed", this, "_color_changed");
+ // get default color picker mode from editor settings
+ int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
+ if (default_color_mode == 1)
+ color_picker->set_hsv_mode(true);
+ else if (default_color_mode == 2)
+ color_picker->set_raw_mode(true);
+
edit_hb = memnew(HBoxContainer);
edit_menu = memnew(MenuButton);
@@ -1740,6 +1780,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
@@ -1776,11 +1817,7 @@ ScriptTextEditor::ScriptTextEditor() {
search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION);
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
- search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL);
-
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
edit_hb->add_child(edit_menu);
@@ -1789,6 +1826,11 @@ ScriptTextEditor::ScriptTextEditor() {
edit_hb->add_child(goto_menu);
goto_menu->set_text(TTR("Go To"));
goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION);
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
bookmarks_menu = memnew(PopupMenu);
bookmarks_menu->set_name("Bookmarks");
@@ -1819,6 +1861,15 @@ ScriptTextEditor::ScriptTextEditor() {
code_editor->get_text_edit()->set_drag_forwarding(this);
}
+ScriptTextEditor::~ScriptTextEditor() {
+ for (const Map<String, SyntaxHighlighter *>::Element *E = highlighters.front(); E; E = E->next()) {
+ if (E->get() != NULL) {
+ memdelete(E->get());
+ }
+ }
+ highlighters.clear();
+}
+
static ScriptEditorBase *create_editor(const RES &p_resource) {
if (Object::cast_to<Script>(*p_resource)) {
@@ -1839,16 +1890,12 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN);
ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K);
- //leave these at zero, same can be accomplished with tab/shift-tab, including selection
- //the next/previous in history shortcut in this case makes a lot more sene.
+ // Leave these at zero, same can be accomplished with tab/shift-tab, including selection.
+ // The next/previous in history shortcut in this case makes a lot more sense.
ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0);
ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0);
ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K);
- ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B);
- ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B);
- ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
- ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0);
ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KEY_MASK_ALT | KEY_F);
ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0);
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
@@ -1859,20 +1906,12 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D);
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
+ ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E);
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I);
-#ifdef OSX_ENABLED
- ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
-#else
- ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
-#endif
- ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
- ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
- ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
-
ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G);
@@ -1887,6 +1926,17 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
#ifdef OSX_ENABLED
+ ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
+#else
+ ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_F1);
+#endif
+
+ ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B);
+ ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B);
+ ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
+ ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0);
+
+#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J);
#else
ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
@@ -1894,10 +1944,13 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KEY_MASK_CMD | KEY_L);
#ifdef OSX_ENABLED
- ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
+ ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B);
#else
- ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_F1);
+ ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
#endif
+ ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
+ ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
+ ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
ScriptEditor::register_create_script_editor_function(create_editor);
}
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 9a2a514a6e..0ea8726ecc 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -81,7 +81,7 @@ class ScriptTextEditor : public ScriptEditorBase {
PopupPanel *color_panel;
ColorPicker *color_picker;
- int color_line;
+ Vector2 color_position;
String color_args;
void _update_member_keywords();
@@ -120,6 +120,7 @@ class ScriptTextEditor : public ScriptEditorBase {
EDIT_TO_UPPERCASE,
EDIT_TO_LOWERCASE,
EDIT_CAPITALIZE,
+ EDIT_EVALUATE,
EDIT_TOGGLE_FOLD_LINE,
EDIT_FOLD_ALL_LINES,
EDIT_UNFOLD_ALL_LINES,
@@ -168,7 +169,7 @@ protected:
void _edit_option(int p_op);
void _edit_option_toggle_inline_comment();
- void _make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition);
+ void _make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
void _color_changed(const Color &p_color);
@@ -231,6 +232,7 @@ public:
virtual void validate();
ScriptTextEditor();
+ ~ScriptTextEditor();
};
#endif // SCRIPT_TEXT_EDITOR_H
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 994c542187..df3e23a9e9 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -55,6 +55,7 @@ void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) {
_load_theme_settings();
get_text_edit()->set_text(p_shader->get_code());
+ get_text_edit()->clear_undo_history();
_validate_script();
_line_col_changed();
@@ -342,6 +343,9 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->remove_all_bookmarks();
} break;
+ case HELP_DOCS: {
+ OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html");
+ } break;
}
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
shader_editor->get_text_edit()->call_deferred("grab_focus");
@@ -368,7 +372,7 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type"));
shader_editor->get_text_edit()->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent"));
shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
- shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
+ shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers"));
shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences"));
shader_editor->get_text_edit()->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
@@ -376,8 +380,8 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing"));
shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
- shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
- shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
+ shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/navigation/smooth_scrolling"));
+ shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/navigation/v_scroll_speed"));
}
void ShaderEditor::_bind_methods() {
@@ -519,26 +523,33 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->cursor_set_column(col);
}
}
- _make_context_menu(tx->is_selection_active());
+ _make_context_menu(tx->is_selection_active(), get_local_mouse_position());
}
}
+
+ Ref<InputEventKey> k = ev;
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_MENU) {
+ TextEdit *tx = shader_editor->get_text_edit();
+ _make_context_menu(tx->is_selection_active(), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->_get_cursor_pixel_pos()));
+ context_menu->grab_focus();
+ }
}
void ShaderEditor::_update_bookmark_list() {
- bookmarks_menu->get_popup()->clear();
+ bookmarks_menu->clear();
- 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 = shader_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 = shader_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
@@ -547,21 +558,21 @@ void ShaderEditor::_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 ShaderEditor::_bookmark_item_pressed(int p_idx) {
if (p_idx < 4) { // Any item before the separator.
- _menu_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ _menu_option(bookmarks_menu->get_item_id(p_idx));
} else {
- shader_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ shader_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx));
}
}
-void ShaderEditor::_make_context_menu(bool p_selection) {
+void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
context_menu->clear();
if (p_selection) {
@@ -581,7 +592,7 @@ void ShaderEditor::_make_context_menu(bool p_selection) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ context_menu->set_position(get_global_transform().xform(p_position));
context_menu->set_size(Vector2(1, 1));
context_menu->popup();
}
@@ -646,22 +657,36 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
- search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
- bookmarks_menu = memnew(MenuButton);
- bookmarks_menu->set_text(TTR("Bookmarks"));
- bookmarks_menu->set_switch_on_hover(true);
+ MenuButton *goto_menu = memnew(MenuButton);
+ goto_menu->set_text(TTR("Go To"));
+ goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
+
+ 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");
+
+ help_menu = memnew(MenuButton);
+ help_menu->set_text(TTR("Help"));
+ help_menu->set_switch_on_hover(true);
+ help_menu->get_popup()->add_icon_item(p_node->get_gui_base()->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
+ help_menu->get_popup()->connect("id_pressed", this, "_menu_option");
add_child(main_container);
main_container->add_child(hbc);
hbc->add_child(search_menu);
hbc->add_child(edit_menu);
- hbc->add_child(bookmarks_menu);
+ hbc->add_child(goto_menu);
+ hbc->add_child(help_menu);
hbc->add_style_override("panel", p_node->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
main_container->add_child(shader_editor);
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 8e55a1ad70..ca9f489713 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -94,13 +94,13 @@ class ShaderEditor : public PanelContainer {
BOOKMARK_GOTO_NEXT,
BOOKMARK_GOTO_PREV,
BOOKMARK_REMOVE_ALL,
-
+ HELP_DOCS,
};
MenuButton *edit_menu;
MenuButton *search_menu;
- MenuButton *bookmarks_menu;
- MenuButton *settings_menu;
+ PopupMenu *bookmarks_menu;
+ MenuButton *help_menu;
PopupMenu *context_menu;
uint64_t idle;
@@ -122,7 +122,7 @@ class ShaderEditor : public PanelContainer {
protected:
void _notification(int p_what);
static void _bind_methods();
- void _make_context_menu(bool p_selection);
+ void _make_context_menu(bool p_selection, Vector2 p_position);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
void _update_bookmark_list();
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 9fd694ee0d..18049e62b4 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -69,19 +69,11 @@
#define FREELOOK_SPEED_MULTIPLIER 1.08
#define MIN_Z 0.01
-#define MAX_Z 10000
+#define MAX_Z 1000000.0
#define MIN_FOV 0.01
#define MAX_FOV 179
-#ifdef TOOLS_ENABLED
-#define get_global_gizmo_transform get_global_gizmo_transform
-#define get_local_gizmo_transform get_local_gizmo_transform
-#else
-#define get_global_gizmo_transform get_global_transform
-#define get_local_gizmo_transform get_transform
-#endif
-
void SpatialEditorViewport::_update_camera(float p_interp_delta) {
bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;
@@ -250,15 +242,7 @@ Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const {
return camera->project_ray_normal(p_pos / viewport_container->get_stretch_shrink());
}
-/*
-void SpatialEditorViewport::_clear_id(Spatial *p_node) {
-
-
- editor_selection->remove_node(p_node);
-
-}
-*/
void SpatialEditorViewport::_clear_selected() {
editor_selection->clear();
@@ -283,7 +267,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 +498,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 +521,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())
@@ -642,7 +629,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 r;
- if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
+ if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
float d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
@@ -750,7 +737,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 r;
- if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
+ if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
float d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
@@ -833,7 +820,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());
@@ -1286,6 +1275,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 ray_pos = _get_ray_pos(m->get_position());
Vector3 ray = _get_ray(m->get_position());
+ float snap = EDITOR_GET("interface/inspector/default_float_step");
+ int snap_step_decimals = Math::range_step_decimals(snap);
switch (_edit.mode) {
@@ -1367,18 +1358,14 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
- float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
-
snap = spatial_editor->get_scale_snap() / 100;
-
- Vector3 motion_snapped = motion;
- motion_snapped.snap(Vector3(snap, snap, snap));
- set_message(TTR("Scaling: ") + motion_snapped);
-
- } else {
- set_message(TTR("Scaling: ") + motion);
}
+ Vector3 motion_snapped = motion;
+ motion_snapped.snap(Vector3(snap, snap, snap));
+ // This might not be necessary anymore after issue #288 is solved (in 4.0?).
+ set_message(TTR("Scaling: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
+ String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
@@ -1497,17 +1484,13 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
// Disable local transformation for TRANSFORM_VIEW
bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
- float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
-
snap = spatial_editor->get_translate_snap();
-
- Vector3 motion_snapped = motion;
- motion_snapped.snap(Vector3(snap, snap, snap));
- set_message(TTR("Translating: ") + motion_snapped);
- } else {
- set_message(TTR("Translating: ") + motion);
}
+ Vector3 motion_snapped = motion;
+ motion_snapped.snap(Vector3(snap, snap, snap));
+ set_message(TTR("Translating: ") + "(" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
+ String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
@@ -1596,20 +1579,12 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
float angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
if (_edit.snap || spatial_editor->is_snap_enabled()) {
-
- float snap = spatial_editor->get_rotate_snap();
-
- if (snap) {
- angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180
- angle -= Math::fmod(angle, snap);
- set_message(vformat(TTR("Rotating %s degrees."), rtos(angle)));
- angle = Math::deg2rad(angle);
- } else
- set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
-
- } else {
- set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
+ snap = spatial_editor->get_rotate_snap();
}
+ angle = Math::rad2deg(angle) + snap * 0.5; //else it won't reach +180
+ angle -= Math::fmod(angle, snap);
+ set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals)));
+ angle = Math::deg2rad(angle);
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -1830,8 +1805,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_menu_option(orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL);
_update_name();
}
- if (ED_IS_SHORTCUT("spatial_editor/align_selection_with_view", p_event)) {
- _menu_option(VIEW_ALIGN_SELECTION_WITH_VIEW);
+ if (ED_IS_SHORTCUT("spatial_editor/align_transform_with_view", p_event)) {
+ _menu_option(VIEW_ALIGN_TRANSFORM_WITH_VIEW);
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/align_rotation_with_view", p_event)) {
+ _menu_option(VIEW_ALIGN_ROTATION_WITH_VIEW);
}
if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) {
if (!get_selected_count() || _edit.mode != TRANSFORM_NONE)
@@ -2387,16 +2365,22 @@ void SpatialEditorViewport::_draw() {
get_stylebox("Focus", "EditorStyles")->draw(surface->get_canvas_item(), r);
}
- RID ci = surface->get_canvas_item();
-
if (cursor.region_select) {
+ const Rect2 selection_rect = Rect2(cursor.region_begin, cursor.region_end - cursor.region_begin);
- VisualServer::get_singleton()->canvas_item_add_rect(
- ci,
- Rect2(cursor.region_begin, cursor.region_end - cursor.region_begin),
- get_color("accent_color", "Editor") * Color(1, 1, 1, 0.375));
+ surface->draw_rect(
+ selection_rect,
+ get_color("box_selection_fill_color", "Editor"));
+
+ surface->draw_rect(
+ selection_rect,
+ get_color("box_selection_stroke_color", "Editor"),
+ false,
+ Math::round(EDSCALE));
}
+ RID ci = surface->get_canvas_item();
+
if (message_time > 0) {
Ref<Font> font = get_font("font", "Label");
Point2 msgpos = Point2(5, get_size().y - 20);
@@ -2557,7 +2541,7 @@ void SpatialEditorViewport::_menu_option(int p_option) {
focus_selection();
} break;
- case VIEW_ALIGN_SELECTION_WITH_VIEW: {
+ case VIEW_ALIGN_TRANSFORM_WITH_VIEW: {
if (!get_selected_count())
break;
@@ -2566,7 +2550,8 @@ void SpatialEditorViewport::_menu_option(int p_option) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- undo_redo->create_action(TTR("Align with View"));
+ undo_redo->create_action(TTR("Align Transform with View"));
+
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Spatial *sp = Object::cast_to<Spatial>(E->get());
@@ -2590,6 +2575,34 @@ void SpatialEditorViewport::_menu_option(int p_option) {
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
}
undo_redo->commit_action();
+ focus_selection();
+
+ } break;
+ case VIEW_ALIGN_ROTATION_WITH_VIEW: {
+
+ if (!get_selected_count())
+ break;
+
+ Transform camera_transform = camera->get_global_transform();
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Align Rotation with View"));
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Spatial *sp = Object::cast_to<Spatial>(E->get());
+ if (!sp)
+ continue;
+
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se)
+ continue;
+
+ undo_redo->add_do_method(sp, "set_rotation", camera_transform.basis.get_rotation());
+ undo_redo->add_undo_method(sp, "set_rotation", sp->get_rotation());
+ }
+ undo_redo->commit_action();
+
} break;
case VIEW_ENVIRONMENT: {
@@ -2907,8 +2920,14 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
if (dd == 0)
dd = 0.0001;
- float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
- gizmo_scale = (gsize / Math::abs(dd)) * MAX(1, EDSCALE) / viewport_container->get_stretch_shrink();
+ float gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
+ // At low viewport heights, multiply the gizmo scale based on the viewport height.
+ // This prevents the gizmo from growing very large and going outside the viewport.
+ const int viewport_base_height = 400 * MAX(1, EDSCALE);
+ gizmo_scale =
+ (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) *
+ MIN(viewport_base_height, viewport_container->get_size().height) / viewport_base_height /
+ viewport_container->get_stretch_shrink();
Vector3 scale = Vector3(1, 1, 1) * gizmo_scale;
xform.basis.scale(scale);
@@ -3530,7 +3549,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Doppler Enable")), VIEW_AUDIO_DOPPLER);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Enable Doppler")), VIEW_AUDIO_DOPPLER);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
@@ -3539,7 +3558,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_origin"), VIEW_CENTER_TO_ORIGIN);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_selection"), VIEW_CENTER_TO_SELECTION);
- view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_selection_with_view"), VIEW_ALIGN_SELECTION_WITH_VIEW);
+ view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_transform_with_view"), VIEW_ALIGN_TRANSFORM_WITH_VIEW);
+ view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_rotation_with_view"), VIEW_ALIGN_ROTATION_WITH_VIEW);
view_menu->get_popup()->connect("id_pressed", this, "_menu_option");
view_menu->set_disable_shortcuts(true);
@@ -3977,11 +3997,11 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
for (int i = 0; i < 3; i++) {
- move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_hl : gizmo_color[i]);
- move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
- rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_hl : gizmo_color[i]);
- scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_hl : gizmo_color[i]);
- scale_plane_gizmo[i]->surface_set_material(0, (i + 12) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
+ move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? plane_gizmo_color_hl[i] : plane_gizmo_color[i]);
+ rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ scale_plane_gizmo[i]->surface_set_material(0, (i + 12) == p_axis ? plane_gizmo_color_hl[i] : plane_gizmo_color[i]);
}
}
@@ -4060,6 +4080,23 @@ Object *SpatialEditor::_get_editor_data(Object *p_what) {
return si;
}
+Color SpatialEditor::_get_axis_color(int axis) {
+
+ switch (axis) {
+ case 0:
+ // X axis
+ return Color(0.96, 0.20, 0.32);
+ case 1:
+ // Y axis
+ return Color(0.53, 0.84, 0.01);
+ case 2:
+ // Z axis
+ return Color(0.16, 0.55, 0.96);
+ default:
+ return Color(0, 0, 0);
+ }
+}
+
void SpatialEditor::_generate_selection_box() {
AABB aabb(Vector3(), Vector3(1, 1, 1));
@@ -4073,11 +4110,6 @@ void SpatialEditor::_generate_selection_box() {
Vector3 a, b;
aabb.get_edge(i, a, b);
- /*Vector<Vector3> points;
- Vector<Color> colors;
- points.push_back(a);
- points.push_back(b);*/
-
st->add_color(Color(1.0, 1.0, 0.8, 0.8));
st->add_vertex(a);
st->add_color(Color(1.0, 1.0, 0.8, 0.4));
@@ -4616,12 +4648,13 @@ void SpatialEditor::_init_indicators() {
for (int i = 0; i < 3; i++) {
Vector3 axis;
axis[i] = 1;
+ Color origin_color = _get_axis_color(i);
grid_enable[i] = false;
grid_visible[i] = false;
- origin_colors.push_back(Color(axis.x, axis.y, axis.z));
- origin_colors.push_back(Color(axis.x, axis.y, axis.z));
+ origin_colors.push_back(origin_color);
+ origin_colors.push_back(origin_color);
origin_points.push_back(axis * 4096);
origin_points.push_back(axis * -4096);
}
@@ -4650,17 +4683,11 @@ void SpatialEditor::_init_indicators() {
//move gizmo
- float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
-
- gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- gizmo_hl->set_on_top_of_alpha();
- gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f));
- gizmo_hl->set_cull_mode(SpatialMaterial::CULL_DISABLED);
-
for (int i = 0; i < 3; i++) {
+ Color col = _get_axis_color(i);
+ col.a = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
+
move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
@@ -4671,13 +4698,13 @@ void SpatialEditor::_init_indicators() {
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
mat->set_on_top_of_alpha();
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- Color col;
- col[i] = 1.0;
- col.a = gizmo_alph;
mat->set_albedo(col);
-
gizmo_color[i] = mat;
+ Ref<SpatialMaterial> mat_hl = mat->duplicate();
+ mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ gizmo_color_hl[i] = mat_hl;
+
Vector3 ivec;
ivec[i] = 1;
Vector3 nivec;
@@ -4767,13 +4794,14 @@ void SpatialEditor::_init_indicators() {
plane_mat->set_on_top_of_alpha();
plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- Color col2;
- col2[i] = 1.0;
- col2.a = gizmo_alph;
- plane_mat->set_albedo(col2);
+ plane_mat->set_albedo(col);
plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides
surftool->set_material(plane_mat);
surftool->commit(move_plane_gizmo[i]);
+
+ Ref<SpatialMaterial> plane_mat_hl = plane_mat->duplicate();
+ plane_mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
// Rotate
@@ -4896,13 +4924,14 @@ void SpatialEditor::_init_indicators() {
plane_mat->set_on_top_of_alpha();
plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- Color col2;
- col2[i] = 1.0;
- col2.a = gizmo_alph;
- plane_mat->set_albedo(col2);
+ plane_mat->set_albedo(col);
plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides
surftool->set_material(plane_mat);
surftool->commit(scale_plane_gizmo[i]);
+
+ Ref<SpatialMaterial> plane_mat_hl = plane_mat->duplicate();
+ plane_mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
}
}
@@ -5139,7 +5168,7 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
// We add a bit of margin to the from position to avoid it from snapping
// when the spatial is already on a floor and there's another floor under
// it
- from = from + Vector3(0.0, 0.1, 0.0);
+ from = from + Vector3(0.0, 0.2, 0.0);
Dictionary d;
@@ -5154,31 +5183,56 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
Array keys = snap_data.keys();
- if (keys.size()) {
- undo_redo->create_action(TTR("Snap Nodes To Floor"));
+ // The maximum height an object can travel to be snapped
+ const float max_snap_height = 20.0;
+
+ // Will be set to `true` if at least one node from the selection was successfully snapped
+ bool snapped_to_floor = false;
+ if (keys.size()) {
+ // For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
+ // We need to check this before snapping to register the undo/redo action only if needed.
for (int i = 0; i < keys.size(); i++) {
Node *node = keys[i];
Spatial *sp = Object::cast_to<Spatial>(node);
-
Dictionary d = snap_data[node];
Vector3 from = d["from"];
- Vector3 position_offset = d["position_offset"];
-
- Vector3 to = from - Vector3(0.0, 10.0, 0.0);
+ Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp);
if (ss->intersect_ray(from, to, result, excluded)) {
- Transform new_transform = sp->get_global_transform();
- new_transform.origin.y = result.position.y;
- new_transform.origin = new_transform.origin - position_offset;
-
- undo_redo->add_do_method(sp, "set_global_transform", new_transform);
- undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ snapped_to_floor = true;
}
}
- undo_redo->commit_action();
+ if (snapped_to_floor) {
+ undo_redo->create_action(TTR("Snap Nodes To Floor"));
+
+ // Perform snapping if at least one node can be snapped
+ for (int i = 0; i < keys.size(); i++) {
+ Node *node = keys[i];
+ Spatial *sp = Object::cast_to<Spatial>(node);
+ Dictionary d = snap_data[node];
+ Vector3 from = d["from"];
+ Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
+ Set<RID> excluded = _get_physics_bodies_rid(sp);
+
+ if (ss->intersect_ray(from, to, result, excluded)) {
+ Vector3 position_offset = d["position_offset"];
+ Transform new_transform = sp->get_global_transform();
+
+ new_transform.origin.y = result.position.y;
+ new_transform.origin = new_transform.origin - position_offset;
+
+ undo_redo->add_do_method(sp, "set_global_transform", new_transform);
+ undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ }
+ }
+
+ undo_redo->commit_action();
+ } else {
+ EditorNode::get_singleton()->show_warning(TTR("Couldn't find a solid floor to snap the selection to."));
+ }
}
}
@@ -5188,42 +5242,6 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
return;
snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
-
- Ref<InputEventKey> k = p_event;
-
- if (k.is_valid()) {
-
- // Note: need to check is_echo because first person movement keys might still be held
- if (!is_any_freelook_active() && !p_event->is_echo()) {
-
- if (!k->is_pressed())
- return;
-
- if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) {
- _menu_item_pressed(MENU_TOOL_SELECT);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) {
- _menu_item_pressed(MENU_TOOL_MOVE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) {
- _menu_item_pressed(MENU_TOOL_ROTATE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) {
- _menu_item_pressed(MENU_TOOL_SCALE);
- } else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) {
- snap_selected_nodes_to_floor();
- } else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) {
- if (are_local_coords_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS);
- } else {
- _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS);
- }
- } else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
- if (is_snap_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_USE_SNAP);
- } else {
- _menu_item_toggled(true, MENU_TOOL_USE_SNAP);
- }
- }
- }
- }
}
void SpatialEditor::_notification(int p_what) {
@@ -5272,6 +5290,10 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_GROUP_SELECTED]->set_icon(get_icon("Group", "EditorIcons"));
+ tool_button[SpatialEditor::TOOL_UNGROUP_SELECTED]->set_icon(get_icon("Ungroup", "EditorIcons"));
tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons"));
tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons"));
@@ -5407,6 +5429,7 @@ void SpatialEditor::_register_all_gizmos() {
add_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
add_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
add_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
+ add_gizmo_plugin(Ref<CPUParticlesGizmoPlugin>(memnew(CPUParticlesGizmoPlugin)));
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
@@ -5496,7 +5519,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
+ tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q));
+ tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
hbc_menu->add_child(memnew(VSeparator));
@@ -5506,7 +5530,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_MOVE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_MOVE;
tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
+ tool_button[TOOL_MODE_MOVE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_move", TTR("Move Mode"), KEY_W));
tool_button[TOOL_MODE_ROTATE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
@@ -5514,7 +5538,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_ROTATE;
tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
+ tool_button[TOOL_MODE_ROTATE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Rotate Mode"), KEY_E));
tool_button[TOOL_MODE_SCALE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
@@ -5522,7 +5546,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_SCALE;
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
+ tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), KEY_R));
hbc_menu->add_child(memnew(VSeparator));
@@ -5566,9 +5590,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
- sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_tooltip(vformat(TTR("Local Space Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Use Local Space"), KEY_T));
tool_option_button[TOOL_OPT_USE_SNAP] = memnew(ToolButton);
hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
@@ -5576,9 +5598,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
button_binds.write[0] = MENU_TOOL_USE_SNAP;
tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
- sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), KEY_Y));
hbc_menu->add_child(memnew(VSeparator));
@@ -5596,13 +5616,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), KEY_K);
ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), KEY_O);
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F);
- ED_SHORTCUT("spatial_editor/align_selection_with_view", TTR("Align Selection With View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
-
- ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q);
- ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
- ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
- ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
-
+ ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_M);
+ ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
PopupMenu *p;
@@ -5614,10 +5629,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p = transform_menu->get_popup();
p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap Object to Floor"), KEY_PAGEDOWN), MENU_SNAP_TO_FLOOR);
- p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
- p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG);
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
+
p->connect("id_pressed", this, "_menu_item_pressed");
view_menu = memnew(MenuButton);
@@ -5641,11 +5657,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_submenu_item(TTR("Gizmos"), "GizmosMenu");
p->add_separator();
-
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
+
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS);
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
@@ -5799,7 +5815,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
EDITOR_DEF("editors/3d/manipulator_gizmo_size", 80);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/3d/manipulator_gizmo_size", PROPERTY_HINT_RANGE, "16,1024,1"));
- EDITOR_DEF("editors/3d/manipulator_gizmo_opacity", 0.2);
+ EDITOR_DEF("editors/3d/manipulator_gizmo_opacity", 0.4);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::REAL, "editors/3d/manipulator_gizmo_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"));
over_gizmo_handle = -1;
}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index b4e2f028d2..aa61f4bae1 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -37,9 +37,6 @@
#include "scene/3d/light.h"
#include "scene/3d/visual_instance.h"
#include "scene/gui/panel_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Camera;
class SpatialEditor;
@@ -61,6 +58,7 @@ public:
RID instance;
Ref<ArrayMesh> mesh;
Ref<Material> material;
+ Ref<SkinReference> skin_reference;
RID skeleton;
bool billboard;
bool unscaled;
@@ -104,7 +102,7 @@ protected:
public:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
- void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID(), const Ref<Material> &p_material = Ref<Material>());
+ void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
@@ -153,7 +151,8 @@ class SpatialEditorViewport : public Control {
VIEW_REAR,
VIEW_CENTER_TO_ORIGIN,
VIEW_CENTER_TO_SELECTION,
- VIEW_ALIGN_SELECTION_WITH_VIEW,
+ VIEW_ALIGN_TRANSFORM_WITH_VIEW,
+ VIEW_ALIGN_ROTATION_WITH_VIEW,
VIEW_PERSPECTIVE,
VIEW_ENVIRONMENT,
VIEW_ORTHOGONAL,
@@ -364,7 +363,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);
@@ -527,7 +526,8 @@ private:
Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3], scale_plane_gizmo[3];
Ref<SpatialMaterial> gizmo_color[3];
Ref<SpatialMaterial> plane_gizmo_color[3];
- Ref<SpatialMaterial> gizmo_hl;
+ Ref<SpatialMaterial> gizmo_color_hl[3];
+ Ref<SpatialMaterial> plane_gizmo_color_hl[3];
int over_gizmo_handle;
@@ -634,6 +634,7 @@ private:
Node *custom_camera;
Object *_get_editor_data(Object *p_what);
+ Color _get_axis_color(int axis);
Ref<Environment> viewport_environment;
diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp
index 2deb2090e2..69fd592652 100644
--- a/editor/plugins/sprite_editor_plugin.cpp
+++ b/editor/plugins/sprite_editor_plugin.cpp
@@ -102,7 +102,7 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float
int lasti = p2->Contour.size() - 1;
Vector2 prev = Vector2(p2->Contour[lasti].X / PRECISION, p2->Contour[lasti].Y / PRECISION);
- for (unsigned int i = 0; i < p2->Contour.size(); i++) {
+ for (uint64_t i = 0; i < p2->Contour.size(); i++) {
Vector2 cur = Vector2(p2->Contour[i].X / PRECISION, p2->Contour[i].Y / PRECISION);
if (cur.distance_to(prev) > 0.5) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index d91de6cbf6..394122d91d 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -464,9 +464,11 @@ void SpriteFramesEditor::_animation_select() {
if (updating)
return;
- double value = anim_speed->get_line_edit()->get_text().to_double();
- if (!Math::is_equal_approx(value, frames->get_animation_speed(edited_anim)))
- _animation_fps_changed(value);
+ if (frames->has_animation(edited_anim)) {
+ double value = anim_speed->get_line_edit()->get_text().to_double();
+ if (!Math::is_equal_approx(value, frames->get_animation_speed(edited_anim)))
+ _animation_fps_changed(value);
+ }
TreeItem *selected = animations->get_selected();
ERR_FAIL_COND(!selected);
@@ -548,6 +550,7 @@ void SpriteFramesEditor::_animation_name_edited() {
undo_redo->commit_action();
}
+
void SpriteFramesEditor::_animation_add() {
String name = "New Anim";
@@ -578,13 +581,21 @@ void SpriteFramesEditor::_animation_add() {
undo_redo->commit_action();
animations->grab_focus();
}
+
void SpriteFramesEditor::_animation_remove() {
+
if (updating)
return;
if (!frames->has_animation(edited_anim))
return;
+ delete_dialog->set_text(TTR("Delete Animation?"));
+ delete_dialog->popup_centered_minsize();
+}
+
+void SpriteFramesEditor::_animation_remove_confirmed() {
+
undo_redo->create_action(TTR("Remove Animation"));
undo_redo->add_do_method(frames, "remove_animation", edited_anim);
undo_redo->add_undo_method(frames, "add_animation", edited_anim);
@@ -598,6 +609,8 @@ void SpriteFramesEditor::_animation_remove() {
undo_redo->add_do_method(this, "_update_library");
undo_redo->add_undo_method(this, "_update_library");
+ edited_anim = StringName();
+
undo_redo->commit_action();
}
@@ -743,7 +756,9 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
if (frame.is_null())
return Variant();
- return EditorNode::get_singleton()->drag_resource(frame, p_from);
+ Dictionary drag_data = EditorNode::get_singleton()->drag_resource(frame, p_from);
+ drag_data["frame"] = idx; // store the frame, incase we want to reorder frames inside 'drop_data_fw'
+ return drag_data;
}
bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
@@ -753,8 +768,9 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
if (!d.has("type"))
return false;
+ // reordering frames
if (d.has("from") && (Object *)(d["from"]) == tree)
- return false;
+ return true;
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
@@ -806,13 +822,31 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
Ref<Texture> texture = r;
if (texture.is_valid()) {
-
- undo_redo->create_action(TTR("Add Frame"));
- undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
- undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) : at_pos);
- undo_redo->add_do_method(this, "_update_library");
- undo_redo->add_undo_method(this, "_update_library");
- undo_redo->commit_action();
+ bool reorder = false;
+ if (d.has("from") && (Object *)(d["from"]) == tree)
+ reorder = true;
+
+ if (reorder) { //drop is from reordering frames
+ int from_frame = -1;
+ if (d.has("frame"))
+ from_frame = d["frame"];
+
+ undo_redo->create_action(TTR("Move Frame"));
+ undo_redo->add_do_method(frames, "remove_frame", edited_anim, from_frame == -1 ? frames->get_frame_count(edited_anim) : from_frame);
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
+ undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) - 1 : at_pos);
+ undo_redo->add_undo_method(frames, "add_frame", edited_anim, texture, from_frame);
+ undo_redo->add_do_method(this, "_update_library");
+ undo_redo->add_undo_method(this, "_update_library");
+ undo_redo->commit_action();
+ } else {
+ undo_redo->create_action(TTR("Add Frame"));
+ undo_redo->add_do_method(frames, "add_frame", edited_anim, texture, at_pos == -1 ? -1 : at_pos);
+ undo_redo->add_undo_method(frames, "remove_frame", edited_anim, at_pos == -1 ? frames->get_frame_count(edited_anim) : at_pos);
+ undo_redo->add_do_method(this, "_update_library");
+ undo_redo->add_undo_method(this, "_update_library");
+ undo_redo->commit_action();
+ }
}
}
@@ -840,6 +874,7 @@ void SpriteFramesEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_animation_name_edited"), &SpriteFramesEditor::_animation_name_edited);
ClassDB::bind_method(D_METHOD("_animation_add"), &SpriteFramesEditor::_animation_add);
ClassDB::bind_method(D_METHOD("_animation_remove"), &SpriteFramesEditor::_animation_remove);
+ ClassDB::bind_method(D_METHOD("_animation_remove_confirmed"), &SpriteFramesEditor::_animation_remove_confirmed);
ClassDB::bind_method(D_METHOD("_animation_loop_changed"), &SpriteFramesEditor::_animation_loop_changed);
ClassDB::bind_method(D_METHOD("_animation_fps_changed"), &SpriteFramesEditor::_animation_fps_changed);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw);
@@ -870,7 +905,6 @@ SpriteFramesEditor::SpriteFramesEditor() {
new_anim = memnew(ToolButton);
new_anim->set_tooltip(TTR("New Animation"));
hbc_animlist->add_child(new_anim);
- new_anim->set_h_size_flags(SIZE_EXPAND_FILL);
new_anim->connect("pressed", this, "_animation_add");
remove_anim = memnew(ToolButton);
@@ -926,7 +960,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
paste->set_tooltip(TTR("Paste"));
hbc->add_child(paste);
- hbc->add_spacer(false);
+ hbc->add_child(memnew(VSeparator));
empty = memnew(ToolButton);
empty->set_tooltip(TTR("Insert Empty (Before)"));
@@ -987,6 +1021,10 @@ SpriteFramesEditor::SpriteFramesEditor() {
edited_anim = "default";
+ delete_dialog = memnew(ConfirmationDialog);
+ add_child(delete_dialog);
+ delete_dialog->connect("confirmed", this, "_animation_remove_confirmed");
+
split_sheet_dialog = memnew(ConfirmationDialog);
add_child(split_sheet_dialog);
VBoxContainer *split_sheet_vb = memnew(VBoxContainer);
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index d64431cde7..f20b54f910 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -73,6 +73,8 @@ class SpriteFramesEditor : public HSplitContainer {
StringName edited_anim;
+ ConfirmationDialog *delete_dialog;
+
ConfirmationDialog *split_sheet_dialog;
ScrollContainer *splite_sheet_scroll;
TextureRect *split_sheet_preview;
@@ -98,6 +100,7 @@ class SpriteFramesEditor : public HSplitContainer {
void _animation_name_edited();
void _animation_add();
void _animation_remove();
+ void _animation_remove_confirmed();
void _animation_loop_changed();
void _animation_fps_changed(double p_value);
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index fae88f4eb7..d0320bcd8b 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -30,6 +30,7 @@
#include "text_editor.h"
+#include "core/os/keyboard.h"
#include "editor_node.h"
void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
@@ -221,19 +222,19 @@ void TextEditor::_validate_script() {
void TextEditor::_update_bookmark_list() {
- bookmarks_menu->get_popup()->clear();
+ bookmarks_menu->clear();
- 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();
@@ -242,17 +243,17 @@ void TextEditor::_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 TextEditor::_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));
}
}
@@ -313,6 +314,11 @@ void TextEditor::goto_line(int p_line, bool p_with_error) {
code_editor->goto_line(p_line);
}
+void TextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
+
+ code_editor->goto_line_selection(p_line, p_begin, p_end);
+}
+
void TextEditor::set_executing_line(int p_line) {
code_editor->set_executing_line(p_line);
@@ -477,6 +483,14 @@ void TextEditor::_edit_option(int p_op) {
code_editor->get_find_replace_bar()->popup_replace();
} break;
+ case SEARCH_IN_FILES: {
+
+ String selected_text = code_editor->get_text_edit()->get_selection_text();
+
+ // Yep, because it doesn't make sense to instance this dialog for every single script open...
+ // So this will be delegated to the ScriptEditor.
+ emit_signal("search_in_files_requested", selected_text);
+ } break;
case SEARCH_GOTO_LINE: {
goto_line_dialog->popup_find_line(tx);
@@ -553,7 +567,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
int to_column = tx->get_selection_to_column();
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
+ // Right click is outside the selected text.
tx->deselect();
}
}
@@ -564,13 +578,21 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
if (!mb->is_pressed()) {
- _make_context_menu(tx->is_selection_active(), can_fold, is_folded);
+ _make_context_menu(tx->is_selection_active(), can_fold, is_folded, get_local_mouse_position());
}
}
}
+
+ Ref<InputEventKey> k = ev;
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_MENU) {
+ TextEdit *tx = code_editor->get_text_edit();
+ int line = tx->cursor_get_line();
+ _make_context_menu(tx->is_selection_active(), tx->can_fold(line), tx->is_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->_get_cursor_pixel_pos()));
+ context_menu->grab_focus();
+ }
}
-void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded) {
+void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position) {
context_menu->clear();
if (p_selection) {
@@ -596,7 +618,7 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is
if (p_can_fold || p_is_folded)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
- context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ context_menu->set_position(get_global_transform().xform(p_position));
context_menu->set_size(Vector2(1, 1));
context_menu->popup();
}
@@ -632,17 +654,14 @@ TextEditor::TextEditor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
-
- goto_line_dialog = memnew(GotoLineDialog);
- add_child(goto_line_dialog);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
edit_menu = memnew(MenuButton);
+ edit_hb->add_child(edit_menu);
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
- edit_hb->add_child(edit_menu);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -684,16 +703,37 @@ TextEditor::TextEditor() {
highlighter_menu->add_radio_check_item(TTR("Standard"));
highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
- 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);
+ goto_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
+
+ bookmarks_menu = memnew(PopupMenu);
+ bookmarks_menu->set_name(TTR("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");
+
+ goto_line_dialog = memnew(GotoLineDialog);
+ add_child(goto_line_dialog);
code_editor->get_text_edit()->set_drag_forwarding(this);
}
+TextEditor::~TextEditor() {
+ for (const Map<String, SyntaxHighlighter *>::Element *E = highlighters.front(); E; E = E->next()) {
+ if (E->get() != NULL) {
+ memdelete(E->get());
+ }
+ }
+ highlighters.clear();
+}
+
void TextEditor::validate() {
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index ae0c0bcf93..7d441a187d 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -46,7 +46,7 @@ private:
MenuButton *edit_menu;
PopupMenu *highlighter_menu;
MenuButton *search_menu;
- MenuButton *bookmarks_menu;
+ PopupMenu *bookmarks_menu;
PopupMenu *context_menu;
GotoLineDialog *goto_line_dialog;
@@ -87,6 +87,7 @@ private:
SEARCH_FIND_NEXT,
SEARCH_FIND_PREV,
SEARCH_REPLACE,
+ SEARCH_IN_FILES,
SEARCH_GOTO_LINE,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
@@ -100,7 +101,7 @@ protected:
void _notification(int p_what);
void _edit_option(int p_op);
- void _make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded);
+ void _make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
Map<String, SyntaxHighlighter *> highlighters;
@@ -131,6 +132,7 @@ public:
virtual Vector<String> get_functions();
virtual void get_breakpoints(List<int> *p_breakpoints);
virtual void goto_line(int p_line, bool p_with_error = false);
+ void goto_line_selection(int p_line, int p_begin, int p_end);
virtual void set_executing_line(int p_line);
virtual void clear_executing_line();
virtual void trim_trailing_whitespace();
@@ -154,6 +156,7 @@ public:
static void register_editor();
TextEditor();
+ ~TextEditor();
};
#endif // TEXT_EDITOR_H
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 0aa4a7662c..6d71c56ead 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -39,9 +39,6 @@ void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
void TextureEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
- }
-
if (p_what == NOTIFICATION_READY) {
//get_scene()->connect("node_removed",this,"_node_removed");
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 8f58fbd6ab..21eebf9ca2 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -193,7 +193,7 @@ void TextureRegionEditor::_region_draw() {
updating_scroll = false;
if (node_ninepatch || obj_styleBox.is_valid()) {
- float margins[4];
+ float margins[4] = { 0 };
if (node_ninepatch) {
margins[0] = node_ninepatch->get_patch_margin(MARGIN_TOP);
margins[1] = node_ninepatch->get_patch_margin(MARGIN_BOTTOM);
@@ -204,12 +204,8 @@ void TextureRegionEditor::_region_draw() {
margins[1] = obj_styleBox->get_margin_size(MARGIN_BOTTOM);
margins[2] = obj_styleBox->get_margin_size(MARGIN_LEFT);
margins[3] = obj_styleBox->get_margin_size(MARGIN_RIGHT);
- } else {
- margins[0] = 0;
- margins[1] = 0;
- margins[2] = 0;
- margins[3] = 0;
}
+
Vector2 pos[4] = {
mtx.basis_xform(Vector2(0, margins[0])) + Vector2(0, endpoints[0].y - draw_ofs.y * draw_zoom),
-mtx.basis_xform(Vector2(0, margins[1])) + Vector2(0, endpoints[2].y - draw_ofs.y * draw_zoom),
@@ -248,7 +244,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
if (mb->is_pressed()) {
if (node_ninepatch || obj_styleBox.is_valid()) {
edited_margin = -1;
- float margins[4];
+ float margins[4] = { 0 };
if (node_ninepatch) {
margins[0] = node_ninepatch->get_patch_margin(MARGIN_TOP);
margins[1] = node_ninepatch->get_patch_margin(MARGIN_BOTTOM);
@@ -260,6 +256,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
margins[2] = obj_styleBox->get_margin_size(MARGIN_LEFT);
margins[3] = obj_styleBox->get_margin_size(MARGIN_RIGHT);
}
+
Vector2 pos[4] = {
mtx.basis_xform(rect.position + Vector2(0, margins[0])) - draw_ofs * draw_zoom,
mtx.basis_xform(rect.position + rect.size - Vector2(0, margins[1])) - draw_ofs * draw_zoom,
@@ -628,9 +625,12 @@ void TextureRegionEditor::_update_rect() {
rect = node_sprite->get_region_rect();
else if (node_sprite_3d)
rect = node_sprite_3d->get_region_rect();
- else if (node_ninepatch)
+ else if (node_ninepatch) {
rect = node_ninepatch->get_region_rect();
- else if (obj_styleBox.is_valid())
+ if (rect == Rect2()) {
+ rect = Rect2(Vector2(), node_ninepatch->get_texture()->get_size());
+ }
+ } else if (obj_styleBox.is_valid())
rect = obj_styleBox->get_region_rect();
else if (atlas_tex.is_valid())
rect = atlas_tex->get_region();
@@ -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/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 5b67d259ba..3055a9382c 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -36,6 +36,7 @@
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
theme = p_theme;
+ main_panel->set_theme(p_theme);
main_container->set_theme(p_theme);
}
@@ -53,6 +54,7 @@ void ThemeEditor::_propagate_redraw(Control *p_at) {
void ThemeEditor::_refresh_interval() {
+ _propagate_redraw(main_panel);
_propagate_redraw(main_container);
}
@@ -130,14 +132,14 @@ void ThemeEditor::_save_template_cbk(String fname) {
Map<String, _TECategory> categories;
- //fill types
+ // Fill types.
List<StringName> type_list;
Theme::get_default()->get_type_list(&type_list);
for (List<StringName>::Element *E = type_list.front(); E; E = E->next()) {
categories.insert(E->get(), _TECategory());
}
- //fill default theme
+ // Fill default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -189,11 +191,9 @@ void ThemeEditor::_save_template_cbk(String fname) {
}
FileAccess *file = FileAccess::open(filename, FileAccess::WRITE);
- if (!file) {
- ERR_EXPLAIN(TTR("Can't save theme to file:") + " " + filename);
- return;
- }
+ ERR_FAIL_COND_MSG(!file, "Can't save theme to file: " + filename + ".");
+
file->store_line("; ******************* ");
file->store_line("; Template Theme File ");
file->store_line("; ******************* ");
@@ -256,7 +256,7 @@ void ThemeEditor::_save_template_cbk(String fname) {
file->store_line("");
file->store_line("");
- //write default theme
+ // Write default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -501,7 +501,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_select_label->show();
type_select->show();
- if (p_option == POPUP_ADD) { //add
+ if (p_option == POPUP_ADD) { // Add.
add_del_dialog->set_title(TTR("Add Item"));
add_del_dialog->get_ok()->set_text(TTR("Add"));
@@ -509,7 +509,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
base_theme = Theme::get_default();
- } else if (p_option == POPUP_CLASS_ADD) { //add
+ } else if (p_option == POPUP_CLASS_ADD) { // Add.
add_del_dialog->set_title(TTR("Add All Items"));
add_del_dialog->get_ok()->set_text(TTR("Add All"));
@@ -552,12 +552,10 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_menu->get_popup()->clear();
- if (p_option == 0 || p_option == 1) { //add
+ if (p_option == 0 || p_option == 1) { // Add.
List<StringName> new_types;
theme->get_type_list(&new_types);
-
- //uh kind of sucks
for (List<StringName>::Element *F = new_types.front(); F; F = F->next()) {
bool found = false;
@@ -583,15 +581,17 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
void ThemeEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
-
- time_left -= get_process_delta_time();
- if (time_left < 0) {
- time_left = 1.5;
- _refresh_interval();
- }
- } else if (p_what == NOTIFICATION_THEME_CHANGED) {
- theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ time_left -= get_process_delta_time();
+ if (time_left < 0) {
+ time_left = 1.5;
+ _refresh_interval();
+ }
+ } break;
+ case NOTIFICATION_THEME_CHANGED: {
+ theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ } break;
}
}
@@ -629,35 +629,34 @@ ThemeEditor::ThemeEditor() {
top_menu->add_child(theme_menu);
theme_menu->get_popup()->connect("id_pressed", this, "_theme_menu_cbk");
- scroll = memnew(ScrollContainer);
+ ScrollContainer *scroll = memnew(ScrollContainer);
add_child(scroll);
- scroll->set_theme(Theme::get_default());
scroll->set_enable_v_scroll(true);
scroll->set_enable_h_scroll(false);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container = memnew(MarginContainer);
- scroll->add_child(main_container);
- main_container->set_theme(Theme::get_default());
- main_container->set_clip_contents(true);
- main_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
- main_container->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container->set_h_size_flags(SIZE_EXPAND_FILL);
+ MarginContainer *root_container = memnew(MarginContainer);
+ scroll->add_child(root_container);
+ root_container->set_theme(Theme::get_default());
+ root_container->set_clip_contents(true);
+ root_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
+ root_container->set_v_size_flags(SIZE_EXPAND_FILL);
+ root_container->set_h_size_flags(SIZE_EXPAND_FILL);
//// Preview Controls ////
- Panel *panel = memnew(Panel);
- main_container->add_child(panel);
+ main_panel = memnew(Panel);
+ root_container->add_child(main_panel);
- MarginContainer *mc = memnew(MarginContainer);
- main_container->add_child(mc);
- mc->add_constant_override("margin_right", 4 * EDSCALE);
- mc->add_constant_override("margin_top", 4 * EDSCALE);
- mc->add_constant_override("margin_left", 4 * EDSCALE);
- mc->add_constant_override("margin_bottom", 4 * EDSCALE);
+ main_container = memnew(MarginContainer);
+ root_container->add_child(main_container);
+ main_container->add_constant_override("margin_right", 4 * EDSCALE);
+ main_container->add_constant_override("margin_top", 4 * EDSCALE);
+ main_container->add_constant_override("margin_left", 4 * EDSCALE);
+ main_container->add_constant_override("margin_bottom", 4 * EDSCALE);
HBoxContainer *main_hb = memnew(HBoxContainer);
- mc->add_child(main_hb);
+ main_container->add_child(main_hb);
VBoxContainer *first_vb = memnew(VBoxContainer);
main_hb->add_child(first_vb);
@@ -695,19 +694,19 @@ ThemeEditor::ThemeEditor() {
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_check_item(TTR("Check Item"));
test_menu_button->get_popup()->add_check_item(TTR("Checked Item"));
- test_menu_button->get_popup()->set_item_checked(3, true);
+ test_menu_button->get_popup()->set_item_checked(4, true);
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_radio_check_item(TTR("Radio Item"));
test_menu_button->get_popup()->add_radio_check_item(TTR("Checked Radio Item"));
- test_menu_button->get_popup()->set_item_checked(6, true);
+ test_menu_button->get_popup()->set_item_checked(7, true);
test_menu_button->get_popup()->add_separator(TTR("Named Sep."));
PopupMenu *test_submenu = memnew(PopupMenu);
test_menu_button->get_popup()->add_child(test_submenu);
test_submenu->set_name("submenu");
test_menu_button->get_popup()->add_submenu_item(TTR("Submenu"), "submenu");
- test_submenu->add_item(TTR("Item 1"));
- test_submenu->add_item(TTR("Item 2"));
+ test_submenu->add_item(TTR("Subitem 1"));
+ test_submenu->add_item(TTR("Subitem 2"));
first_vb->add_child(test_menu_button);
OptionButton *test_option_button = memnew(OptionButton);
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index cc236907a9..6ffee46569 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -45,7 +45,7 @@ class ThemeEditor : public VBoxContainer {
GDCLASS(ThemeEditor, VBoxContainer);
- ScrollContainer *scroll;
+ Panel *main_panel;
MarginContainer *main_container;
Ref<Theme> theme;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 25e812e31c..90276041a8 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -376,7 +376,7 @@ void TileMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
}
// Implementation detail of TileMapEditor::_update_palette();
-// in modern C++ this could have been inside its body
+// In modern C++ this could have been inside its body.
namespace {
struct _PaletteEntry {
int id;
@@ -393,10 +393,10 @@ void TileMapEditor::_update_palette() {
if (!node)
return;
- // Update the clear button
+ // Update the clear button.
clear_transform_button->set_disabled(!flip_h && !flip_v && !transpose);
- // Update the palette
+ // Update the palette.
Vector<int> selected = get_selected_tiles();
int selected_single = palette->get_current();
int selected_manual = manual_palette->get_current();
@@ -405,8 +405,15 @@ void TileMapEditor::_update_palette() {
manual_palette->hide();
Ref<TileSet> tileset = node->get_tileset();
- if (tileset.is_null())
+ if (tileset.is_null()) {
+ search_box->set_text("");
+ search_box->set_editable(false);
+ info_message->show();
return;
+ }
+
+ search_box->set_editable(true);
+ info_message->hide();
List<int> tiles;
tileset->get_tile_list(&tiles);
@@ -421,7 +428,6 @@ void TileMapEditor::_update_palette() {
bool sort_by_name = bool(EDITOR_DEF("editors/tile_map/sort_tiles_by_name", true));
palette->add_constant_override("hseparation", hseparation * EDSCALE);
- palette->add_constant_override("vseparation", 8 * EDSCALE);
palette->set_fixed_icon_size(Size2(min_size, min_size));
palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1));
@@ -479,7 +485,7 @@ void TileMapEditor::_update_palette() {
region.position += (region.size + Vector2(spacing, spacing)) * tileset->autotile_get_icon_coordinate(entries[i].id);
}
- // Transpose and flip
+ // Transpose and flip.
palette->set_item_icon_transposed(palette->get_item_count() - 1, transpose);
if (flip_h) {
region.size.x = -region.size.x;
@@ -488,14 +494,14 @@ void TileMapEditor::_update_palette() {
region.size.y = -region.size.y;
}
- // Set region
+ // Set region.
if (region.size != Size2())
palette->set_item_icon_region(palette->get_item_count() - 1, region);
- // Set icon
+ // Set icon.
palette->set_item_icon(palette->get_item_count() - 1, tex);
- // Modulation
+ // Modulation.
Color color = tileset->tile_get_modulate(entries[i].id);
palette->set_item_icon_modulate(palette->get_item_count() - 1, color);
}
@@ -511,44 +517,47 @@ void TileMapEditor::_update_palette() {
palette->select(0);
}
- if (sel_tile != TileMap::INVALID_CELL) {
- if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) ||
- (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE)) {
+ if (sel_tile != TileMap::INVALID_CELL && ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE))) {
- const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
+ const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
- Vector<Vector2> entries2;
- for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
- entries2.push_back(E->key());
+ Vector<Vector2> entries2;
+ for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
+ entries2.push_back(E->key());
+ }
+ // Sort tiles in row-major order.
+ struct SwapComparator {
+ _FORCE_INLINE_ bool operator()(const Vector2 &v_l, const Vector2 &v_r) const {
+ return v_l.y != v_r.y ? v_l.y < v_r.y : v_l.x < v_r.x;
}
- entries2.sort();
-
- Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
+ };
+ entries2.sort_custom<SwapComparator>();
- for (int i = 0; i < entries2.size(); i++) {
+ Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
- manual_palette->add_item(String());
+ for (int i = 0; i < entries2.size(); i++) {
- if (tex.is_valid()) {
+ manual_palette->add_item(String());
- Rect2 region = tileset->tile_get_region(sel_tile);
- int spacing = tileset->autotile_get_spacing(sel_tile);
- region.size = tileset->autotile_get_size(sel_tile); // !!
- region.position += (region.size + Vector2(spacing, spacing)) * entries2[i];
+ if (tex.is_valid()) {
- if (!region.has_no_area())
- manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
+ Rect2 region = tileset->tile_get_region(sel_tile);
+ int spacing = tileset->autotile_get_spacing(sel_tile);
+ region.size = tileset->autotile_get_size(sel_tile); // !!
+ region.position += (region.size + Vector2(spacing, spacing)) * entries2[i];
- manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
- }
+ if (!region.has_no_area())
+ manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
- manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries2[i]);
+ manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
}
+
+ manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries2[i]);
}
}
if (manual_palette->get_item_count() > 0) {
- // Only show the manual palette if at least tile exists in it
+ // Only show the manual palette if at least tile exists in it.
if (selected_manual == -1 || selected_single != palette->get_current())
selected_manual = 0;
if (selected_manual < manual_palette->get_item_count())
@@ -966,7 +975,7 @@ static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) {
bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
- if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree())
+ if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree() || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT)
return false;
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
@@ -1467,15 +1476,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;
}
@@ -1514,7 +1536,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
- if (!node)
+ if (!node || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT)
return;
Transform2D cell_xf = node->get_cell_transform();
@@ -1917,8 +1939,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);
@@ -1934,6 +1954,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
add_child(priority_button);
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Filter tiles"));
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
search_box->connect("text_entered", this, "_text_entered");
search_box->connect("text_changed", this, "_text_changed");
@@ -1956,7 +1977,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette_container->set_custom_minimum_size(Size2(mw, 0));
add_child(palette_container);
- // Add tile palette
+ // Add tile palette.
palette = memnew(ItemList);
palette->set_h_size_flags(SIZE_EXPAND_FILL);
palette->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1964,11 +1985,21 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette->set_icon_mode(ItemList::ICON_MODE_TOP);
palette->set_max_text_lines(2);
palette->set_select_mode(ItemList::SELECT_MULTI);
+ palette->add_constant_override("vseparation", 8 * EDSCALE);
palette->connect("item_selected", this, "_palette_selected");
palette->connect("multi_selected", this, "_palette_multi_selected");
palette_container->add_child(palette);
- // Add autotile override palette
+ // Add message for when no texture is selected.
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Give a TileSet resource to this TileMap to use its tiles."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ palette->add_child(info_message);
+
+ // Add autotile override palette.
manual_palette = memnew(ItemList);
manual_palette->set_h_size_flags(SIZE_EXPAND_FILL);
manual_palette->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1978,18 +2009,17 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
manual_palette->hide();
palette_container->add_child(manual_palette);
- // Add menu items
+ // Add menu items.
toolbar = memnew(HBoxContainer);
toolbar->hide();
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar);
- // Separator
toolbar->add_child(memnew(VSeparator));
- // Tools
+ // Tools.
paint_button = memnew(ToolButton);
paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P));
- paint_button->set_tooltip(TTR("Shift+RMB: Line Draw\nShift+Ctrl+RMB: Rectangle Paint"));
+ paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint"));
paint_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_NONE));
paint_button->set_toggle_mode(true);
toolbar->add_child(paint_button);
@@ -2014,18 +2044,18 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
_update_button_tool();
- // Container to the right of the toolbar
+ // Container to the right of the toolbar.
toolbar_right = memnew(HBoxContainer);
toolbar_right->hide();
toolbar_right->set_h_size_flags(SIZE_EXPAND_FILL);
toolbar_right->set_alignment(BoxContainer::ALIGN_END);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar_right);
- // Tile position
+ // Tile position.
tile_info = memnew(Label);
toolbar_right->add_child(tile_info);
- // Menu
+ // Menu.
options = memnew(MenuButton);
options->set_text("TileMap");
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("TileMap", "EditorIcons"));
@@ -2044,30 +2074,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);
@@ -2114,6 +2149,8 @@ void TileMapEditorPlugin::make_visible(bool p_visible) {
tile_map_editor->show();
tile_map_editor->get_toolbar()->show();
tile_map_editor->get_toolbar_right()->show();
+ // Change to TOOL_SELECT when TileMap node is selected, to prevent accidental movement.
+ CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT);
} else {
tile_map_editor->hide();
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 3331fb971f..e3d678c2fd 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -41,10 +41,6 @@
#include "scene/gui/menu_button.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
@@ -86,6 +82,8 @@ class TileMapEditor : public VBoxContainer {
ItemList *palette;
ItemList *manual_palette;
+ Label *info_message;
+
HBoxContainer *toolbar;
HBoxContainer *toolbar_right;
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index f135becf5f..e0bf8dfdb2 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -176,6 +176,86 @@ Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bo
return OK;
}
+Variant TileSetEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
+
+ return false;
+}
+
+bool TileSetEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+
+ Dictionary d = p_data;
+
+ if (!d.has("type"))
+ return false;
+
+ if (d.has("from") && (Object *)(d["from"]) == texture_list)
+ return false;
+
+ if (String(d["type"]) == "resource" && d.has("resource")) {
+ RES r = d["resource"];
+
+ Ref<Texture> texture = r;
+
+ if (texture.is_valid()) {
+
+ return true;
+ }
+ }
+
+ if (String(d["type"]) == "files") {
+
+ Vector<String> files = d["files"];
+
+ if (files.size() == 0)
+ return false;
+
+ for (int i = 0; i < files.size(); i++) {
+ String file = files[i];
+ String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
+
+ if (!ClassDB::is_parent_class(ftype, "Texture")) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ return false;
+}
+
+void TileSetEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+
+ if (!can_drop_data_fw(p_point, p_data, p_from))
+ return;
+
+ Dictionary d = p_data;
+
+ if (!d.has("type"))
+ return;
+
+ if (String(d["type"]) == "resource" && d.has("resource")) {
+ RES r = d["resource"];
+
+ Ref<Texture> texture = r;
+
+ if (texture.is_valid())
+ add_texture(texture);
+
+ if (texture_list->get_item_count() > 0) {
+ update_texture_list_icon();
+ texture_list->select(texture_list->get_item_count() - 1);
+ _on_texture_list_selected(texture_list->get_item_count() - 1);
+ }
+ }
+
+ if (String(d["type"]) == "files") {
+
+ PoolVector<String> files = d["files"];
+
+ _on_textures_added(files);
+ }
+}
+
void TileSetEditor::_bind_methods() {
ClassDB::bind_method("_undo_redo_import_scene", &TileSetEditor::_undo_redo_import_scene);
@@ -203,6 +283,10 @@ void TileSetEditor::_bind_methods() {
ClassDB::bind_method("_select_edited_shape_coord", &TileSetEditor::_select_edited_shape_coord);
ClassDB::bind_method("_sort_tiles", &TileSetEditor::_sort_tiles);
+ ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &TileSetEditor::get_drag_data_fw);
+ ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &TileSetEditor::can_drop_data_fw);
+ ClassDB::bind_method(D_METHOD("drop_data_fw"), &TileSetEditor::drop_data_fw);
+
ClassDB::bind_method("edit", &TileSetEditor::edit);
ClassDB::bind_method("add_texture", &TileSetEditor::add_texture);
ClassDB::bind_method("remove_texture", &TileSetEditor::remove_texture);
@@ -274,6 +358,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
texture_list->set_v_size_flags(SIZE_EXPAND_FILL);
texture_list->set_custom_minimum_size(Size2(200, 0));
texture_list->connect("item_selected", this, "_on_texture_list_selected");
+ texture_list->set_drag_forwarding(this);
HBoxContainer *tileset_toolbar_container = memnew(HBoxContainer);
left_container->add_child(tileset_toolbar_container);
@@ -494,6 +579,14 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
scroll->set_clip_contents(true);
+ empty_message = memnew(Label);
+ empty_message->set_text(TTR("Add or select a texture on the left panel to edit the tiles bound to it."));
+ empty_message->set_valign(Label::VALIGN_CENTER);
+ empty_message->set_align(Label::ALIGN_CENTER);
+ empty_message->set_autowrap(true);
+ empty_message->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(empty_message);
+
workspace_container = memnew(Control);
scroll->add_child(workspace_container);
@@ -542,7 +635,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
helper = memnew(TilesetEditorContext(this));
tile_names_visible = false;
- // config scale
+ // Config scale.
max_scale = 10.0f;
min_scale = 0.1f;
scale_ratio = 1.2f;
@@ -646,8 +739,7 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
for (int i = 0; i < p_paths.size(); i++) {
Ref<Texture> t = Ref<Texture>(ResourceLoader::load(p_paths[i]));
- ERR_EXPLAIN("'" + p_paths[i] + "' is not a valid texture.");
- ERR_CONTINUE(!t.is_valid());
+ ERR_CONTINUE_MSG(!t.is_valid(), "'" + p_paths[i] + "' is not a valid texture.");
if (texture_map.has(t->get_rid())) {
invalid_count++;
@@ -924,8 +1016,7 @@ void TileSetEditor::_on_workspace_draw() {
case EDITMODE_OCCLUSION:
case EDITMODE_NAVIGATION: {
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Vector2 coord = edited_shape_coord;
- draw_highlight_subtile(coord);
+ draw_highlight_subtile(edited_shape_coord);
}
draw_polygon_shapes();
draw_grid_snap();
@@ -1519,6 +1610,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
undo_redo->create_action(TTR("Edit Navigation Polygon"));
undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "set_vertices", edited_navigation_shape->get_vertices());
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "clear_polygons");
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "clear_polygons");
undo_redo->add_do_method(edited_navigation_shape.ptr(), "add_polygon", indices);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "add_polygon", edited_navigation_shape->get_polygon(0));
undo_redo->add_do_method(this, "_select_edited_shape_coord");
@@ -1872,7 +1965,7 @@ void TileSetEditor::_update_tile_data() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
for (int y = 0; y < cell_count.y; y++) {
for (int x = 0; x < cell_count.x; x++) {
SubtileData data;
@@ -1974,7 +2067,7 @@ void TileSetEditor::_select_previous_tile() {
case EDITMODE_Z_INDEX: {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
cell_count -= Vector2(1, 1);
edited_shape_coord = cell_count;
_select_edited_shape_coord();
@@ -2031,7 +2124,7 @@ void TileSetEditor::_select_next_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x >= cell_count.x - 1 && edited_shape_coord.y >= cell_count.y - 1) {
_select_next_tile();
} else {
@@ -2057,7 +2150,7 @@ void TileSetEditor::_select_previous_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x <= 0 && edited_shape_coord.y <= 0) {
_select_previous_tile();
} else {
@@ -2077,9 +2170,9 @@ void TileSetEditor::_select_next_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_next_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
@@ -2130,9 +2223,9 @@ void TileSetEditor::_select_previous_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_previous_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
@@ -3038,12 +3131,28 @@ void TileSetEditor::update_workspace_tile_mode() {
}
tools[SELECT_NEXT]->set_disabled(true);
tools[SELECT_PREVIOUS]->set_disabled(true);
+
+ tools[ZOOM_OUT]->hide();
+ tools[ZOOM_1]->hide();
+ tools[ZOOM_IN]->hide();
+ tools[VISIBLE_INFO]->hide();
+
+ scroll->hide();
+ empty_message->show();
} else {
for (int i = 1; i < WORKSPACE_MODE_MAX; i++) {
tool_workspacemode[i]->set_disabled(false);
}
tools[SELECT_NEXT]->set_disabled(false);
tools[SELECT_PREVIOUS]->set_disabled(false);
+
+ tools[ZOOM_OUT]->show();
+ tools[ZOOM_1]->show();
+ tools[ZOOM_IN]->show();
+ tools[VISIBLE_INFO]->show();
+
+ scroll->show();
+ empty_message->hide();
}
if (workspace_mode != WORKSPACE_EDIT) {
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 69ad8205a4..944dc04e4e 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -138,6 +138,7 @@ class TileSetEditor : public HSplitContainer {
int current_item_index;
Sprite *preview;
ScrollContainer *scroll;
+ Label *empty_message;
Control *workspace_container;
bool draw_handles;
Control *workspace_overlay;
@@ -173,6 +174,12 @@ class TileSetEditor : public HSplitContainer {
static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge);
void _undo_redo_import_scene(Node *p_scene, bool p_merge);
+ bool _is_drop_valid(const Dictionary &p_drag_data, const Dictionary &p_item_data) const;
+ Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
+ bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+ void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+ void _file_load_request(const PoolVector<String> &p_path, int p_at_pos = -1);
+
protected:
static void _bind_methods();
void _notification(int p_what);
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
new file mode 100644
index 0000000000..e8cd7692b6
--- /dev/null
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -0,0 +1,597 @@
+/*************************************************************************/
+/* version_control_editor_plugin.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 "version_control_editor_plugin.h"
+#include "core/script_language.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
+
+VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = NULL;
+
+void VersionControlEditorPlugin::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_selected_a_vcs"), &VersionControlEditorPlugin::_selected_a_vcs);
+ ClassDB::bind_method(D_METHOD("_initialize_vcs"), &VersionControlEditorPlugin::_initialize_vcs);
+ ClassDB::bind_method(D_METHOD("_send_commit_msg"), &VersionControlEditorPlugin::_send_commit_msg);
+ ClassDB::bind_method(D_METHOD("_refresh_stage_area"), &VersionControlEditorPlugin::_refresh_stage_area);
+ ClassDB::bind_method(D_METHOD("_stage_all"), &VersionControlEditorPlugin::_stage_all);
+ ClassDB::bind_method(D_METHOD("_stage_selected"), &VersionControlEditorPlugin::_stage_selected);
+ ClassDB::bind_method(D_METHOD("_view_file_diff"), &VersionControlEditorPlugin::_view_file_diff);
+ ClassDB::bind_method(D_METHOD("_refresh_file_diff"), &VersionControlEditorPlugin::_refresh_file_diff);
+ ClassDB::bind_method(D_METHOD("popup_vcs_set_up_dialog"), &VersionControlEditorPlugin::popup_vcs_set_up_dialog);
+
+ // Used to track the status of files in the staging area
+ BIND_ENUM_CONSTANT(CHANGE_TYPE_NEW);
+ BIND_ENUM_CONSTANT(CHANGE_TYPE_MODIFIED);
+ BIND_ENUM_CONSTANT(CHANGE_TYPE_RENAMED);
+ BIND_ENUM_CONSTANT(CHANGE_TYPE_DELETED);
+ BIND_ENUM_CONSTANT(CHANGE_TYPE_TYPECHANGE);
+}
+
+void VersionControlEditorPlugin::_selected_a_vcs(int p_id) {
+
+ List<StringName> available_addons = get_available_vcs_names();
+ const StringName selected_vcs = set_up_choice->get_item_text(p_id);
+}
+
+void VersionControlEditorPlugin::_populate_available_vcs_names() {
+
+ static bool called = false;
+
+ if (!called) {
+
+ List<StringName> available_addons = get_available_vcs_names();
+ for (int i = 0; i < available_addons.size(); i++) {
+
+ set_up_choice->add_item(available_addons[i]);
+ }
+
+ called = true;
+ }
+}
+
+VersionControlEditorPlugin *VersionControlEditorPlugin::get_singleton() {
+
+ return singleton ? singleton : memnew(VersionControlEditorPlugin);
+}
+
+void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_base) {
+
+ fetch_available_vcs_addon_names();
+ List<StringName> available_addons = get_available_vcs_names();
+ if (available_addons.size() >= 1) {
+
+ Size2 popup_size = Size2(400, 100);
+ Size2 window_size = p_gui_base->get_viewport_rect().size;
+ popup_size.x = MIN(window_size.x * 0.5, popup_size.x);
+ popup_size.y = MIN(window_size.y * 0.5, popup_size.y);
+
+ _populate_available_vcs_names();
+
+ set_up_dialog->popup_centered_clamped(popup_size * EDSCALE);
+ } else {
+
+ EditorNode::get_singleton()->show_warning(TTR("No VCS addons are available."), TTR("Error"));
+ }
+}
+
+void VersionControlEditorPlugin::_initialize_vcs() {
+
+ register_editor();
+
+ if (EditorVCSInterface::get_singleton()) {
+
+ ERR_EXPLAIN(EditorVCSInterface::get_singleton()->get_vcs_name() + " is already active");
+ return;
+ }
+
+ const int id = set_up_choice->get_selected_id();
+ String selected_addon = set_up_choice->get_item_text(id);
+
+ String path = ScriptServer::get_global_class_path(selected_addon);
+ Ref<Script> script = ResourceLoader::load(path);
+ if (!script.is_valid()) {
+
+ ERR_EXPLAIN("VCS Addon path is invalid");
+ }
+
+ EditorVCSInterface *vcs_interface = memnew(EditorVCSInterface);
+ ScriptInstance *addon_script_instance = script->instance_create(vcs_interface);
+ if (!addon_script_instance) {
+
+ ERR_FAIL_NULL(addon_script_instance);
+ return;
+ }
+
+ // The addon is attached as a script to the VCS interface as a proxy end-point
+ vcs_interface->set_script_and_instance(script.get_ref_ptr(), addon_script_instance);
+
+ EditorVCSInterface::set_singleton(vcs_interface);
+ EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_refresh_stage_area");
+
+ String res_dir = OS::get_singleton()->get_resource_dir();
+ if (!EditorVCSInterface::get_singleton()->initialize(res_dir)) {
+
+ ERR_EXPLAIN("VCS was not initialized");
+ }
+
+ _refresh_stage_area();
+}
+
+void VersionControlEditorPlugin::_send_commit_msg() {
+
+ String msg = commit_message->get_text();
+ if (msg == "") {
+
+ commit_status->set_text(TTR("No commit message was provided"));
+ return;
+ }
+
+ if (EditorVCSInterface::get_singleton()) {
+
+ if (staged_files_count == 0) {
+
+ commit_status->set_text(TTR("No files added to stage"));
+ return;
+ }
+
+ EditorVCSInterface::get_singleton()->commit(msg);
+
+ commit_message->set_text("");
+ version_control_dock_button->set_pressed(false);
+ } else {
+
+ WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
+ }
+
+ _update_commit_status();
+ _refresh_stage_area();
+ _clear_file_diff();
+}
+
+void VersionControlEditorPlugin::_refresh_stage_area() {
+
+ if (EditorVCSInterface::get_singleton()) {
+
+ staged_files_count = 0;
+ clear_stage_area();
+
+ Dictionary modified_file_paths = EditorVCSInterface::get_singleton()->get_modified_files_data();
+ String file_path;
+ for (int i = 0; i < modified_file_paths.size(); i++) {
+
+ file_path = modified_file_paths.get_key_at_index(i);
+ TreeItem *found = stage_files->search_item_text(file_path, 0, true);
+ if (!found) {
+
+ ChangeType change_index = (ChangeType)(int)modified_file_paths.get_value_at_index(i);
+ String change_text = file_path + " (" + change_type_to_strings[change_index] + ")";
+ Color &change_color = change_type_to_color[change_index];
+ TreeItem *new_item = stage_files->create_item(stage_files->get_root());
+ new_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
+ new_item->set_text(0, change_text);
+ new_item->set_metadata(0, file_path);
+ new_item->set_custom_color(0, change_color);
+ new_item->set_checked(0, true);
+ new_item->set_editable(0, true);
+ } else {
+
+ if (found->get_metadata(0) == diff_file_name->get_text()) {
+
+ _refresh_file_diff();
+ }
+ }
+ commit_status->set_text("New changes detected");
+ }
+ } else {
+
+ WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu.")
+ }
+}
+
+void VersionControlEditorPlugin::_stage_selected() {
+
+ if (!EditorVCSInterface::get_singleton()) {
+
+ WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
+ return;
+ }
+
+ staged_files_count = 0;
+ TreeItem *root = stage_files->get_root();
+ if (root) {
+
+ TreeItem *file_entry = root->get_children();
+ while (file_entry) {
+
+ if (file_entry->is_checked(0)) {
+
+ EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0));
+ file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor"));
+ staged_files_count++;
+ } else {
+
+ EditorVCSInterface::get_singleton()->unstage_file(file_entry->get_metadata(0));
+ file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ }
+
+ file_entry = file_entry->get_next();
+ }
+ }
+
+ _update_stage_status();
+}
+
+void VersionControlEditorPlugin::_stage_all() {
+
+ if (!EditorVCSInterface::get_singleton()) {
+
+ WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
+ return;
+ }
+
+ staged_files_count = 0;
+ TreeItem *root = stage_files->get_root();
+ if (root) {
+
+ TreeItem *file_entry = root->get_children();
+ while (file_entry) {
+
+ EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0));
+ file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor"));
+ file_entry->set_checked(0, true);
+ staged_files_count++;
+
+ file_entry = file_entry->get_next();
+ }
+ }
+
+ _update_stage_status();
+}
+
+void VersionControlEditorPlugin::_view_file_diff() {
+
+ version_control_dock_button->set_pressed(true);
+
+ String file_path = stage_files->get_selected()->get_metadata(0);
+
+ _display_file_diff(file_path);
+}
+
+void VersionControlEditorPlugin::_display_file_diff(String p_file_path) {
+
+ Array diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path);
+
+ diff_file_name->set_text(p_file_path);
+
+ diff->clear();
+ diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_font("source", "EditorFonts"));
+ for (int i = 0; i < diff_content.size(); i++) {
+
+ Dictionary line_result = diff_content[i];
+
+ if (line_result["status"] == "+") {
+
+ diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor"));
+ } else if (line_result["status"] == "-") {
+
+ diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
+ } else {
+
+ diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Label"));
+ }
+
+ diff->add_text((String)line_result["content"]);
+
+ diff->pop();
+ }
+ diff->pop();
+}
+
+void VersionControlEditorPlugin::_refresh_file_diff() {
+
+ String open_file = diff_file_name->get_text();
+ if (open_file != "") {
+
+ _display_file_diff(diff_file_name->get_text());
+ }
+}
+
+void VersionControlEditorPlugin::_clear_file_diff() {
+
+ diff->clear();
+ diff_file_name->set_text("");
+ version_control_dock_button->set_pressed(false);
+}
+
+void VersionControlEditorPlugin::_update_stage_status() {
+
+ String status;
+ if (staged_files_count == 1) {
+
+ status = "Stage contains 1 file";
+ } else {
+
+ status = "Stage contains " + String::num_int64(staged_files_count) + " files";
+ }
+ commit_status->set_text(status);
+}
+
+void VersionControlEditorPlugin::_update_commit_status() {
+
+ String status;
+ if (staged_files_count == 1) {
+
+ status = "Committed 1 file";
+ } else {
+
+ status = "Committed " + String::num_int64(staged_files_count) + " files ";
+ }
+ commit_status->set_text(status);
+ staged_files_count = 0;
+}
+
+void VersionControlEditorPlugin::register_editor() {
+
+ if (!EditorVCSInterface::get_singleton()) {
+
+ EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock);
+ TabContainer *dock_vbc = (TabContainer *)version_commit_dock->get_parent_control();
+ dock_vbc->set_tab_title(version_commit_dock->get_index(), TTR("Commit"));
+
+ ToolButton *vc = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock);
+ set_version_control_tool_button(vc);
+ }
+}
+
+void VersionControlEditorPlugin::fetch_available_vcs_addon_names() {
+
+ List<StringName> global_classes;
+ ScriptServer::get_global_class_list(&global_classes);
+
+ for (int i = 0; i != global_classes.size(); i++) {
+
+ String path = ScriptServer::get_global_class_path(global_classes[i]);
+ Ref<Script> script = ResourceLoader::load(path);
+
+ if (script->get_instance_base_type() == "EditorVCSInterface") {
+
+ available_addons.push_back(global_classes[i]);
+ }
+ }
+}
+
+void VersionControlEditorPlugin::clear_stage_area() {
+
+ stage_files->get_root()->clear_children();
+}
+
+void VersionControlEditorPlugin::shut_down() {
+
+ if (EditorVCSInterface::get_singleton()) {
+
+ EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "_refresh_stage_area");
+ EditorVCSInterface::get_singleton()->shut_down();
+ memdelete(EditorVCSInterface::get_singleton());
+ EditorVCSInterface::set_singleton(NULL);
+
+ EditorNode::get_singleton()->remove_control_from_dock(version_commit_dock);
+ EditorNode::get_singleton()->remove_bottom_panel_item(version_control_dock);
+ }
+}
+
+bool VersionControlEditorPlugin::get_is_vcs_intialized() const {
+
+ return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_is_vcs_intialized() : false;
+}
+
+const String VersionControlEditorPlugin::get_vcs_name() const {
+
+ return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_vcs_name() : "";
+}
+
+VersionControlEditorPlugin::VersionControlEditorPlugin() {
+
+ singleton = this;
+ staged_files_count = 0;
+
+ version_control_actions = memnew(PopupMenu);
+ version_control_actions->set_v_size_flags(BoxContainer::SIZE_SHRINK_CENTER);
+
+ set_up_dialog = memnew(AcceptDialog);
+ set_up_dialog->set_title(TTR("Set Up Version Control"));
+ set_up_dialog->set_custom_minimum_size(Size2(400, 100));
+ version_control_actions->add_child(set_up_dialog);
+
+ set_up_ok_button = set_up_dialog->get_ok();
+ set_up_ok_button->set_text(TTR("Close"));
+
+ set_up_vbc = memnew(VBoxContainer);
+ set_up_vbc->set_alignment(VBoxContainer::ALIGN_CENTER);
+ set_up_dialog->add_child(set_up_vbc);
+
+ set_up_hbc = memnew(HBoxContainer);
+ set_up_hbc->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL);
+ set_up_vbc->add_child(set_up_hbc);
+
+ set_up_vcs_status = memnew(RichTextLabel);
+ set_up_vcs_status->set_text(TTR("VCS Addon is not initialized"));
+ set_up_vbc->add_child(set_up_vcs_status);
+
+ set_up_vcs_label = memnew(Label);
+ set_up_vcs_label->set_text(TTR("Version Control System"));
+ set_up_hbc->add_child(set_up_vcs_label);
+
+ set_up_choice = memnew(OptionButton);
+ set_up_choice->set_h_size_flags(HBoxContainer::SIZE_EXPAND_FILL);
+ set_up_choice->connect("item_selected", this, "_selected_a_vcs");
+ set_up_hbc->add_child(set_up_choice);
+
+ set_up_init_settings = NULL;
+
+ set_up_init_button = memnew(Button);
+ set_up_init_button->set_text(TTR("Initialize"));
+ set_up_init_button->connect("pressed", this, "_initialize_vcs");
+ set_up_vbc->add_child(set_up_init_button);
+
+ version_control_actions->set_v_size_flags(PopupMenu::SIZE_EXPAND_FILL);
+ version_control_actions->set_h_size_flags(PopupMenu::SIZE_EXPAND_FILL);
+
+ version_commit_dock = memnew(VBoxContainer);
+ version_commit_dock->set_visible(false);
+
+ commit_box_vbc = memnew(VBoxContainer);
+ commit_box_vbc->set_alignment(VBoxContainer::ALIGN_BEGIN);
+ commit_box_vbc->set_h_size_flags(VBoxContainer::SIZE_EXPAND_FILL);
+ commit_box_vbc->set_v_size_flags(VBoxContainer::SIZE_EXPAND_FILL);
+ version_commit_dock->add_child(commit_box_vbc);
+
+ stage_tools = memnew(HSplitContainer);
+ stage_tools->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED);
+ commit_box_vbc->add_child(stage_tools);
+
+ staging_area_label = memnew(Label);
+ staging_area_label->set_h_size_flags(Label::SIZE_EXPAND_FILL);
+ staging_area_label->set_text(TTR("Staging area"));
+ stage_tools->add_child(staging_area_label);
+
+ refresh_button = memnew(Button);
+ refresh_button->set_tooltip(TTR("Detect new changes"));
+ refresh_button->set_text(TTR("Refresh"));
+ refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Reload", "EditorIcons"));
+ refresh_button->connect("pressed", this, "_refresh_stage_area");
+ stage_tools->add_child(refresh_button);
+
+ stage_files = memnew(Tree);
+ stage_files->set_h_size_flags(Tree::SIZE_EXPAND_FILL);
+ stage_files->set_v_size_flags(Tree::SIZE_EXPAND_FILL);
+ stage_files->set_columns(1);
+ stage_files->set_column_title(0, TTR("Changes"));
+ stage_files->set_column_titles_visible(true);
+ stage_files->set_allow_reselect(true);
+ stage_files->set_allow_rmb_select(true);
+ stage_files->set_select_mode(Tree::SelectMode::SELECT_MULTI);
+ stage_files->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
+ stage_files->connect("cell_selected", this, "_view_file_diff");
+ stage_files->create_item();
+ stage_files->set_hide_root(true);
+ commit_box_vbc->add_child(stage_files);
+
+ change_type_to_strings[CHANGE_TYPE_NEW] = TTR("New");
+ change_type_to_strings[CHANGE_TYPE_MODIFIED] = TTR("Modified");
+ change_type_to_strings[CHANGE_TYPE_RENAMED] = TTR("Renamed");
+ change_type_to_strings[CHANGE_TYPE_DELETED] = TTR("Deleted");
+ change_type_to_strings[CHANGE_TYPE_TYPECHANGE] = TTR("Typechange");
+
+ change_type_to_color[CHANGE_TYPE_NEW] = EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor");
+ change_type_to_color[CHANGE_TYPE_MODIFIED] = EditorNode::get_singleton()->get_gui_base()->get_color("warning_color", "Editor");
+ change_type_to_color[CHANGE_TYPE_RENAMED] = EditorNode::get_singleton()->get_gui_base()->get_color("disabled_font_color", "Editor");
+ change_type_to_color[CHANGE_TYPE_DELETED] = EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor");
+ change_type_to_color[CHANGE_TYPE_TYPECHANGE] = EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Editor");
+
+ stage_buttons = memnew(HSplitContainer);
+ stage_buttons->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN_COLLAPSED);
+ commit_box_vbc->add_child(stage_buttons);
+
+ stage_selected_button = memnew(Button);
+ stage_selected_button->set_h_size_flags(Button::SIZE_EXPAND_FILL);
+ stage_selected_button->set_text(TTR("Stage Selected"));
+ stage_selected_button->connect("pressed", this, "_stage_selected");
+ stage_buttons->add_child(stage_selected_button);
+
+ stage_all_button = memnew(Button);
+ stage_all_button->set_text(TTR("Stage All"));
+ stage_all_button->connect("pressed", this, "_stage_all");
+ stage_buttons->add_child(stage_all_button);
+
+ commit_box_vbc->add_child(memnew(HSeparator));
+
+ commit_message = memnew(TextEdit);
+ commit_message->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ commit_message->set_h_grow_direction(Control::GrowDirection::GROW_DIRECTION_BEGIN);
+ commit_message->set_v_grow_direction(Control::GrowDirection::GROW_DIRECTION_END);
+ commit_message->set_custom_minimum_size(Size2(200, 100));
+ commit_message->set_wrap_enabled(true);
+ commit_message->set_text(TTR("Add a commit message"));
+ commit_box_vbc->add_child(commit_message);
+
+ commit_button = memnew(Button);
+ commit_button->set_text(TTR("Commit Changes"));
+ commit_button->connect("pressed", this, "_send_commit_msg");
+ commit_box_vbc->add_child(commit_button);
+
+ commit_status = memnew(Label);
+ commit_status->set_align(Label::ALIGN_CENTER);
+ commit_box_vbc->add_child(commit_status);
+
+ version_control_dock = memnew(PanelContainer);
+ version_control_dock->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ version_control_dock->hide();
+
+ diff_vbc = memnew(VBoxContainer);
+ diff_vbc->set_h_size_flags(HBoxContainer::SIZE_FILL);
+ diff_vbc->set_v_size_flags(HBoxContainer::SIZE_FILL);
+ version_control_dock->add_child(diff_vbc);
+
+ diff_hbc = memnew(HBoxContainer);
+ diff_hbc->set_h_size_flags(HBoxContainer::SIZE_FILL);
+ diff_vbc->add_child(diff_hbc);
+
+ diff_heading = memnew(Label);
+ diff_heading->set_text(TTR("Status"));
+ diff_heading->set_tooltip(TTR("View file diffs before committing them to the latest version"));
+ diff_hbc->add_child(diff_heading);
+
+ diff_file_name = memnew(Label);
+ diff_file_name->set_text(TTR("No file diff is active"));
+ diff_file_name->set_h_size_flags(Label::SIZE_EXPAND_FILL);
+ diff_file_name->set_align(Label::ALIGN_RIGHT);
+ diff_hbc->add_child(diff_file_name);
+
+ diff_refresh_button = memnew(Button);
+ diff_refresh_button->set_tooltip(TTR("Detect changes in file diff"));
+ diff_refresh_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Reload", "EditorIcons"));
+ diff_refresh_button->connect("pressed", this, "_refresh_file_diff");
+ diff_hbc->add_child(diff_refresh_button);
+
+ diff = memnew(RichTextLabel);
+ diff->set_h_size_flags(TextEdit::SIZE_EXPAND_FILL);
+ diff->set_v_size_flags(TextEdit::SIZE_EXPAND_FILL);
+ diff->set_selection_enabled(true);
+ diff_vbc->add_child(diff);
+}
+
+VersionControlEditorPlugin::~VersionControlEditorPlugin() {
+
+ shut_down();
+ memdelete(version_control_dock);
+ memdelete(version_commit_dock);
+ memdelete(version_control_actions);
+}
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
new file mode 100644
index 0000000000..450ebccce1
--- /dev/null
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* version_control_editor_plugin.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 VERSION_CONTROL_EDITOR_PLUGIN_H
+#define VERSION_CONTROL_EDITOR_PLUGIN_H
+
+#include "editor/editor_plugin.h"
+#include "editor/editor_vcs_interface.h"
+#include "scene/gui/container.h"
+#include "scene/gui/rich_text_label.h"
+#include "scene/gui/text_edit.h"
+#include "scene/gui/tree.h"
+
+class VersionControlEditorPlugin : public EditorPlugin {
+
+ GDCLASS(VersionControlEditorPlugin, EditorPlugin)
+
+public:
+ enum ChangeType {
+
+ CHANGE_TYPE_NEW = 0,
+ CHANGE_TYPE_MODIFIED = 1,
+ CHANGE_TYPE_RENAMED = 2,
+ CHANGE_TYPE_DELETED = 3,
+ CHANGE_TYPE_TYPECHANGE = 4
+ };
+
+private:
+ static VersionControlEditorPlugin *singleton;
+
+ int staged_files_count;
+ List<StringName> available_addons;
+
+ PopupMenu *version_control_actions;
+ AcceptDialog *set_up_dialog;
+ VBoxContainer *set_up_vbc;
+ HBoxContainer *set_up_hbc;
+ Label *set_up_vcs_label;
+ OptionButton *set_up_choice;
+ PanelContainer *set_up_init_settings;
+ Button *set_up_init_button;
+ RichTextLabel *set_up_vcs_status;
+ Button *set_up_ok_button;
+
+ HashMap<ChangeType, String> change_type_to_strings;
+ HashMap<ChangeType, Color> change_type_to_color;
+
+ VBoxContainer *version_commit_dock;
+ VBoxContainer *commit_box_vbc;
+ HSplitContainer *stage_tools;
+ Tree *stage_files;
+ TreeItem *new_files;
+ TreeItem *modified_files;
+ TreeItem *renamed_files;
+ TreeItem *deleted_files;
+ TreeItem *typechange_files;
+ Label *staging_area_label;
+ HSplitContainer *stage_buttons;
+ Button *stage_all_button;
+ Button *stage_selected_button;
+ Button *refresh_button;
+ TextEdit *commit_message;
+ Button *commit_button;
+ Label *commit_status;
+
+ PanelContainer *version_control_dock;
+ ToolButton *version_control_dock_button;
+ VBoxContainer *diff_vbc;
+ HBoxContainer *diff_hbc;
+ Button *diff_refresh_button;
+ Label *diff_file_name;
+ Label *diff_heading;
+ RichTextLabel *diff;
+
+ void _populate_available_vcs_names();
+ void _selected_a_vcs(int p_id);
+ void _initialize_vcs();
+ void _send_commit_msg();
+ void _refresh_stage_area();
+ void _stage_selected();
+ void _stage_all();
+ void _view_file_diff();
+ void _display_file_diff(String p_file_path);
+ void _refresh_file_diff();
+ void _clear_file_diff();
+ void _update_stage_status();
+ void _update_commit_status();
+
+ friend class EditorVCSInterface;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static VersionControlEditorPlugin *get_singleton();
+
+ void popup_vcs_set_up_dialog(const Control *p_gui_base);
+ void set_version_control_tool_button(ToolButton *p_button) { version_control_dock_button = p_button; }
+
+ PopupMenu *get_version_control_actions_panel() const { return version_control_actions; }
+ VBoxContainer *get_version_commit_dock() const { return version_commit_dock; }
+ PanelContainer *get_version_control_dock() const { return version_control_dock; }
+
+ List<StringName> get_available_vcs_names() const { return available_addons; }
+ bool get_is_vcs_intialized() const;
+ const String get_vcs_name() const;
+
+ void register_editor();
+ void fetch_available_vcs_addon_names();
+ void clear_stage_area();
+ void shut_down();
+
+ VersionControlEditorPlugin();
+ ~VersionControlEditorPlugin();
+};
+
+VARIANT_ENUM_CAST(VersionControlEditorPlugin::ChangeType);
+
+#endif // !VERSION_CONTROL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index c1debfe482..82baa99da2 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -41,18 +41,19 @@
#include "scene/gui/panel.h"
#include "scene/main/viewport.h"
#include "scene/resources/visual_shader_nodes.h"
+#include "servers/visual/shader_types.h"
-Control *VisualShaderNodePlugin::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (get_script_instance()) {
- return get_script_instance()->call("create_editor", p_node);
+ return get_script_instance()->call("create_editor", p_parent_resource, p_node);
}
return NULL;
}
void VisualShaderNodePlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
+ BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
}
///////////////////
@@ -69,8 +70,16 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
}
visual_shader = Ref<VisualShader>(p_visual_shader);
+ if (!visual_shader->is_connected("changed", this, "_update_preview")) {
+ visual_shader->connect("changed", this, "_update_preview");
+ }
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
} else {
+ if (visual_shader.is_valid()) {
+ if (visual_shader->is_connected("changed", this, "")) {
+ visual_shader->disconnect("changed", this, "_update_preview");
+ }
+ }
visual_shader.unref();
}
@@ -78,7 +87,10 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
hide();
} else {
if (changed) { // to avoid tree collapse
+ _clear_buffer();
+ _update_custom_nodes();
_update_options_menu();
+ _update_preview();
}
_update_graph();
}
@@ -94,31 +106,36 @@ void VisualShaderEditor::remove_plugin(const Ref<VisualShaderNodePlugin> &p_plug
plugins.erase(p_plugin);
}
-void VisualShaderEditor::add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
-
+void VisualShaderEditor::clear_custom_types() {
for (int i = 0; i < add_options.size(); i++) {
- ERR_FAIL_COND(add_options[i].script == p_script);
+ if (add_options[i].is_custom) {
+ add_options.remove(i);
+ }
}
-
- AddOption ao;
- ao.name = p_name;
- ao.script = p_script;
- ao.category = p_category;
- add_options.push_back(ao);
-
- _update_options_menu();
}
-void VisualShaderEditor::remove_custom_type(const Ref<Script> &p_script) {
+void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category) {
+
+ ERR_FAIL_COND(!p_name.is_valid_identifier());
+ ERR_FAIL_COND(!p_script.is_valid());
for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].script == p_script) {
- add_options.remove(i);
- return;
+ if (add_options[i].is_custom) {
+ if (add_options[i].script == p_script)
+ return;
}
}
- _update_options_menu();
+ AddOption ao;
+ ao.name = p_name;
+ ao.script = p_script;
+ ao.return_type = p_return_icon_type;
+ ao.description = p_description;
+ ao.category = p_category;
+ ao.sub_category = p_sub_category;
+ ao.is_custom = true;
+
+ add_options.push_back(ao);
}
bool VisualShaderEditor::_is_available(int p_mode) {
@@ -161,6 +178,66 @@ bool VisualShaderEditor::_is_available(int p_mode) {
return (p_mode == -1 || (p_mode & current_mode) != 0);
}
+void VisualShaderEditor::_update_custom_nodes() {
+ clear_custom_types();
+ List<StringName> class_list;
+ ScriptServer::get_global_class_list(&class_list);
+ for (int i = 0; i < class_list.size(); i++) {
+ if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
+
+ String script_path = ScriptServer::get_global_class_path(class_list[i]);
+ Ref<Resource> res = ResourceLoader::load(script_path);
+ ERR_FAIL_COND(res.is_null());
+ ERR_FAIL_COND(!res->is_class("Script"));
+ Ref<Script> script = Ref<Script>(res);
+
+ Ref<VisualShaderNodeCustom> ref;
+ ref.instance();
+ ref->set_script(script.get_ref_ptr());
+
+ String name;
+ if (ref->has_method("_get_name")) {
+ name = (String)ref->call("_get_name");
+ } else {
+ name = "Unnamed";
+ }
+
+ String description = "";
+ if (ref->has_method("_get_description")) {
+ description = (String)ref->call("_get_description");
+ }
+
+ int return_icon_type = -1;
+ if (ref->has_method("_get_return_icon_type")) {
+ return_icon_type = (int)ref->call("_get_return_icon_type");
+ }
+
+ String category = "";
+ if (ref->has_method("_get_category")) {
+ category = (String)ref->call("_get_category");
+ }
+ if (category == "") {
+ category = "Custom";
+ }
+
+ String sub_category = "";
+ if (ref->has_method("_get_subcategory")) {
+ sub_category = (String)ref->call("_get_subcategory");
+ }
+
+ add_custom_type(name, script, description, return_icon_type, category, sub_category);
+ }
+ }
+}
+
+String VisualShaderEditor::_get_description(int p_idx) {
+ if (add_options[p_idx].highend) {
+ return TTR("(GLES3 only)") + " " + add_options[p_idx].description; // TODO: change it to (Vulkan Only) when its ready
+ } else {
+ return add_options[p_idx].description;
+ }
+}
+
void VisualShaderEditor::_update_options_menu() {
node_desc->set_text("");
@@ -184,6 +261,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()) {
@@ -205,6 +287,9 @@ void VisualShaderEditor::_update_options_menu() {
if (!use_filter || add_options[i].name.findn(filter) != -1) {
+ if ((add_options[i].func != current_func && add_options[i].func != -1) || !_is_available(add_options[i].mode))
+ continue;
+
if (prev_category != add_options[i].category) {
if (category != NULL && item_count == 0) {
memdelete(category);
@@ -235,65 +320,52 @@ void VisualShaderEditor::_update_options_menu() {
sub_category->set_collapsed(true);
}
}
- if (sub_category != NULL) {
- 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);
- item->set_text(0, add_options[i].name);
- if (is_first_item) {
- item->select(0);
- is_first_item = false;
- }
- switch (add_options[i].return_type) {
- case VisualShaderNode::PORT_TYPE_SCALAR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_COLOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
- break;
- default:
- break;
- }
- item->set_meta("id", i);
- }
- }
} else {
- if (category != NULL) {
- 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);
- item->set_text(0, add_options[i].name);
- switch (add_options[i].return_type) {
- case VisualShaderNode::PORT_TYPE_SCALAR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_VECTOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
- break;
- case VisualShaderNode::PORT_TYPE_COLOR:
- item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
- break;
- default:
- break;
- }
- item->set_meta("id", i);
- }
+ sub_category = NULL;
+ }
+
+ TreeItem *p_category = NULL;
+
+ if (sub_category != NULL) {
+ p_category = sub_category;
+ ++item_count2;
+ } else if (category != NULL) {
+ p_category = category;
+ ++item_count;
+ }
+
+ if (p_category != NULL) {
+ TreeItem *item = members->create_item(p_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 && use_filter) {
+ item->select(0);
+ node_desc->set_text(_get_description(i));
+ is_first_item = false;
+ }
+ switch (add_options[i].return_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
+ break;
+ case VisualShaderNode::PORT_TYPE_ICON_COLOR:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
+ break;
+ default:
+ break;
}
+ item->set_meta("id", i);
}
prev_sub_category = add_options[i].sub_category;
@@ -338,6 +410,7 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) {
node->add_color_override("title_color", c);
c.a = 0.7;
node->add_color_override("close_color", c);
+ node->add_color_override("resizer_color", c);
}
}
@@ -425,7 +498,7 @@ void VisualShaderEditor::_update_graph() {
int port_offset = 0;
if (is_group) {
- port_offset++;
+ port_offset += 2;
}
Ref<VisualShaderNodeUniform> uniform = vsnode;
@@ -449,7 +522,7 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins.write[i]->create_editor(vsnode);
+ custom_editor = plugins.write[i]->create_editor(visual_shader, vsnode);
if (custom_editor) {
break;
}
@@ -464,21 +537,28 @@ void VisualShaderEditor::_update_graph() {
}
if (is_group) {
- HBoxContainer *hb2 = memnew(HBoxContainer);
- Button *add_input_btn = memnew(Button);
- add_input_btn->set_text(TTR("Add input +"));
- add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_input_btn);
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
+ node->add_child(offset);
- hb2->add_spacer();
+ if (group_node->is_editable()) {
+ HBoxContainer *hb2 = memnew(HBoxContainer);
- Button *add_output_btn = memnew(Button);
- add_output_btn->set_text(TTR("Add output +"));
- add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_output_btn);
+ Button *add_input_btn = memnew(Button);
+ add_input_btn->set_text(TTR("Add input +"));
+ add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_input_btn);
- node->add_child(hb2);
+ hb2->add_spacer();
+
+ Button *add_output_btn = memnew(Button);
+ add_output_btn->set_text(TTR("Add output +"));
+ add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_output_btn);
+
+ node->add_child(hb2);
+ }
}
for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) {
@@ -511,6 +591,7 @@ void VisualShaderEditor::_update_graph() {
}
HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_constant_override("separation", 7 * EDSCALE);
Variant default_value;
@@ -529,6 +610,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));
@@ -543,7 +627,6 @@ void VisualShaderEditor::_update_graph() {
}
if (i == 0 && custom_editor) {
-
hb->add_child(custom_editor);
custom_editor->set_h_size_flags(SIZE_EXPAND_FILL);
} else {
@@ -551,7 +634,6 @@ void VisualShaderEditor::_update_graph() {
if (valid_left) {
if (is_group) {
-
OptionButton *type_box = memnew(OptionButton);
hb->add_child(type_box);
type_box->add_item(TTR("Scalar"));
@@ -564,9 +646,9 @@ void VisualShaderEditor::_update_graph() {
LineEdit *name_box = memnew(LineEdit);
hb->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(SIZE_EXPAND_FILL);
name_box->set_text(name_left);
- name_box->set_expand_to_text_length(true);
name_box->connect("text_entered", this, "_change_input_port_name", varray(name_box, nodes[n_i], i));
name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, nodes[n_i], i, false));
@@ -584,7 +666,9 @@ void VisualShaderEditor::_update_graph() {
}
}
- hb->add_spacer();
+ if (!is_group) {
+ hb->add_spacer();
+ }
if (valid_right) {
if (is_group) {
@@ -596,9 +680,9 @@ void VisualShaderEditor::_update_graph() {
LineEdit *name_box = memnew(LineEdit);
hb->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(SIZE_EXPAND_FILL);
name_box->set_text(name_right);
- name_box->set_expand_to_text_length(true);
name_box->connect("text_entered", this, "_change_output_port_name", varray(name_box, nodes[n_i], i));
name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, nodes[n_i], i, true));
@@ -659,7 +743,7 @@ void VisualShaderEditor::_update_graph() {
}
offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
+ offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
node->add_child(offset);
String error = vsnode->get_warning(visual_shader->get_mode(), type);
@@ -676,12 +760,14 @@ void VisualShaderEditor::_update_graph() {
expression_node->set_control(expression_box, 0);
node->add_child(expression_box);
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
expression_box->set_syntax_coloring(true);
+ expression_box->add_color_override("background_color", background_color);
for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
@@ -934,8 +1020,10 @@ void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
}
void VisualShaderEditor::_rebuild() {
- EditorNode::get_singleton()->get_log()->clear();
- visual_shader->rebuild();
+ if (visual_shader != NULL) {
+ EditorNode::get_singleton()->get_log()->clear();
+ visual_shader->rebuild();
+ }
}
void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) {
@@ -994,7 +1082,7 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
}
undo_redo->create_action(TTR("Resize VisualShader node"), UndoRedo::MERGE_ENDS);
- undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size / EDSCALE);
+ undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size);
undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size());
undo_redo->commit_action();
}
@@ -1131,7 +1219,9 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
Ref<VisualShaderNode> vsnode;
- if (add_options[p_idx].type != String()) {
+ bool is_custom = add_options[p_idx].is_custom;
+
+ if (!is_custom && add_options[p_idx].type != String()) {
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
ERR_FAIL_COND(!vsn);
@@ -1150,6 +1240,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) {
@@ -1351,6 +1453,9 @@ void VisualShaderEditor::_delete_request(int which) {
undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, which);
undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, which), which);
+ undo_redo->add_do_method(this, "_clear_buffer");
+ undo_redo->add_undo_method(this, "_clear_buffer");
+
// restore size, inputs and outputs if node is group
VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr());
if (group) {
@@ -1481,11 +1586,36 @@ void VisualShaderEditor::_notification(int p_what) {
node_filter->set_right_icon(Control::get_icon("Search", "EditorIcons"));
+ preview_shader->set_icon(Control::get_icon("Shader", "EditorIcons"));
+
+ {
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
+ Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
+ Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
+ Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
+
+ preview_text->add_color_override("background_color", background_color);
+
+ for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
+
+ preview_text->add_keyword_color(E->get(), keyword_color);
+ }
+
+ preview_text->add_font_override("font", get_font("expression", "EditorFonts"));
+ preview_text->add_color_override("font_color", text_color);
+ preview_text->add_color_override("symbol_color", symbol_color);
+ preview_text->add_color_region("/*", "*/", comment_color, false);
+ preview_text->add_color_region("//", "", comment_color, false);
+
+ error_text->add_font_override("font", get_font("status_source", "EditorFonts"));
+ error_text->add_color_override("font_color", get_color("error_color", "Editor"));
+ }
+
tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Tools", "EditorIcons"));
if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())
_update_graph();
- } else if (p_what == NOTIFICATION_PROCESS) {
}
}
@@ -1506,12 +1636,32 @@ void VisualShaderEditor::_node_changed(int p_id) {
}
}
-void VisualShaderEditor::_duplicate_nodes() {
+void VisualShaderEditor::_dup_update_excluded(int p_type, Set<int> &r_excluded) {
+ r_excluded.clear();
+ VisualShader::Type type = (VisualShader::Type)p_type;
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ for (int i = 0; i < graph->get_child_count(); i++) {
- List<int> nodes;
- Set<int> excluded;
+ GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
+ if (gn) {
+ int id = String(gn->get_name()).to_int();
+ Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
+ Ref<VisualShaderNodeOutput> output = node;
+ if (output.is_valid()) {
+ r_excluded.insert(id);
+ continue;
+ }
+ r_excluded.insert(id);
+ }
+ }
+}
+
+void VisualShaderEditor::_dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded) {
+
+ VisualShader::Type type = (VisualShader::Type)p_type;
+
+ selection_center.x = 0.0f;
+ selection_center.y = 0.0f;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -1521,33 +1671,53 @@ void VisualShaderEditor::_duplicate_nodes() {
Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
Ref<VisualShaderNodeOutput> output = node;
if (output.is_valid()) { // can't duplicate output
- excluded.insert(id);
+ r_excluded.insert(id);
continue;
}
if (node.is_valid() && gn->is_selected()) {
- nodes.push_back(id);
+ Vector2 pos = visual_shader->get_node_position(type, id);
+ selection_center += pos;
+ r_nodes.push_back(id);
}
- excluded.insert(id);
+ r_excluded.insert(id);
}
}
- if (nodes.empty())
- return;
+ selection_center /= (float)r_nodes.size();
+}
- undo_redo->create_action(TTR("Duplicate Nodes"));
+void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select) {
+
+ VisualShader::Type type = (VisualShader::Type)p_type;
+ VisualShader::Type pasted_type = (VisualShader::Type)p_pasted_type;
int base_id = visual_shader->get_valid_node_id(type);
int id_from = base_id;
Map<int, int> connection_remap;
+ Set<int> unsupported_set;
- for (List<int>::Element *E = nodes.front(); E; E = E->next()) {
+ for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) {
connection_remap[E->get()] = id_from;
- Ref<VisualShaderNode> node = visual_shader->get_node(type, E->get());
+ Ref<VisualShaderNode> node = visual_shader->get_node(pasted_type, E->get());
+
+ bool unsupported = false;
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].type == node->get_class_name()) {
+ if (!_is_available(add_options[i].mode)) {
+ unsupported = true;
+ }
+ break;
+ }
+ }
+ if (unsupported) {
+ unsupported_set.insert(E->get());
+ continue;
+ }
Ref<VisualShaderNode> dupli = node->duplicate();
- undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(type, E->get()) + Vector2(10, 10) * EDSCALE, id_from);
+ undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(pasted_type, E->get()) + p_offset, id_from);
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from);
// duplicate size, inputs and outputs if node is group
@@ -1567,9 +1737,12 @@ void VisualShaderEditor::_duplicate_nodes() {
}
List<VisualShader::Connection> conns;
- visual_shader->get_node_connections(type, &conns);
+ visual_shader->get_node_connections(pasted_type, &conns);
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (unsupported_set.has(E->get().from_node) || unsupported_set.has(E->get().to_node)) {
+ continue;
+ }
if (connection_remap.has(E->get().from_node) && connection_remap.has(E->get().to_node)) {
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes_forced", type, connection_remap[E->get().from_node], E->get().from_port, connection_remap[E->get().to_node], E->get().to_port);
}
@@ -1579,21 +1752,71 @@ void VisualShaderEditor::_duplicate_nodes() {
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
- // reselect duplicated nodes by excluding the other ones
- for (int i = 0; i < graph->get_child_count(); i++) {
-
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- int id = String(gn->get_name()).to_int();
- if (!excluded.has(id)) {
- gn->set_selected(true);
- } else {
- gn->set_selected(false);
+ if (p_select) {
+ // reselect duplicated nodes by excluding the other ones
+ for (int i = 0; i < graph->get_child_count(); i++) {
+
+ GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
+ if (gn) {
+ int id = String(gn->get_name()).to_int();
+ if (!r_excluded.has(id)) {
+ gn->set_selected(true);
+ } else {
+ gn->set_selected(false);
+ }
}
}
}
}
+void VisualShaderEditor::_clear_buffer() {
+
+ copy_nodes_buffer.clear();
+ copy_nodes_excluded_buffer.clear();
+}
+
+void VisualShaderEditor::_duplicate_nodes() {
+
+ int type = edit_type->get_selected();
+
+ List<int> nodes;
+ Set<int> excluded;
+
+ _dup_copy_nodes(type, nodes, excluded);
+
+ if (nodes.empty())
+ return;
+
+ undo_redo->create_action(TTR("Duplicate Nodes"));
+
+ _dup_paste_nodes(type, type, nodes, excluded, Vector2(10, 10) * EDSCALE, true);
+}
+
+void VisualShaderEditor::_copy_nodes() {
+
+ copy_type = edit_type->get_selected();
+
+ _clear_buffer();
+
+ _dup_copy_nodes(copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer);
+}
+
+void VisualShaderEditor::_paste_nodes() {
+
+ if (copy_nodes_buffer.empty())
+ return;
+
+ int type = edit_type->get_selected();
+
+ undo_redo->create_action(TTR("Paste Nodes"));
+
+ float scale = graph->get_zoom();
+
+ _dup_paste_nodes(type, copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + graph->get_local_mouse_position() / scale - selection_center), false);
+
+ _dup_update_excluded(type, copy_nodes_excluded_buffer); // to prevent selection of previous copies at new paste
+}
+
void VisualShaderEditor::_on_nodes_delete() {
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
@@ -1620,6 +1843,9 @@ void VisualShaderEditor::_on_nodes_delete() {
undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get());
undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F->get()), F->get());
+ undo_redo->add_do_method(this, "_clear_buffer");
+ undo_redo->add_undo_method(this, "_clear_buffer");
+
// restore size, inputs and outputs if node is group
VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr());
if (group) {
@@ -1664,6 +1890,7 @@ void VisualShaderEditor::_on_nodes_delete() {
}
void VisualShaderEditor::_mode_selected(int p_id) {
+
_update_options_menu();
_update_graph();
}
@@ -1711,7 +1938,7 @@ 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);
+ node_desc->set_text(_get_description(item->get_meta("id")));
} else {
members_dialog->get_ok()->set_disabled(true);
node_desc->set_text("");
@@ -1831,6 +2058,48 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
}
+void VisualShaderEditor::_show_preview_text() {
+ preview_showed = !preview_showed;
+ preview_vbox->set_visible(preview_showed);
+ if (preview_showed) {
+ if (pending_update_preview) {
+ _update_preview();
+ pending_update_preview = false;
+ }
+ }
+}
+
+void VisualShaderEditor::_update_preview() {
+
+ if (!preview_showed) {
+ pending_update_preview = true;
+ return;
+ }
+
+ String code = visual_shader->get_code();
+
+ preview_text->set_text(code);
+
+ ShaderLanguage sl;
+
+ Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types());
+
+ for (int i = 0; i < preview_text->get_line_count(); i++) {
+ preview_text->set_line_as_marked(i, false);
+ }
+ if (err != OK) {
+ preview_text->set_line_as_marked(sl.get_error_line() - 1, true);
+ error_text->set_visible(true);
+
+ String text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
+ error_text->set_text(text);
+ shader_error = true;
+ } else {
+ error_text->set_visible(false);
+ shader_error = false;
+ }
+}
+
void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_rebuild", &VisualShaderEditor::_rebuild);
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
@@ -1853,6 +2122,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_line_edit_changed", &VisualShaderEditor::_line_edit_changed);
ClassDB::bind_method("_port_name_focus_out", &VisualShaderEditor::_port_name_focus_out);
ClassDB::bind_method("_duplicate_nodes", &VisualShaderEditor::_duplicate_nodes);
+ ClassDB::bind_method("_copy_nodes", &VisualShaderEditor::_copy_nodes);
+ ClassDB::bind_method("_paste_nodes", &VisualShaderEditor::_paste_nodes);
ClassDB::bind_method("_mode_selected", &VisualShaderEditor::_mode_selected);
ClassDB::bind_method("_input_select_item", &VisualShaderEditor::_input_select_item);
ClassDB::bind_method("_preview_select_port", &VisualShaderEditor::_preview_select_port);
@@ -1867,6 +2138,9 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_remove_output_port", &VisualShaderEditor::_remove_output_port);
ClassDB::bind_method("_node_resized", &VisualShaderEditor::_node_resized);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
+ ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
+ ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text);
+ ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -1893,13 +2167,25 @@ VisualShaderEditor::VisualShaderEditor() {
saved_node_pos = Point2(0, 0);
ShaderLanguage::get_keyword_list(&keyword_list);
+ preview_showed = false;
+ pending_update_preview = false;
+ shader_error = false;
+
to_node = -1;
to_slot = -1;
from_node = -1;
from_slot = -1;
+ main_box = memnew(HSplitContainer);
+ main_box->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(main_box);
+
graph = memnew(GraphEdit);
- add_child(graph);
+ graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
+ graph->set_v_size_flags(SIZE_EXPAND_FILL);
+ graph->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_box->add_child(graph);
graph->set_drag_forwarding(this);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
@@ -1912,6 +2198,8 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("node_selected", this, "_node_selected");
graph->connect("scroll_offset_changed", this, "_scroll_changed");
graph->connect("duplicate_nodes_request", this, "_duplicate_nodes");
+ graph->connect("copy_nodes_request", this, "_copy_nodes");
+ graph->connect("paste_nodes_request", this, "_paste_nodes");
graph->connect("delete_nodes_request", this, "_on_nodes_delete");
graph->connect("gui_input", this, "_graph_gui_input");
graph->connect("connection_to_empty", this, "_connection_to_empty");
@@ -1946,6 +2234,32 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->move_child(add_node, 0);
add_node->connect("pressed", this, "_show_members_dialog", varray(false));
+ preview_shader = memnew(ToolButton);
+ preview_shader->set_toggle_mode(true);
+ preview_shader->set_tooltip(TTR("Show resulted shader code."));
+ graph->get_zoom_hbox()->add_child(preview_shader);
+ preview_shader->connect("pressed", this, "_show_preview_text");
+
+ ///////////////////////////////////////
+ // PREVIEW PANEL
+ ///////////////////////////////////////
+
+ preview_vbox = memnew(VBoxContainer);
+ preview_vbox->set_visible(preview_showed);
+ main_box->add_child(preview_vbox);
+ preview_text = memnew(TextEdit);
+ preview_vbox->add_child(preview_text);
+ preview_text->set_h_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_v_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
+ preview_text->set_syntax_coloring(true);
+ preview_text->set_show_line_numbers(true);
+ preview_text->set_readonly(true);
+
+ error_text = memnew(Label);
+ preview_vbox->add_child(error_text);
+ error_text->set_visible(false);
+
///////////////////////////////////////
// SHADER NODES TREE
///////////////////////////////////////
@@ -2036,13 +2350,28 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), VisualShaderNodeColorOp::OP_SCREEN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), VisualShaderNodeColorOp::OP_SOFT_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR));
- 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));
+ add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
- // BOOLEAN
+ // CONDITIONAL
+ const String &compare_func_desc = TTR("Returns the boolean result of the %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));
+ 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));
+ add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SwitchS", "Conditional", "Functions", "VisualShaderNodeScalarSwitch", TTR("Returns an associated scalar if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+
+ add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
+
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));
@@ -2054,6 +2383,7 @@ VisualShaderEditor::VisualShaderEditor() {
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("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), "output_is_srgb", VisualShaderNode::PORT_TYPE_BOOLEAN, -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));
@@ -2084,6 +2414,7 @@ VisualShaderEditor::VisualShaderEditor() {
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("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), "front_facing", VisualShaderNode::PORT_TYPE_BOOLEAN, 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));
@@ -2176,16 +2507,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));
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));
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));
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));
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 +2533,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));
+ 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));
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));
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("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than '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));
+ add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
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));
@@ -2226,23 +2557,24 @@ VisualShaderEditor::VisualShaderEditor() {
// TEXTURES
- 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("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_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_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_ICON_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));
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));
+ add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
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 +2592,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));
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));
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));
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));
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));
@@ -2286,28 +2618,29 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_VECTOR));
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));
+ 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));
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));
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("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("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));
+ add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
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));
@@ -2322,16 +2655,17 @@ 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("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
- 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));
/////////////////////////////////////////////////////////////////////
@@ -2447,6 +2781,7 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
+ Ref<Resource> parent_resource;
public:
void _property_changed(const String &prop, const Variant &p_value, const String &p_field, bool p_changing = false) {
@@ -2460,7 +2795,27 @@ public:
undo_redo->create_action(TTR("Edit Visual Property") + ": " + prop, UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(node.ptr(), prop, p_value);
undo_redo->add_undo_property(node.ptr(), prop, node->get(prop));
+
+ if (p_value.get_type() == Variant::OBJECT) {
+
+ RES prev_res = node->get(prop);
+ RES curr_res = p_value;
+
+ if (curr_res.is_null()) {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ } else {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)curr_res.ptr());
+ }
+ if (!prev_res.is_null()) {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)prev_res.ptr());
+ } else {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ }
+ undo_redo->add_do_method(this, "_refresh_request");
+ undo_redo->add_undo_method(this, "_refresh_request");
+ }
undo_redo->commit_action();
+
updating = false;
}
@@ -2476,11 +2831,20 @@ public:
VisualShaderEditor::get_singleton()->call_deferred("_update_graph");
}
+ void _resource_selected(const String &p_path, RES p_resource) {
+ _open_inspector(p_resource);
+ }
+
+ void _open_inspector(RES p_resource) {
+ EditorNode::get_singleton()->get_inspector()->edit(p_resource.ptr());
+ }
+
bool updating;
Ref<VisualShaderNode> node;
Vector<EditorProperty *> properties;
- void setup(Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ parent_resource = p_parent_resource;
updating = false;
node = p_node;
properties = p_properties;
@@ -2489,6 +2853,11 @@ public:
add_child(p_properties[i]);
+ bool res_prop = Object::cast_to<EditorPropertyResource>(p_properties[i]);
+ if (res_prop) {
+ p_properties[i]->connect("resource_selected", this, "_resource_selected");
+ }
+
properties[i]->connect("property_changed", this, "_property_changed");
properties[i]->set_object_and_property(node.ptr(), p_names[i]);
properties[i]->update_property();
@@ -2502,10 +2871,12 @@ public:
ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed, DEFVAL(String()), DEFVAL(false));
ClassDB::bind_method("_node_changed", &VisualShaderNodePluginDefaultEditor::_node_changed);
ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request);
+ ClassDB::bind_method("_resource_selected", &VisualShaderNodePluginDefaultEditor::_resource_selected);
+ ClassDB::bind_method("_open_inspector", &VisualShaderNodePluginDefaultEditor::_open_inspector);
}
};
-Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (p_node->is_class("VisualShaderNodeInput")) {
//create input
@@ -2563,7 +2934,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode
properties.push_back(pinfo[i].name);
}
VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
- editor->setup(editors, properties, p_node);
+ editor->setup(p_parent_resource, editors, properties, p_node);
return editor;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 4274cc3d76..cd5efc366b 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -48,7 +48,7 @@ protected:
static void _bind_methods();
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class VisualShaderEditor : public VBoxContainer {
@@ -60,14 +60,22 @@ class VisualShaderEditor : public VBoxContainer {
int editing_port;
Ref<VisualShader> visual_shader;
+ HSplitContainer *main_box;
GraphEdit *graph;
ToolButton *add_node;
+ ToolButton *preview_shader;
OptionButton *edit_type;
PanelContainer *error_panel;
Label *error_label;
+ bool pending_update_preview;
+ bool shader_error;
+ VBoxContainer *preview_vbox;
+ TextEdit *preview_text;
+ Label *error_text;
+
UndoRedo *undo_redo;
Point2 saved_node_pos;
bool saved_node_pos_dirty;
@@ -75,6 +83,8 @@ class VisualShaderEditor : public VBoxContainer {
ConfirmationDialog *members_dialog;
MenuButton *tools;
+ bool preview_showed;
+
enum ToolsMenuOptions {
EXPAND_ALL,
COLLAPSE_ALL
@@ -103,8 +113,10 @@ class VisualShaderEditor : public VBoxContainer {
int return_type;
int func;
float value;
+ bool highend;
+ bool is_custom;
- 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 +127,11 @@ class VisualShaderEditor : public VBoxContainer {
mode = p_mode;
func = p_func;
value = p_value;
+ highend = p_highend;
+ is_custom = false;
}
- 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 +142,8 @@ class VisualShaderEditor : public VBoxContainer {
mode = p_mode;
func = p_func;
value = p_value;
+ highend = p_highend;
+ is_custom = false;
}
};
@@ -137,8 +153,13 @@ class VisualShaderEditor : public VBoxContainer {
void _draw_color_over_button(Object *obj, Color p_color);
void _add_node(int p_idx, int p_op_idx = -1);
+ void _update_custom_nodes();
void _update_options_menu();
+ void _show_preview_text();
+ void _update_preview();
+ String _get_description(int p_idx);
+
static VisualShaderEditor *singleton;
void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
@@ -173,8 +194,21 @@ class VisualShaderEditor : public VBoxContainer {
void _port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output);
+ void _dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded);
+ void _dup_update_excluded(int p_type, Set<int> &r_excluded);
+ void _dup_paste_nodes(int p_type, int p_pasted_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select);
+
void _duplicate_nodes();
+ Vector2 selection_center;
+ int copy_type; // shader type
+ List<int> copy_nodes_buffer;
+ Set<int> copy_nodes_excluded_buffer;
+
+ void _clear_buffer();
+ void _copy_nodes();
+ void _paste_nodes();
+
Vector<Ref<VisualShaderNodePlugin> > plugins;
void _mode_selected(int p_id);
@@ -224,8 +258,8 @@ public:
static VisualShaderEditor *get_singleton() { return singleton; }
- void add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script);
- void remove_custom_type(const Ref<Script> &p_script);
+ void clear_custom_types();
+ void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category);
virtual Size2 get_minimum_size() const;
void edit(VisualShader *p_visual_shader);
@@ -256,7 +290,7 @@ class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class EditorPropertyShaderMode : public EditorProperty {
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index c78a81dbe0..c54103f6f7 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -931,17 +931,8 @@ void ProjectExportDialog::_export_project() {
export_project->add_filter("*." + extension_list[i] + " ; " + platform->get_name() + " Export");
}
- String current_preset_export_path = current->get_export_path();
-
- if (current_preset_export_path != "") {
-
- if (!DirAccess::exists(current_preset_export_path.get_base_dir())) {
-
- DirAccessRef da(DirAccess::create(DirAccess::ACCESS_FILESYSTEM));
- da->make_dir_recursive(current_preset_export_path.get_base_dir());
- }
-
- export_project->set_current_path(current_preset_export_path);
+ if (current->get_export_path() != "") {
+ export_project->set_current_path(current->get_export_path());
} else {
if (extension_list.size() >= 1) {
export_project->set_current_file(default_filename + "." + extension_list[0]);
@@ -1125,6 +1116,7 @@ ProjectExportDialog::ProjectExportDialog() {
sections = memnew(TabContainer);
sections->set_tab_align(TabContainer::ALIGN_LEFT);
+ sections->set_use_hidden_tabs_for_min_size(true);
settings_vb->add_child(sections);
sections->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 4b3d468a61..e2527a4039 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -52,6 +52,10 @@
#include "scene/gui/texture_rect.h"
#include "scene/gui/tool_button.h"
+static inline String get_project_key_from_path(const String &dir) {
+ return dir.replace("/", "::");
+}
+
class ProjectDialog : public ConfirmationDialog {
GDCLASS(ProjectDialog, ConfirmationDialog);
@@ -191,7 +195,7 @@ private:
unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io);
if (!pkg) {
- set_message(TTR("Error opening package file, not in zip format."), MESSAGE_ERROR);
+ set_message(TTR("Error opening package file, not in ZIP format."), MESSAGE_ERROR);
memdelete(d);
get_ok()->set_disabled(true);
unzClose(pkg);
@@ -515,7 +519,7 @@ private:
unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
if (!pkg) {
- dialog_error->set_text(TTR("Error opening package file, not in zip format."));
+ dialog_error->set_text(TTR("Error opening package file, not in ZIP format."));
dialog_error->popup_centered_minsize();
return;
}
@@ -606,7 +610,7 @@ private:
dir = dir.replace("\\", "/");
if (dir.ends_with("/"))
dir = dir.substr(0, dir.length() - 1);
- String proj = dir.replace("/", "::");
+ String proj = get_project_key_from_path(dir);
EditorSettings::get_singleton()->set("projects/" + proj, dir);
EditorSettings::get_singleton()->save();
@@ -765,6 +769,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();
@@ -917,596 +922,1053 @@ public:
}
};
-struct ProjectItem {
- String project;
- String project_name;
- String path;
- String conf;
- String icon;
- String main_scene;
- uint64_t last_modified;
- bool favorite;
- bool grayed;
- ProjectListFilter::FilterOption filter_order_option;
- ProjectItem() {}
- ProjectItem(const String &p_project, const String &p_name, const String &p_path, const String &p_conf, const String &p_icon, const String &p_main_scene, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const ProjectListFilter::FilterOption p_filter_order_option = ProjectListFilter::FILTER_NAME) {
- project = p_project;
- project_name = p_name;
- path = p_path;
- conf = p_conf;
- icon = p_icon;
- main_scene = p_main_scene;
- last_modified = p_last_modified;
- favorite = p_favorite;
- grayed = p_grayed;
- filter_order_option = p_filter_order_option;
- }
- _FORCE_INLINE_ bool operator<(const ProjectItem &l) const {
- switch (filter_order_option) {
+class ProjectListItemControl : public HBoxContainer {
+ GDCLASS(ProjectListItemControl, HBoxContainer)
+public:
+ TextureButton *favorite_button;
+ TextureRect *icon;
+ bool icon_needs_reload;
+ bool hover;
+
+ ProjectListItemControl() {
+ favorite_button = NULL;
+ icon = NULL;
+ icon_needs_reload = true;
+ hover = false;
+ }
+
+ void set_is_favorite(bool fav) {
+ favorite_button->set_modulate(fav ? Color(1, 1, 1, 1) : Color(1, 1, 1, 0.2));
+ }
+
+ void _notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_MOUSE_ENTER: {
+ hover = true;
+ update();
+ } break;
+ case NOTIFICATION_MOUSE_EXIT: {
+ hover = false;
+ update();
+ } break;
+ case NOTIFICATION_DRAW: {
+ if (hover) {
+ draw_style_box(get_stylebox("hover", "Tree"), Rect2(Point2(), get_size() - Size2(10, 0) * EDSCALE));
+ }
+ } break;
+ }
+ }
+};
+
+class ProjectList : public ScrollContainer {
+ GDCLASS(ProjectList, ScrollContainer)
+public:
+ static const char *SIGNAL_SELECTION_CHANGED;
+ static const char *SIGNAL_PROJECT_ASK_OPEN;
+
+ enum MenuOptions {
+ GLOBAL_NEW_WINDOW,
+ GLOBAL_OPEN_PROJECT
+ };
+
+ // Can often be passed by copy
+ struct Item {
+ String project_key;
+ String project_name;
+ String description;
+ String path;
+ String icon;
+ String main_scene;
+ uint64_t last_modified;
+ bool favorite;
+ bool grayed;
+ bool missing;
+ int version;
+
+ ProjectListItemControl *control;
+
+ Item() {}
+
+ Item(const String &p_project,
+ const String &p_name,
+ const String &p_description,
+ const String &p_path,
+ const String &p_icon,
+ const String &p_main_scene,
+ uint64_t p_last_modified,
+ bool p_favorite,
+ bool p_grayed,
+ bool p_missing,
+ int p_version) {
+
+ project_key = p_project;
+ project_name = p_name;
+ description = p_description;
+ path = p_path;
+ icon = p_icon;
+ main_scene = p_main_scene;
+ last_modified = p_last_modified;
+ favorite = p_favorite;
+ grayed = p_grayed;
+ missing = p_missing;
+ version = p_version;
+ control = NULL;
+ }
+
+ _FORCE_INLINE_ bool operator==(const Item &l) const {
+ return project_key == l.project_key;
+ }
+ };
+
+ ProjectList();
+ ~ProjectList();
+
+ void load_projects();
+ void set_search_term(String p_search_term);
+ void set_order_option(ProjectListFilter::FilterOption p_option);
+ void sort_projects();
+ int get_project_count() const;
+ void select_project(int p_index);
+ void erase_selected_projects();
+ Vector<Item> get_selected_projects() const;
+ const Set<String> &get_selected_project_keys() const;
+ void ensure_project_visible(int p_index);
+ int get_single_selected_index() const;
+ bool is_any_project_missing() const;
+ void erase_missing_projects();
+ int refresh_project(const String &dir_path);
+
+private:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+ void _panel_draw(Node *p_hb);
+ void _panel_input(const Ref<InputEvent> &p_ev, Node *p_hb);
+ void _favorite_pressed(Node *p_hb);
+ void _show_project(const String &p_path);
+
+ void select_range(int p_begin, int p_end);
+ void toggle_select(int p_index);
+ void create_project_item_control(int p_index);
+ void remove_project(int p_index, bool p_update_settings);
+ void update_icons_async();
+ void load_project_icon(int p_index);
+
+ static void load_project_data(const String &p_property_key, Item &p_item, bool p_favorite);
+
+ String _search_term;
+ ProjectListFilter::FilterOption _order_option;
+ Set<String> _selected_project_keys;
+ String _last_clicked; // Project key
+ VBoxContainer *_scroll_children;
+ int _icon_load_index;
+
+ Vector<Item> _projects;
+};
+
+struct ProjectListComparator {
+ ProjectListFilter::FilterOption order_option;
+
+ // operator<
+ _FORCE_INLINE_ bool operator()(const ProjectList::Item &a, const ProjectList::Item &b) const {
+ if (a.favorite && !b.favorite) {
+ return true;
+ }
+ if (b.favorite && !a.favorite) {
+ return false;
+ }
+ switch (order_option) {
case ProjectListFilter::FILTER_PATH:
- return project < l.project;
+ return a.project_key < b.project_key;
case ProjectListFilter::FILTER_MODIFIED:
- return last_modified > l.last_modified;
+ return a.last_modified > b.last_modified;
default:
- return project_name < l.project_name;
+ return a.project_name < b.project_name;
}
}
- _FORCE_INLINE_ bool operator==(const ProjectItem &l) const { return project == l.project; }
};
-void ProjectManager::_notification(int p_what) {
+ProjectList::ProjectList() {
+ _order_option = ProjectListFilter::FILTER_MODIFIED;
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
+ _scroll_children = memnew(VBoxContainer);
+ _scroll_children->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(_scroll_children);
- Engine::get_singleton()->set_editor_hint(false);
- } break;
- case NOTIFICATION_READY: {
+ _icon_load_index = 0;
+}
- if (scroll_children->get_child_count() == 0 && StreamPeerSSL::is_available())
- open_templates->popup_centered_minsize();
- } break;
- case NOTIFICATION_VISIBILITY_CHANGED: {
+ProjectList::~ProjectList() {
+}
- set_process_unhandled_input(is_visible_in_tree());
- } break;
- case NOTIFICATION_WM_QUIT_REQUEST: {
+void ProjectList::update_icons_async() {
+ _icon_load_index = 0;
+ set_process(true);
+}
- _dim_window();
- } break;
+void ProjectList::_notification(int p_what) {
+ if (p_what == NOTIFICATION_PROCESS) {
+
+ // Load icons as a coroutine to speed up launch when you have hundreds of projects
+ if (_icon_load_index < _projects.size()) {
+ Item &item = _projects.write[_icon_load_index];
+ if (item.control->icon_needs_reload) {
+ load_project_icon(_icon_load_index);
+ }
+ _icon_load_index++;
+
+ } else {
+ set_process(false);
+ }
}
}
-void ProjectManager::_dim_window() {
-
- // This method must be called before calling `get_tree()->quit()`.
- // Otherwise, its effect won't be visible
+void ProjectList::load_project_icon(int p_index) {
+ Item &item = _projects.write[p_index];
+
+ Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons");
+ Ref<Texture> icon;
+ if (item.icon != "") {
+ Ref<Image> img;
+ img.instance();
+ Error err = img->load(item.icon.replace_first("res://", item.path + "/"));
+ if (err == OK) {
+
+ img->resize(default_icon->get_width(), default_icon->get_height(), Image::INTERPOLATE_LANCZOS);
+ Ref<ImageTexture> it = memnew(ImageTexture);
+ it->create_from_image(img);
+ icon = it;
+ }
+ }
+ if (icon.is_null()) {
+ icon = default_icon;
+ }
- // Dim the project manager 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);
+ item.control->icon->set_texture(icon);
+ item.control->icon_needs_reload = false;
}
-void ProjectManager::_panel_draw(Node *p_hb) {
+void ProjectList::load_project_data(const String &p_property_key, Item &p_item, bool p_favorite) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(p_hb);
+ String path = EditorSettings::get_singleton()->get(p_property_key);
+ String conf = path.plus_file("project.godot");
+ bool grayed = false;
+ bool missing = false;
- hb->draw_line(Point2(0, hb->get_size().y + 1), Point2(hb->get_size().x - 10, hb->get_size().y + 1), get_color("guide_color", "Tree"));
+ Ref<ConfigFile> cf = memnew(ConfigFile);
+ Error cf_err = cf->load(conf);
+
+ int config_version = 0;
+ String project_name = TTR("Unnamed Project");
+ if (cf_err == OK) {
+ String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", ""));
+ if (cf_project_name != "")
+ project_name = cf_project_name.xml_unescape();
+ config_version = (int)cf->get_value("", "config_version", 0);
+ }
+
+ if (config_version > ProjectSettings::CONFIG_VERSION) {
+ // Comes from an incompatible (more recent) Godot version, grey it out
+ grayed = true;
+ }
- if (selected_list.has(hb->get_meta("name"))) {
- hb->draw_style_box(gui_base->get_stylebox("selected", "Tree"), Rect2(Point2(), hb->get_size() - Size2(10, 0) * EDSCALE));
+ String description = cf->get_value("application", "config/description", "");
+ String icon = cf->get_value("application", "config/icon", "");
+ String main_scene = cf->get_value("application", "run/main_scene", "");
+
+ uint64_t last_modified = 0;
+ if (FileAccess::exists(conf)) {
+ last_modified = FileAccess::get_modified_time(conf);
+
+ String fscache = path.plus_file(".fscache");
+ if (FileAccess::exists(fscache)) {
+ uint64_t cache_modified = FileAccess::get_modified_time(fscache);
+ if (cache_modified > last_modified)
+ last_modified = cache_modified;
+ }
+ } else {
+ grayed = true;
+ missing = true;
+ print_line("Project is missing: " + conf);
}
+
+ String project_key = p_property_key.get_slice("/", 1);
+
+ p_item = Item(project_key, project_name, description, path, icon, main_scene, last_modified, p_favorite, grayed, missing, config_version);
}
-void ProjectManager::_update_project_buttons() {
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
+void ProjectList::load_projects() {
+ // This is a full, hard reload of the list. Don't call this unless really required, it's expensive.
+ // If you have 150 projects, it may read through 150 files on your disk at once + load 150 icons.
- CanvasItem *item = Object::cast_to<CanvasItem>(scroll_children->get_child(i));
- item->update();
+ // Clear whole list
+ for (int i = 0; i < _projects.size(); ++i) {
+ Item &project = _projects.write[i];
+ CRASH_COND(project.control == NULL);
+ memdelete(project.control); // Why not queue_free()?
}
+ _projects.clear();
+ _last_clicked = "";
+ _selected_project_keys.clear();
+ OS::get_singleton()->global_menu_clear("_dock");
- bool empty_selection = selected_list.empty();
- erase_btn->set_disabled(empty_selection);
- open_btn->set_disabled(empty_selection);
- rename_btn->set_disabled(empty_selection);
- run_btn->set_disabled(empty_selection);
-
- bool missing_projects = false;
- Map<String, String> list_all_projects;
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (hb) {
- list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
+ // Load data
+ // TODO Would be nice to change how projects and favourites are stored... it complicates things a bit.
+ // Use a dictionary associating project path to metadata (like is_favorite).
+
+ List<PropertyInfo> properties;
+ EditorSettings::get_singleton()->get_property_list(&properties);
+
+ Set<String> favorites;
+ // Find favourites...
+ for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ String property_key = E->get().name;
+ if (property_key.begins_with("favorite_projects/")) {
+ favorites.insert(property_key);
}
}
- for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) {
- String project_name = E->key().replace(":::", ":/").replace("::", "/") + "/project.godot";
- if (!FileAccess::exists(project_name)) {
- missing_projects = true;
- break;
- }
+
+ for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ // This is actually something like "projects/C:::Documents::Godot::Projects::MyGame"
+ String property_key = E->get().name;
+ if (!property_key.begins_with("projects/"))
+ continue;
+
+ String project_key = property_key.get_slice("/", 1);
+ bool favorite = favorites.has("favorite_projects/" + project_key);
+
+ Item item;
+ load_project_data(property_key, item, favorite);
+
+ _projects.push_back(item);
+ }
+
+ // Create controls
+ for (int i = 0; i < _projects.size(); ++i) {
+ create_project_item_control(i);
}
- erase_missing_btn->set_visible(missing_projects);
+ OS::get_singleton()->global_menu_add_separator("_dock");
+ OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+
+ sort_projects();
+
+ set_v_scroll(0);
+
+ update_icons_async();
}
-void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
+void ProjectList::create_project_item_control(int p_index) {
- Ref<InputEventMouseButton> mb = p_ev;
+ // Will be added last in the list, so make sure indexes match
+ ERR_FAIL_COND(p_index != _scroll_children->get_child_count());
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ Item &item = _projects.write[p_index];
+ ERR_FAIL_COND(item.control != NULL); // Already created
+
+ Ref<Texture> favorite_icon = get_icon("Favorites", "EditorIcons");
+ Color font_color = get_color("font_color", "Tree");
+
+ ProjectListItemControl *hb = memnew(ProjectListItemControl);
+ hb->connect("draw", this, "_panel_draw", varray(hb));
+ hb->connect("gui_input", this, "_panel_input", varray(hb));
+ hb->add_constant_override("separation", 10 * EDSCALE);
+ hb->set_tooltip(item.description);
+
+ VBoxContainer *favorite_box = memnew(VBoxContainer);
+ favorite_box->set_name("FavoriteBox");
+ TextureButton *favorite = memnew(TextureButton);
+ favorite->set_name("FavoriteButton");
+ favorite->set_normal_texture(favorite_icon);
+ // This makes the project's "hover" style display correctly when hovering the favorite icon
+ favorite->set_mouse_filter(MOUSE_FILTER_PASS);
+ favorite->connect("pressed", this, "_favorite_pressed", varray(hb));
+ favorite_box->add_child(favorite);
+ favorite_box->set_alignment(BoxContainer::ALIGN_CENTER);
+ hb->add_child(favorite_box);
+ hb->favorite_button = favorite;
+ hb->set_is_favorite(item.favorite);
+
+ TextureRect *tf = memnew(TextureRect);
+ tf->set_texture(get_icon("DefaultProjectIcon", "EditorIcons"));
+ if (item.missing) {
+ tf->set_modulate(Color(1, 1, 1, 0.5));
+ }
+ hb->add_child(tf);
+ hb->icon = tf;
- String clicked = p_hb->get_meta("name");
- String clicked_main_scene = p_hb->get_meta("main_scene");
+ VBoxContainer *vb = memnew(VBoxContainer);
+ if (item.grayed)
+ vb->set_modulate(Color(1, 1, 1, 0.5));
+ vb->set_h_size_flags(SIZE_EXPAND_FILL);
+ hb->add_child(vb);
+ Control *ec = memnew(Control);
+ ec->set_custom_minimum_size(Size2(0, 1));
+ ec->set_mouse_filter(MOUSE_FILTER_PASS);
+ vb->add_child(ec);
+ Label *title = memnew(Label(!item.missing ? item.project_name : TTR("Missing Project")));
+ title->add_font_override("font", get_font("title", "EditorFonts"));
+ title->add_color_override("font_color", font_color);
+ title->set_clip_text(true);
+ vb->add_child(title);
+
+ HBoxContainer *path_hb = memnew(HBoxContainer);
+ path_hb->set_h_size_flags(SIZE_EXPAND_FILL);
+ vb->add_child(path_hb);
+
+ Button *show = memnew(Button);
+ // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't
+ show->set_icon(get_icon(!item.missing ? "Load" : "FileBroken", "EditorIcons"));
+ show->set_flat(true);
+ if (!item.grayed) {
+ // Don't make the icon less prominent if the parent is already grayed out
+ show->set_modulate(Color(1, 1, 1, 0.5));
+ }
+ path_hb->add_child(show);
- if (mb->get_shift() && selected_list.size() > 0 && last_clicked != "" && clicked != last_clicked) {
+ if (!item.missing) {
+ show->connect("pressed", this, "_show_project", varray(item.path));
+ show->set_tooltip(TTR("Show in File Manager"));
+ } else {
+ show->set_tooltip(TTR("Error: Project is missing on the filesystem."));
+ }
- int clicked_id = -1;
- int last_clicked_id = -1;
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (!hb) continue;
- if (hb->get_meta("name") == clicked) clicked_id = i;
- if (hb->get_meta("name") == last_clicked) last_clicked_id = i;
- }
+ Label *fpath = memnew(Label(item.path));
+ path_hb->add_child(fpath);
+ fpath->set_h_size_flags(SIZE_EXPAND_FILL);
+ fpath->set_modulate(Color(1, 1, 1, 0.5));
+ fpath->add_color_override("font_color", font_color);
+ fpath->set_clip_text(true);
- if (last_clicked_id != -1 && clicked_id != -1) {
- int min = clicked_id < last_clicked_id ? clicked_id : last_clicked_id;
- int max = clicked_id > last_clicked_id ? clicked_id : last_clicked_id;
- for (int i = 0; i < scroll_children->get_child_count(); ++i) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (!hb) continue;
- if (i != clicked_id && (i < min || i > max) && !mb->get_control()) {
- selected_list.erase(hb->get_meta("name"));
- } else if (i >= min && i <= max) {
- selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
- }
- }
- }
+ _scroll_children->add_child(hb);
+ OS::get_singleton()->global_menu_add_item("_dock", item.project_name + " ( " + item.path + " )", GLOBAL_OPEN_PROJECT, Variant(item.path.plus_file("project.godot")));
+ item.control = hb;
+}
- } else if (selected_list.has(clicked) && mb->get_control()) {
+void ProjectList::set_search_term(String p_search_term) {
+ _search_term = p_search_term;
+}
- selected_list.erase(clicked);
+void ProjectList::set_order_option(ProjectListFilter::FilterOption p_option) {
+ if (_order_option != p_option) {
+ _order_option = p_option;
+ EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)_order_option);
+ EditorSettings::get_singleton()->save();
+ }
+}
- } else {
+void ProjectList::sort_projects() {
- last_clicked = clicked;
- if (mb->get_control() || selected_list.size() == 0) {
- selected_list.insert(clicked, clicked_main_scene);
+ SortArray<Item, ProjectListComparator> sorter;
+ sorter.compare.order_option = _order_option;
+ sorter.sort(_projects.ptrw(), _projects.size());
+
+ for (int i = 0; i < _projects.size(); ++i) {
+ Item &item = _projects.write[i];
+
+ bool visible = true;
+ if (_search_term != "") {
+
+ String search_path;
+ if (_search_term.find("/") != -1) {
+ // Search path will match the whole path
+ search_path = item.path;
} else {
- selected_list.clear();
- selected_list.insert(clicked, clicked_main_scene);
+ // Search path will only match the last path component to make searching more strict
+ search_path = item.path.get_file();
}
+
+ // When searching, display projects whose name or path contain the search term
+ visible = item.project_name.findn(_search_term) != -1 || search_path.findn(_search_term) != -1;
}
- _update_project_buttons();
+ item.control->set_visible(visible);
+ }
- if (mb->is_doubleclick())
- _open_selected_projects_ask(); //open if doubleclicked
+ for (int i = 0; i < _projects.size(); ++i) {
+ Item &item = _projects.write[i];
+ if (item.control->is_visible()) {
+ item.control->get_parent()->move_child(item.control, i);
+ }
}
+
+ // Rewind the coroutine because order of projects changed
+ update_icons_async();
}
-void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
+const Set<String> &ProjectList::get_selected_project_keys() const {
+ // Faster if that's all you need
+ return _selected_project_keys;
+}
- Ref<InputEventKey> k = p_ev;
+Vector<ProjectList::Item> ProjectList::get_selected_projects() const {
+ Vector<Item> items;
+ if (_selected_project_keys.size() == 0) {
+ return items;
+ }
+ items.resize(_selected_project_keys.size());
+ int j = 0;
+ for (int i = 0; i < _projects.size(); ++i) {
+ const Item &item = _projects[i];
+ if (_selected_project_keys.has(item.project_key)) {
+ items.write[j++] = item;
+ }
+ }
+ ERR_FAIL_COND_V(j != items.size(), items);
+ return items;
+}
- if (k.is_valid()) {
+void ProjectList::ensure_project_visible(int p_index) {
+ const Item &item = _projects[p_index];
- if (!k->is_pressed())
- return;
+ int item_top = item.control->get_position().y;
+ int item_bottom = item.control->get_position().y + item.control->get_size().y;
- if (tabs->get_current_tab() != 0)
- return;
+ if (item_top < get_v_scroll()) {
+ set_v_scroll(item_top);
- bool scancode_handled = true;
+ } else if (item_bottom > get_v_scroll() + get_size().y) {
+ set_v_scroll(item_bottom - get_size().y);
+ }
+}
- switch (k->get_scancode()) {
+int ProjectList::get_single_selected_index() const {
+ if (_selected_project_keys.size() == 0) {
+ // Default selection
+ return 0;
+ }
+ String key;
+ if (_selected_project_keys.size() == 1) {
+ // Only one selected
+ key = _selected_project_keys.front()->get();
+ } else {
+ // Multiple selected, consider the last clicked one as "main"
+ key = _last_clicked;
+ }
+ for (int i = 0; i < _projects.size(); ++i) {
+ if (_projects[i].project_key == key) {
+ return i;
+ }
+ }
+ return 0;
+}
- case KEY_ENTER: {
+void ProjectList::remove_project(int p_index, bool p_update_settings) {
+ const Item item = _projects[p_index]; // Take a copy
- _open_selected_projects_ask();
- } break;
- case KEY_DELETE: {
+ _selected_project_keys.erase(item.project_key);
- _erase_project();
- } break;
- case KEY_HOME: {
+ if (_last_clicked == item.project_key) {
+ _last_clicked = "";
+ }
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
+ memdelete(item.control);
+ _projects.remove(p_index);
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (hb) {
- selected_list.clear();
- selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
- scroll->set_v_scroll(0);
- _update_project_buttons();
- break;
- }
- }
+ if (p_update_settings) {
+ EditorSettings::get_singleton()->erase("projects/" + item.project_key);
+ EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key);
+ // Not actually saving the file, in case you are doing more changes to settings
+ }
+}
- } break;
- case KEY_END: {
+bool ProjectList::is_any_project_missing() const {
+ for (int i = 0; i < _projects.size(); ++i) {
+ if (_projects[i].missing) {
+ return true;
+ }
+ }
+ return false;
+}
- for (int i = scroll_children->get_child_count() - 1; i >= 0; i--) {
+void ProjectList::erase_missing_projects() {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (hb) {
- selected_list.clear();
- selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
- scroll->set_v_scroll(scroll_children->get_size().y);
- _update_project_buttons();
- break;
- }
- }
+ if (_projects.empty()) {
+ return;
+ }
- } break;
- case KEY_UP: {
+ int deleted_count = 0;
+ int remaining_count = 0;
- if (k->get_shift())
- break;
+ for (int i = 0; i < _projects.size(); ++i) {
+ const Item &item = _projects[i];
- if (selected_list.size()) {
+ if (item.missing) {
+ remove_project(i, true);
+ --i;
+ ++deleted_count;
- bool found = false;
+ } else {
+ ++remaining_count;
+ }
+ }
- for (int i = scroll_children->get_child_count() - 1; i >= 0; i--) {
+ print_line("Removed " + itos(deleted_count) + " projects from the list, remaining " + itos(remaining_count) + " projects");
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (!hb) continue;
+ EditorSettings::get_singleton()->save();
+}
- String current = hb->get_meta("name");
+int ProjectList::refresh_project(const String &dir_path) {
+ // Reads editor settings and reloads information about a specific project.
+ // If it wasn't loaded and should be in the list, it is added (i.e new project).
+ // If it isn't in the list anymore, it is removed.
+ // If it is in the list but doesn't exist anymore, it is marked as missing.
+
+ String project_key = get_project_key_from_path(dir_path);
+
+ // Read project manager settings
+ bool is_favourite = false;
+ bool should_be_in_list = false;
+ String property_key = "projects/" + project_key;
+ {
+ List<PropertyInfo> properties;
+ EditorSettings::get_singleton()->get_property_list(&properties);
+ String favorite_property_key = "favorite_projects/" + project_key;
+
+ bool found = false;
+ for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ String prop = E->get().name;
+ if (!found && prop == property_key) {
+ found = true;
+ } else if (!is_favourite && prop == favorite_property_key) {
+ is_favourite = true;
+ }
+ }
- if (found) {
- selected_list.clear();
- selected_list.insert(current, hb->get_meta("main_scene"));
+ should_be_in_list = found;
+ }
- int offset_diff = scroll->get_v_scroll() - hb->get_position().y;
+ bool was_selected = _selected_project_keys.has(project_key);
- if (offset_diff > 0)
- scroll->set_v_scroll(scroll->get_v_scroll() - offset_diff);
+ // Remove item in any case
+ for (int i = 0; i < _projects.size(); ++i) {
+ const Item &existing_item = _projects[i];
+ if (existing_item.path == dir_path) {
+ remove_project(i, false);
+ break;
+ }
+ }
- _update_project_buttons();
+ int index = -1;
+ if (should_be_in_list) {
+ // Recreate it with updated info
- break;
+ Item item;
+ load_project_data(property_key, item, is_favourite);
- } else if (current == selected_list.back()->key()) {
+ _projects.push_back(item);
+ create_project_item_control(_projects.size() - 1);
- found = true;
- }
- }
+ sort_projects();
- break;
+ for (int i = 0; i < _projects.size(); ++i) {
+ if (_projects[i].project_key == project_key) {
+ if (was_selected) {
+ select_project(i);
+ ensure_project_visible(i);
}
- FALLTHROUGH;
+ load_project_icon(i);
+ index = i;
+ break;
}
- case KEY_DOWN: {
+ }
+ }
- if (k->get_shift())
- break;
+ return index;
+}
- bool found = selected_list.empty();
+int ProjectList::get_project_count() const {
+ return _projects.size();
+}
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
+void ProjectList::select_project(int p_index) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (!hb) continue;
+ Vector<Item> previous_selected_items = get_selected_projects();
+ _selected_project_keys.clear();
- String current = hb->get_meta("name");
+ for (int i = 0; i < previous_selected_items.size(); ++i) {
+ previous_selected_items[i].control->update();
+ }
- if (found) {
- selected_list.clear();
- selected_list.insert(current, hb->get_meta("main_scene"));
+ toggle_select(p_index);
+}
- int last_y_visible = scroll->get_v_scroll() + scroll->get_size().y;
- int offset_diff = (hb->get_position().y + hb->get_size().y) - last_y_visible;
+inline void sort(int &a, int &b) {
+ if (a > b) {
+ int temp = a;
+ a = b;
+ b = temp;
+ }
+}
- if (offset_diff > 0)
- scroll->set_v_scroll(scroll->get_v_scroll() + offset_diff);
+void ProjectList::select_range(int p_begin, int p_end) {
+ sort(p_begin, p_end);
+ select_project(p_begin);
+ for (int i = p_begin + 1; i <= p_end; ++i) {
+ toggle_select(i);
+ }
+}
- _update_project_buttons();
+void ProjectList::toggle_select(int p_index) {
+ Item &item = _projects.write[p_index];
+ if (_selected_project_keys.has(item.project_key)) {
+ _selected_project_keys.erase(item.project_key);
+ } else {
+ _selected_project_keys.insert(item.project_key);
+ }
+ item.control->update();
+}
- break;
+void ProjectList::erase_selected_projects() {
- } else if (current == selected_list.back()->key()) {
+ if (_selected_project_keys.size() == 0) {
+ return;
+ }
- found = true;
- }
+ for (int i = 0; i < _projects.size(); ++i) {
+ Item &item = _projects.write[i];
+ if (_selected_project_keys.has(item.project_key) && item.control->is_visible()) {
+
+ EditorSettings::get_singleton()->erase("projects/" + item.project_key);
+ EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key);
+
+ memdelete(item.control);
+ _projects.remove(i);
+ --i;
+ }
+ }
+
+ EditorSettings::get_singleton()->save();
+
+ _selected_project_keys.clear();
+ _last_clicked = "";
+}
+
+// Draws selected project highlight
+void ProjectList::_panel_draw(Node *p_hb) {
+ Control *hb = Object::cast_to<Control>(p_hb);
+
+ hb->draw_line(Point2(0, hb->get_size().y + 1), Point2(hb->get_size().x - 10, hb->get_size().y + 1), get_color("guide_color", "Tree"));
+
+ String key = _projects[p_hb->get_index()].project_key;
+
+ if (_selected_project_keys.has(key)) {
+ hb->draw_style_box(get_stylebox("selected", "Tree"), Rect2(Point2(), hb->get_size() - Size2(10, 0) * EDSCALE));
+ }
+}
+
+// Input for each item in the list
+void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
+
+ Ref<InputEventMouseButton> mb = p_ev;
+ int clicked_index = p_hb->get_index();
+ const Item &clicked_project = _projects[clicked_index];
+
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+
+ if (mb->get_shift() && _selected_project_keys.size() > 0 && _last_clicked != "" && clicked_project.project_key != _last_clicked) {
+
+ int anchor_index = -1;
+ for (int i = 0; i < _projects.size(); ++i) {
+ const Item &p = _projects[i];
+ if (p.project_key == _last_clicked) {
+ anchor_index = p.control->get_index();
+ break;
}
+ }
+ CRASH_COND(anchor_index == -1);
+ select_range(anchor_index, clicked_index);
- } break;
- case KEY_F: {
- if (k->get_command())
- this->project_filter->search_box->grab_focus();
- else
- scancode_handled = false;
- } break;
- default: {
- scancode_handled = false;
- } break;
+ } else if (mb->get_control()) {
+ toggle_select(clicked_index);
+
+ } else {
+ _last_clicked = clicked_project.project_key;
+ select_project(clicked_index);
}
- if (scancode_handled) {
- accept_event();
+ emit_signal(SIGNAL_SELECTION_CHANGED);
+
+ if (mb->is_doubleclick()) {
+ emit_signal(SIGNAL_PROJECT_ASK_OPEN);
}
}
}
-void ProjectManager::_favorite_pressed(Node *p_hb) {
+void ProjectList::_favorite_pressed(Node *p_hb) {
- String clicked = p_hb->get_meta("name");
- bool favorite = !p_hb->get_meta("favorite");
- String proj = clicked.replace(":::", ":/");
- proj = proj.replace("::", "/");
+ ProjectListItemControl *control = Object::cast_to<ProjectListItemControl>(p_hb);
- if (favorite) {
- EditorSettings::get_singleton()->set("favorite_projects/" + clicked, proj);
+ int index = control->get_index();
+ Item item = _projects.write[index]; // Take copy
+
+ item.favorite = !item.favorite;
+
+ if (item.favorite) {
+ EditorSettings::get_singleton()->set("favorite_projects/" + item.project_key, item.path);
} else {
- EditorSettings::get_singleton()->erase("favorite_projects/" + clicked);
+ EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key);
}
EditorSettings::get_singleton()->save();
- call_deferred("_load_recent_projects");
+
+ _projects.write[index] = item;
+
+ control->set_is_favorite(item.favorite);
+
+ sort_projects();
+
+ if (item.favorite) {
+ for (int i = 0; i < _projects.size(); ++i) {
+ if (_projects[i].project_key == item.project_key) {
+ ensure_project_visible(i);
+ break;
+ }
+ }
+ }
}
-void ProjectManager::_load_recent_projects() {
+void ProjectList::_show_project(const String &p_path) {
+
+ OS::get_singleton()->shell_open(String("file://") + p_path);
+}
+
+const char *ProjectList::SIGNAL_SELECTION_CHANGED = "selection_changed";
+const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
+
+void ProjectList::_bind_methods() {
+
+ ClassDB::bind_method("_panel_draw", &ProjectList::_panel_draw);
+ ClassDB::bind_method("_panel_input", &ProjectList::_panel_input);
+ ClassDB::bind_method("_favorite_pressed", &ProjectList::_favorite_pressed);
+ ClassDB::bind_method("_show_project", &ProjectList::_show_project);
+
+ ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED));
+ ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN));
+}
+
+void ProjectManager::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+
+ Engine::get_singleton()->set_editor_hint(false);
+ } break;
+ case NOTIFICATION_READY: {
- ProjectListFilter::FilterOption filter_option = project_filter->get_filter_option();
- String search_term = project_filter->get_search_term();
+ if (_project_list->get_project_count() == 0 && StreamPeerSSL::is_available())
+ open_templates->popup_centered_minsize();
- while (scroll_children->get_child_count() > 0) {
- memdelete(scroll_children->get_child(0));
+ if (_project_list->get_project_count() >= 1) {
+ // Focus on the search box immediately to allow the user
+ // to search without having to reach for their mouse
+ project_filter->search_box->grab_focus();
+ }
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+
+ set_process_unhandled_input(is_visible_in_tree());
+ } break;
+ case NOTIFICATION_WM_QUIT_REQUEST: {
+
+ _dim_window();
+ } break;
}
+}
- Map<String, String> selected_list_copy = selected_list;
+void ProjectManager::_dim_window() {
- List<PropertyInfo> properties;
- EditorSettings::get_singleton()->get_property_list(&properties);
+ // This method must be called before calling `get_tree()->quit()`.
+ // Otherwise, its effect won't be visible
- Color font_color = gui_base->get_color("font_color", "Tree");
+ // Dim the project manager 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 = 0.5f;
+ Color dim_color = Color(c, c, c);
+ gui_base->set_modulate(dim_color);
+}
- ProjectListFilter::FilterOption filter_order_option = project_order_filter->get_filter_option();
- EditorSettings::get_singleton()->set("project_manager/sorting_order", (int)filter_order_option);
+void ProjectManager::_update_project_buttons() {
- List<ProjectItem> projects;
- List<ProjectItem> favorite_projects;
+ Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
+ bool empty_selection = selected_projects.empty();
- for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ bool is_missing_project_selected = false;
+ for (int i = 0; i < selected_projects.size(); ++i) {
+ if (selected_projects[i].missing) {
+ is_missing_project_selected = true;
+ break;
+ }
+ }
- String _name = E->get().name;
- if (!_name.begins_with("projects/") && !_name.begins_with("favorite_projects/"))
- continue;
+ erase_btn->set_disabled(empty_selection);
+ open_btn->set_disabled(empty_selection || is_missing_project_selected);
+ rename_btn->set_disabled(empty_selection || is_missing_project_selected);
+ run_btn->set_disabled(empty_selection || is_missing_project_selected);
- String path = EditorSettings::get_singleton()->get(_name);
- if (filter_option == ProjectListFilter::FILTER_PATH && search_term != "" && path.findn(search_term) == -1)
- continue;
+ erase_missing_btn->set_visible(_project_list->is_any_project_missing());
+}
- String project = _name.get_slice("/", 1);
- String conf = path.plus_file("project.godot");
- bool favorite = (_name.begins_with("favorite_projects/")) ? true : false;
- bool grayed = false;
+void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
- Ref<ConfigFile> cf = memnew(ConfigFile);
- Error cf_err = cf->load(conf);
+ Ref<InputEventKey> k = p_ev;
- int config_version = 0;
- String project_name = TTR("Unnamed Project");
- if (cf_err == OK) {
+ if (k.is_valid()) {
- String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", ""));
- if (cf_project_name != "")
- project_name = cf_project_name.xml_unescape();
- config_version = (int)cf->get_value("", "config_version", 0);
+ if (!k->is_pressed()) {
+ return;
}
- if (config_version > ProjectSettings::CONFIG_VERSION) {
- // Comes from an incompatible (more recent) Godot version, grey it out
- grayed = true;
+ // Pressing Command + Q quits the Project Manager
+ // This is handled by the platform implementation on macOS,
+ // so only define the shortcut on other platforms
+#ifndef OSX_ENABLED
+ if (k->get_scancode_with_modifiers() == (KEY_MASK_CMD | KEY_Q)) {
+ _dim_window();
+ get_tree()->quit();
}
+#endif
- String icon = cf->get_value("application", "config/icon", "");
- String main_scene = cf->get_value("application", "run/main_scene", "");
+ if (tabs->get_current_tab() != 0)
+ return;
- uint64_t last_modified = 0;
- if (FileAccess::exists(conf)) {
- last_modified = FileAccess::get_modified_time(conf);
+ bool scancode_handled = true;
- String fscache = path.plus_file(".fscache");
- if (FileAccess::exists(fscache)) {
- uint64_t cache_modified = FileAccess::get_modified_time(fscache);
- if (cache_modified > last_modified)
- last_modified = cache_modified;
- }
- } else {
- grayed = true;
- }
+ switch (k->get_scancode()) {
- ProjectItem item(project, project_name, path, conf, icon, main_scene, last_modified, favorite, grayed, filter_order_option);
- if (favorite)
- favorite_projects.push_back(item);
- else
- projects.push_back(item);
- }
- projects.sort();
- favorite_projects.sort();
+ case KEY_ENTER: {
- for (List<ProjectItem>::Element *E = projects.front(); E;) {
- List<ProjectItem>::Element *next = E->next();
- if (favorite_projects.find(E->get()) != NULL)
- projects.erase(E->get());
- E = next;
- }
- for (List<ProjectItem>::Element *E = favorite_projects.back(); E; E = E->prev()) {
- projects.push_front(E->get());
- }
+ _open_selected_projects_ask();
+ } break;
+ case KEY_DELETE: {
- Ref<Texture> favorite_icon = get_icon("Favorites", "EditorIcons");
+ _erase_project();
+ } break;
+ case KEY_HOME: {
- for (List<ProjectItem>::Element *E = projects.front(); E; E = E->next()) {
+ if (_project_list->get_project_count() > 0) {
+ _project_list->select_project(0);
+ _update_project_buttons();
+ }
- ProjectItem &item = E->get();
- String project = item.project;
- String path = item.path;
- String conf = item.conf;
+ } break;
+ case KEY_END: {
- if (filter_option == ProjectListFilter::FILTER_NAME && search_term != "" && item.project_name.findn(search_term) == -1)
- continue;
+ if (_project_list->get_project_count() > 0) {
+ _project_list->select_project(_project_list->get_project_count() - 1);
+ _update_project_buttons();
+ }
- Ref<Texture> icon;
+ } break;
+ case KEY_UP: {
- if (item.icon != "") {
- Ref<Image> img;
- img.instance();
- Error err = img->load(item.icon.replace_first("res://", path + "/"));
- if (err == OK) {
+ if (k->get_shift())
+ break;
- Ref<Texture> default_icon = get_icon("DefaultProjectIcon", "EditorIcons");
- img->resize(default_icon->get_width(), default_icon->get_height());
- Ref<ImageTexture> it = memnew(ImageTexture);
- it->create_from_image(img);
- icon = it;
- }
- }
+ int index = _project_list->get_single_selected_index();
+ if (index > 0) {
+ _project_list->select_project(index - 1);
+ _project_list->ensure_project_visible(index - 1);
+ _update_project_buttons();
+ }
- if (icon.is_null()) {
- icon = get_icon("DefaultProjectIcon", "EditorIcons");
- }
+ break;
+ }
+ case KEY_DOWN: {
- selected_list_copy.erase(project);
-
- bool is_favorite = item.favorite;
- bool is_grayed = item.grayed;
-
- HBoxContainer *hb = memnew(HBoxContainer);
- hb->set_meta("name", project);
- hb->set_meta("main_scene", item.main_scene);
- hb->set_meta("favorite", is_favorite);
- hb->connect("draw", this, "_panel_draw", varray(hb));
- hb->connect("gui_input", this, "_panel_input", varray(hb));
- hb->add_constant_override("separation", 10 * EDSCALE);
-
- VBoxContainer *favorite_box = memnew(VBoxContainer);
- TextureButton *favorite = memnew(TextureButton);
- favorite->set_normal_texture(favorite_icon);
- if (!is_favorite)
- favorite->set_modulate(Color(1, 1, 1, 0.2));
- favorite->connect("pressed", this, "_favorite_pressed", varray(hb));
- favorite_box->add_child(favorite);
- favorite_box->set_alignment(BoxContainer::ALIGN_CENTER);
- hb->add_child(favorite_box);
-
- TextureRect *tf = memnew(TextureRect);
- tf->set_texture(icon);
- hb->add_child(tf);
+ if (k->get_shift())
+ break;
- VBoxContainer *vb = memnew(VBoxContainer);
- if (is_grayed)
- vb->set_modulate(Color(0.5, 0.5, 0.5));
- vb->set_name("project");
- vb->set_h_size_flags(SIZE_EXPAND_FILL);
- hb->add_child(vb);
- Control *ec = memnew(Control);
- ec->set_custom_minimum_size(Size2(0, 1));
- ec->set_mouse_filter(MOUSE_FILTER_PASS);
- vb->add_child(ec);
- Label *title = memnew(Label(item.project_name));
- title->add_font_override("font", gui_base->get_font("title", "EditorFonts"));
- title->add_color_override("font_color", font_color);
- title->set_clip_text(true);
- vb->add_child(title);
-
- HBoxContainer *path_hb = memnew(HBoxContainer);
- path_hb->set_name("path_box");
- path_hb->set_h_size_flags(SIZE_EXPAND_FILL);
- vb->add_child(path_hb);
-
- Button *show = memnew(Button);
- show->set_name("show");
- show->set_icon(get_icon("Filesystem", "EditorIcons"));
- show->set_flat(true);
- show->set_modulate(Color(1, 1, 1, 0.5));
- path_hb->add_child(show);
- show->connect("pressed", this, "_show_project", varray(path));
- show->set_tooltip(TTR("Show in File Manager"));
+ int index = _project_list->get_single_selected_index();
+ if (index + 1 < _project_list->get_project_count()) {
+ _project_list->select_project(index + 1);
+ _project_list->ensure_project_visible(index + 1);
+ _update_project_buttons();
+ }
- Label *fpath = memnew(Label(path));
- fpath->set_name("path");
- path_hb->add_child(fpath);
- fpath->set_h_size_flags(SIZE_EXPAND_FILL);
- fpath->set_modulate(Color(1, 1, 1, 0.5));
- fpath->add_color_override("font_color", font_color);
- fpath->set_clip_text(true);
+ } break;
+ case KEY_F: {
+ if (k->get_command())
+ this->project_filter->search_box->grab_focus();
+ else
+ scancode_handled = false;
+ } break;
+ default: {
+ scancode_handled = false;
+ } break;
+ }
- scroll_children->add_child(hb);
+ if (scancode_handled) {
+ accept_event();
+ }
}
+}
- for (Map<String, String>::Element *E = selected_list_copy.front(); E; E = E->next()) {
- String key = E->key();
- selected_list.erase(key);
- }
+void ProjectManager::_load_recent_projects() {
- scroll->set_v_scroll(0);
+ _project_list->set_order_option(project_order_filter->get_filter_option());
+ _project_list->set_search_term(project_filter->get_search_term());
+ _project_list->load_projects();
_update_project_buttons();
- EditorSettings::get_singleton()->save();
-
tabs->set_current_tab(0);
}
void ProjectManager::_on_projects_updated() {
- _load_recent_projects();
+ Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
+ int index = 0;
+ for (int i = 0; i < selected_projects.size(); ++i) {
+ index = _project_list->refresh_project(selected_projects[i].path);
+ }
+ if (index != -1) {
+ _project_list->ensure_project_visible(index);
+ }
}
void ProjectManager::_on_project_created(const String &dir) {
project_filter->clear();
- bool has_already = false;
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- Label *fpath = Object::cast_to<Label>(hb->get_node(NodePath("project/path_box/path")));
- if (fpath->get_text() == dir) {
- has_already = true;
- break;
- }
- }
- if (has_already) {
- _update_scroll_position(dir);
- } else {
- _load_recent_projects();
- _update_scroll_position(dir);
- }
+ int i = _project_list->refresh_project(dir);
+ _project_list->select_project(i);
+ _project_list->ensure_project_visible(i);
_open_selected_projects_ask();
}
-void ProjectManager::_update_scroll_position(const String &dir) {
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- Label *fpath = Object::cast_to<Label>(hb->get_node(NodePath("project/path_box/path")));
- if (fpath->get_text() == dir) {
- last_clicked = hb->get_meta("name");
- selected_list.clear();
- selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
- _update_project_buttons();
- int last_y_visible = scroll->get_v_scroll() + scroll->get_size().y;
- int offset_diff = (hb->get_position().y + hb->get_size().y) - last_y_visible;
-
- if (offset_diff > 0)
- scroll->set_v_scroll(scroll->get_v_scroll() + offset_diff);
- break;
- }
- }
-}
-
void ProjectManager::_confirm_update_settings() {
_open_selected_projects();
}
+void ProjectManager::_global_menu_action(const Variant &p_id, const Variant &p_meta) {
+
+ int id = (int)p_id;
+ if (id == ProjectList::GLOBAL_NEW_WINDOW) {
+ List<String> args;
+ String exec = OS::get_singleton()->get_executable_path();
+
+ OS::ProcessID pid = 0;
+ OS::get_singleton()->execute(exec, args, false, &pid);
+ } else if (id == ProjectList::GLOBAL_OPEN_PROJECT) {
+ String conf = (String)p_meta;
+
+ if (conf != String()) {
+ List<String> args;
+ args.push_back(conf);
+ String exec = OS::get_singleton()->get_executable_path();
+
+ OS::ProcessID pid = 0;
+ OS::get_singleton()->execute(exec, args, false, &pid);
+ }
+ }
+}
+
void ProjectManager::_open_selected_projects() {
- for (const Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
- const String &selected = E->key();
+ const Set<String> &selected_list = _project_list->get_selected_project_keys();
+
+ for (const Set<String>::Element *E = selected_list.front(); E; E = E->next()) {
+ const String &selected = E->get();
String path = EditorSettings::get_singleton()->get("projects/" + selected);
String conf = path.plus_file("project.godot");
+
if (!FileAccess::exists(conf)) {
dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
dialog_error->popup_centered_minsize();
@@ -1539,6 +2001,8 @@ void ProjectManager::_open_selected_projects() {
void ProjectManager::_open_selected_projects_ask() {
+ const Set<String> &selected_list = _project_list->get_selected_project_keys();
+
if (selected_list.size() < 1) {
return;
}
@@ -1549,22 +2013,14 @@ void ProjectManager::_open_selected_projects_ask() {
return;
}
- // Update the project settings or don't open
- String path = EditorSettings::get_singleton()->get("projects/" + selected_list.front()->key());
- String conf = path.plus_file("project.godot");
-
- // FIXME: We already parse those in _load_recent_projects, we could instead make
- // its `projects` list global and reuse its parsed metadata here.
- Ref<ConfigFile> cf = memnew(ConfigFile);
- Error cf_err = cf->load(conf);
-
- if (cf_err != OK) {
- dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
- dialog_error->popup_centered_minsize();
+ ProjectList::Item project = _project_list->get_selected_projects()[0];
+ if (project.missing) {
return;
}
- int config_version = (int)cf->get_value("", "config_version", 0);
+ // Update the project settings or don't open
+ String conf = project.path.plus_file("project.godot");
+ int config_version = project.version;
// Check if the config_version property was empty or 0
if (config_version == 0) {
@@ -1580,7 +2036,7 @@ void ProjectManager::_open_selected_projects_ask() {
}
// Check if the file was generated by a newer, incompatible engine version
if (config_version > ProjectSettings::CONFIG_VERSION) {
- dialog_error->set_text(vformat(TTR("Can't open project at '%s'.") + "\n" + TTR("The project settings were created by a newer engine version, whose settings are not compatible with this version."), path));
+ dialog_error->set_text(vformat(TTR("Can't open project at '%s'.") + "\n" + TTR("The project settings were created by a newer engine version, whose settings are not compatible with this version."), project.path));
dialog_error->popup_centered_minsize();
return;
}
@@ -1591,16 +2047,18 @@ void ProjectManager::_open_selected_projects_ask() {
void ProjectManager::_run_project_confirm() {
- for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
+ Vector<ProjectList::Item> selected_list = _project_list->get_selected_projects();
- const String &selected_main = E->get();
+ for (int i = 0; i < selected_list.size(); ++i) {
+
+ const String &selected_main = selected_list[i].main_scene;
if (selected_main == "") {
run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in the Project Settings under the \"Application\" category."));
run_error_diag->popup_centered();
return;
}
- const String &selected = E->key();
+ const String &selected = selected_list[i].project_key;
String path = EditorSettings::get_singleton()->get("projects/" + selected);
if (!DirAccess::exists(path + "/.import")) {
@@ -1628,8 +2086,11 @@ void ProjectManager::_run_project_confirm() {
}
}
+// When you press the "Run" button
void ProjectManager::_run_project() {
+ const Set<String> &selected_list = _project_list->get_selected_project_keys();
+
if (selected_list.size() < 1) {
return;
}
@@ -1642,11 +2103,6 @@ void ProjectManager::_run_project() {
}
}
-void ProjectManager::_show_project(const String &p_path) {
-
- OS::get_singleton()->shell_open(String("file://") + p_path);
-}
-
void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->change_dir(path);
@@ -1672,7 +2128,7 @@ void ProjectManager::_scan_begin(const String &p_base) {
print_line("Found " + itos(projects.size()) + " projects.");
for (List<String>::Element *E = projects.front(); E; E = E->next()) {
- String proj = E->get().replace("/", "::");
+ String proj = get_project_key_from_path(E->get());
EditorSettings::get_singleton()->set("projects/" + proj, E->get());
}
EditorSettings::get_singleton()->save();
@@ -1698,12 +2154,14 @@ void ProjectManager::_import_project() {
void ProjectManager::_rename_project() {
+ const Set<String> &selected_list = _project_list->get_selected_project_keys();
+
if (selected_list.size() == 0) {
return;
}
- for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
- const String &selected = E->key();
+ for (Set<String>::Element *E = selected_list.front(); E; E = E->next()) {
+ const String &selected = E->get();
String path = EditorSettings::get_singleton()->get("projects/" + selected);
npdialog->set_project_path(path);
npdialog->set_mode(ProjectDialog::MODE_RENAME);
@@ -1712,55 +2170,19 @@ void ProjectManager::_rename_project() {
}
void ProjectManager::_erase_project_confirm() {
-
- if (selected_list.size() == 0) {
- return;
- }
- for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
- EditorSettings::get_singleton()->erase("projects/" + E->key());
- EditorSettings::get_singleton()->erase("favorite_projects/" + E->key());
- }
- EditorSettings::get_singleton()->save();
- selected_list.clear();
- last_clicked = "";
- _load_recent_projects();
+ _project_list->erase_selected_projects();
+ _update_project_buttons();
}
void ProjectManager::_erase_missing_projects_confirm() {
-
- Map<String, String> list_all_projects;
- for (int i = 0; i < scroll_children->get_child_count(); i++) {
- HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i));
- if (hb) {
- list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
- }
- }
-
- if (list_all_projects.size() == 0) {
- return;
- }
-
- int deleted_projects = 0;
- int remaining_projects = 0;
- for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) {
- String project_name = E->key().replace(":::", ":/").replace("::", "/") + "/project.godot";
- if (!FileAccess::exists(project_name)) {
- deleted_projects++;
- EditorSettings::get_singleton()->erase("projects/" + E->key());
- EditorSettings::get_singleton()->erase("favorite_projects/" + E->key());
- } else {
- remaining_projects++;
- }
- }
- print_line("Deleted " + itos(deleted_projects) + " projects, remaining " + itos(remaining_projects) + " projects");
- EditorSettings::get_singleton()->save();
- selected_list.clear();
- last_clicked = "";
- _load_recent_projects();
+ _project_list->erase_missing_projects();
+ _update_project_buttons();
}
void ProjectManager::_erase_project() {
+ const Set<String> &selected_list = _project_list->get_selected_project_keys();
+
if (selected_list.size() == 0)
return;
@@ -1777,7 +2199,7 @@ void ProjectManager::_erase_project() {
void ProjectManager::_erase_missing_projects() {
- erase_missing_ask->set_text(TTR("Remove all missing projects from the list? (Folders contents will not be modified)"));
+ erase_missing_ask->set_text(TTR("Remove all missing projects from the list?\nThe project folders' contents won't be modified."));
erase_missing_ask->popup_centered_minsize();
}
@@ -1866,13 +2288,23 @@ void ProjectManager::_scan_multiple_folders(PoolStringArray p_files) {
}
}
+void ProjectManager::_on_order_option_changed() {
+ _project_list->set_order_option(project_order_filter->get_filter_option());
+ _project_list->sort_projects();
+}
+
+void ProjectManager::_on_filter_option_changed() {
+ _project_list->set_search_term(project_filter->get_search_term());
+ _project_list->sort_projects();
+}
+
void ProjectManager::_bind_methods() {
ClassDB::bind_method("_open_selected_projects_ask", &ProjectManager::_open_selected_projects_ask);
ClassDB::bind_method("_open_selected_projects", &ProjectManager::_open_selected_projects);
+ ClassDB::bind_method(D_METHOD("_global_menu_action"), &ProjectManager::_global_menu_action, DEFVAL(Variant()));
ClassDB::bind_method("_run_project", &ProjectManager::_run_project);
ClassDB::bind_method("_run_project_confirm", &ProjectManager::_run_project_confirm);
- ClassDB::bind_method("_show_project", &ProjectManager::_show_project);
ClassDB::bind_method("_scan_projects", &ProjectManager::_scan_projects);
ClassDB::bind_method("_scan_begin", &ProjectManager::_scan_begin);
ClassDB::bind_method("_import_project", &ProjectManager::_import_project);
@@ -1885,18 +2317,16 @@ void ProjectManager::_bind_methods() {
ClassDB::bind_method("_language_selected", &ProjectManager::_language_selected);
ClassDB::bind_method("_restart_confirm", &ProjectManager::_restart_confirm);
ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
- ClassDB::bind_method("_load_recent_projects", &ProjectManager::_load_recent_projects);
+ ClassDB::bind_method("_on_order_option_changed", &ProjectManager::_on_order_option_changed);
+ ClassDB::bind_method("_on_filter_option_changed", &ProjectManager::_on_filter_option_changed);
ClassDB::bind_method("_on_projects_updated", &ProjectManager::_on_projects_updated);
ClassDB::bind_method("_on_project_created", &ProjectManager::_on_project_created);
- ClassDB::bind_method("_update_scroll_position", &ProjectManager::_update_scroll_position);
- ClassDB::bind_method("_panel_draw", &ProjectManager::_panel_draw);
- ClassDB::bind_method("_panel_input", &ProjectManager::_panel_input);
ClassDB::bind_method("_unhandled_input", &ProjectManager::_unhandled_input);
- ClassDB::bind_method("_favorite_pressed", &ProjectManager::_favorite_pressed);
ClassDB::bind_method("_install_project", &ProjectManager::_install_project);
ClassDB::bind_method("_files_dropped", &ProjectManager::_files_dropped);
ClassDB::bind_method("_open_asset_library", &ProjectManager::_open_asset_library);
ClassDB::bind_method("_confirm_update_settings", &ProjectManager::_confirm_update_settings);
+ ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons);
ClassDB::bind_method(D_METHOD("_scan_multiple_folders", "files"), &ProjectManager::_scan_multiple_folders);
}
@@ -1924,35 +2354,21 @@ ProjectManager::ProjectManager() {
editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0);
} break;
- case 1: {
- editor_set_scale(0.75);
- } break;
-
- case 2: {
- editor_set_scale(1.0);
- } break;
-
- case 3: {
- editor_set_scale(1.25);
- } break;
-
- case 4: {
- editor_set_scale(1.5);
- } break;
-
- case 5: {
- editor_set_scale(1.75);
- } break;
-
- case 6: {
- editor_set_scale(2.0);
- } break;
+ case 1: editor_set_scale(0.75); break;
+ case 2: editor_set_scale(1.0); break;
+ case 3: editor_set_scale(1.25); break;
+ case 4: editor_set_scale(1.5); break;
+ case 5: editor_set_scale(1.75); break;
+ case 6: editor_set_scale(2.0); break;
default: {
editor_set_scale(custom_display_scale);
} break;
}
+ // Define a minimum window size to prevent UI elements from overlapping or being cut off
+ OS::get_singleton()->set_min_window_size(Size2(750, 420) * EDSCALE);
+
#ifndef OSX_ENABLED
// The macOS platform implementation uses its own hiDPI window resizing code
// TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below
@@ -1978,26 +2394,11 @@ ProjectManager::ProjectManager() {
VBoxContainer *vb = memnew(VBoxContainer);
panel->add_child(vb);
vb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE);
- vb->add_constant_override("separation", 8 * EDSCALE);
String cp;
cp += 0xA9;
OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2019 Juan Linietsky, Ariel Manzur & Godot Contributors");
- HBoxContainer *top_hb = memnew(HBoxContainer);
- vb->add_child(top_hb);
- Label *l = memnew(Label);
- l->set_text(VERSION_NAME + String(" - ") + TTR("Project Manager"));
- top_hb->add_child(l);
- top_hb->add_spacer();
- l = memnew(Label);
- String hash = String(VERSION_HASH);
- if (hash.length() != 0)
- hash = "." + hash.left(9);
- l->set_text("v" VERSION_FULL_BUILD "" + hash);
- l->set_align(Label::ALIGN_CENTER);
- top_hb->add_child(l);
-
Control *center_box = memnew(Control);
center_box->set_v_size_flags(SIZE_EXPAND_FILL);
vb->add_child(center_box);
@@ -2005,11 +2406,12 @@ ProjectManager::ProjectManager() {
tabs = memnew(TabContainer);
center_box->add_child(tabs);
tabs->set_anchors_and_margins_preset(Control::PRESET_WIDE);
+ tabs->set_tab_align(TabContainer::ALIGN_LEFT);
HBoxContainer *tree_hb = memnew(HBoxContainer);
projects_hb = tree_hb;
- projects_hb->set_name(TTR("Project List"));
+ projects_hb->set_name(TTR("Projects"));
tabs->add_child(tree_hb);
@@ -2026,31 +2428,23 @@ ProjectManager::ProjectManager() {
sort_filter_titles.push_back("Path");
sort_filter_titles.push_back("Last Modified");
project_order_filter = memnew(ProjectListFilter);
+ project_order_filter->add_filter_option();
project_order_filter->_setup_filters(sort_filter_titles);
project_order_filter->set_filter_size(150);
sort_filters->add_child(project_order_filter);
- project_order_filter->connect("filter_changed", this, "_load_recent_projects");
+ project_order_filter->connect("filter_changed", this, "_on_order_option_changed");
project_order_filter->set_custom_minimum_size(Size2(180, 10) * EDSCALE);
int projects_sorting_order = (int)EditorSettings::get_singleton()->get("project_manager/sorting_order");
project_order_filter->set_filter_option((ProjectListFilter::FilterOption)projects_sorting_order);
sort_filters->add_spacer(true);
- Label *search_label = memnew(Label);
- search_label->set_text(TTR("Search:"));
- sort_filters->add_child(search_label);
-
- HBoxContainer *search_filters = memnew(HBoxContainer);
- Vector<String> vec2;
- vec2.push_back("Name");
- vec2.push_back("Path");
+
project_filter = memnew(ProjectListFilter);
- project_filter->_setup_filters(vec2);
project_filter->add_search_box();
- search_filters->add_child(project_filter);
- project_filter->connect("filter_changed", this, "_load_recent_projects");
+ project_filter->connect("filter_changed", this, "_on_filter_option_changed");
project_filter->set_custom_minimum_size(Size2(280, 10) * EDSCALE);
- sort_filters->add_child(search_filters);
+ sort_filters->add_child(project_filter);
search_tree_vb->add_child(sort_filters);
@@ -2059,15 +2453,14 @@ ProjectManager::ProjectManager() {
search_tree_vb->add_child(pc);
pc->set_v_size_flags(SIZE_EXPAND_FILL);
- scroll = memnew(ScrollContainer);
- pc->add_child(scroll);
- scroll->set_enable_h_scroll(false);
+ _project_list = memnew(ProjectList);
+ _project_list->connect(ProjectList::SIGNAL_SELECTION_CHANGED, this, "_update_project_buttons");
+ _project_list->connect(ProjectList::SIGNAL_PROJECT_ASK_OPEN, this, "_open_selected_projects_ask");
+ pc->add_child(_project_list);
+ _project_list->set_enable_h_scroll(false);
VBoxContainer *tree_vb = memnew(VBoxContainer);
tree_hb->add_child(tree_vb);
- scroll_children = memnew(VBoxContainer);
- scroll_children->set_h_size_flags(SIZE_EXPAND_FILL);
- scroll->add_child(scroll_children);
Button *open = memnew(Button);
open->set_text(TTR("Edit"));
@@ -2141,6 +2534,17 @@ ProjectManager::ProjectManager() {
settings_hb->set_alignment(BoxContainer::ALIGN_END);
settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
+ Label *version_label = memnew(Label);
+ String hash = String(VERSION_HASH);
+ if (hash.length() != 0) {
+ hash = "." + hash.left(9);
+ }
+ version_label->set_text("v" VERSION_FULL_BUILD "" + hash);
+ // Fade out the version label to be less prominent, but still readable
+ version_label->set_self_modulate(Color(1, 1, 1, 0.6));
+ version_label->set_align(Label::ALIGN_CENTER);
+ settings_hb->add_child(version_label);
+
language_btn = memnew(OptionButton);
language_btn->set_flat(true);
language_btn->set_focus_mode(Control::FOCUS_NONE);
@@ -2173,27 +2577,6 @@ ProjectManager::ProjectManager() {
center_box->add_child(settings_hb);
settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT);
- CenterContainer *cc = memnew(CenterContainer);
- Button *cancel = memnew(Button);
- cancel->set_text(TTR("Exit"));
- cancel->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
-
-#ifndef OSX_ENABLED
- // Pressing Command + Q quits the Project Manager
- // This is handled by the platform implementation on macOS,
- // so only define the shortcut on other platforms
- InputEventKey *quit_key = memnew(InputEventKey);
- quit_key->set_command(true);
- quit_key->set_scancode(KEY_Q);
- ShortCut *quit_shortcut = memnew(ShortCut);
- quit_shortcut->set_shortcut(quit_key);
- cancel->set_shortcut(quit_shortcut);
-#endif
-
- cc->add_child(cancel);
- cancel->connect("pressed", this, "_exit_dialog");
- vb->add_child(cc);
-
//////////////////////////////////////////////////////////////
language_restart_ask = memnew(ConfirmationDialog);
@@ -2237,15 +2620,15 @@ ProjectManager::ProjectManager() {
npdialog->connect("projects_updated", this, "_on_projects_updated");
npdialog->connect("project_created", this, "_on_project_created");
+
_load_recent_projects();
if (EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")) {
_scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"));
}
- last_clicked = "";
-
SceneTree::get_singleton()->connect("files_dropped", this, "_files_dropped");
+ SceneTree::get_singleton()->connect("global_menu_action", this, "_global_menu_action");
run_error_diag = memnew(AcceptDialog);
gui_base->add_child(run_error_diag);
@@ -2315,11 +2698,20 @@ void ProjectListFilter::_bind_methods() {
ADD_SIGNAL(MethodInfo("filter_changed"));
}
+void ProjectListFilter::add_filter_option() {
+ filter_option = memnew(OptionButton);
+ filter_option->set_clip_text(true);
+ filter_option->connect("item_selected", this, "_filter_option_selected");
+ add_child(filter_option);
+}
+
void ProjectListFilter::add_search_box() {
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Search"));
search_box->connect("text_changed", this, "_search_text_changed");
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(search_box);
+
has_search_box = true;
}
@@ -2330,13 +2722,6 @@ void ProjectListFilter::set_filter_size(int h_size) {
ProjectListFilter::ProjectListFilter() {
_current_filter = FILTER_NAME;
-
- filter_option = memnew(OptionButton);
- set_filter_size(80);
- filter_option->set_clip_text(true);
- filter_option->connect("item_selected", this, "_filter_option_selected");
- add_child(filter_option);
-
has_search_box = false;
}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index d75d7164cc..cf0b8b8801 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -39,9 +39,11 @@
#include "scene/gui/tree.h"
class ProjectDialog;
+class ProjectList;
class ProjectListFilter;
class ProjectManager : public Control {
+
GDCLASS(ProjectManager, Control);
Button *erase_btn;
@@ -68,16 +70,13 @@ class ProjectManager : public Control {
AcceptDialog *dialog_error;
ProjectDialog *npdialog;
- ScrollContainer *scroll;
- VBoxContainer *scroll_children;
HBoxContainer *projects_hb;
TabContainer *tabs;
+ ProjectList *_project_list;
OptionButton *language_btn;
Control *gui_base;
- Map<String, String> selected_list; // name -> main_scene
- String last_clicked;
bool importing;
void _open_asset_library();
@@ -86,7 +85,6 @@ class ProjectManager : public Control {
void _run_project_confirm();
void _open_selected_projects();
void _open_selected_projects_ask();
- void _show_project(const String &p_path);
void _import_project();
void _new_project();
void _rename_project();
@@ -99,6 +97,7 @@ class ProjectManager : public Control {
void _restart_confirm();
void _exit_dialog();
void _scan_begin(const String &p_base);
+ void _global_menu_action(const Variant &p_id, const Variant &p_meta);
void _confirm_update_settings();
@@ -111,13 +110,13 @@ class ProjectManager : public Control {
void _install_project(const String &p_zip_path, const String &p_title);
void _dim_window();
- void _panel_draw(Node *p_hb);
- void _panel_input(const Ref<InputEvent> &p_ev, Node *p_hb);
void _unhandled_input(const Ref<InputEvent> &p_ev);
- void _favorite_pressed(Node *p_hb);
void _files_dropped(PoolStringArray p_files, int p_screen);
void _scan_multiple_folders(PoolStringArray p_files);
+ void _on_order_option_changed();
+ void _on_filter_option_changed();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -155,6 +154,7 @@ protected:
public:
void _setup_filters(Vector<String> options);
+ void add_filter_option();
void add_search_box();
void set_filter_size(int h_size);
String get_search_term();
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 001846604c..91ce256be5 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -52,8 +52,8 @@ static const char *_button_names[JOY_BUTTON_MAX] = {
"R2",
"L3",
"R3",
- "Select, Nintendo -",
- "Start, Nintendo +",
+ "Select, DualShock Share, Nintendo -",
+ "Start, DualShock Options, Nintendo +",
"D-Pad Up",
"D-Pad Down",
"D-Pad Left",
@@ -965,8 +965,6 @@ void ProjectSettingsEditor::_action_add() {
while (r->get_next())
r = r->get_next();
- if (!r)
- return;
r->select(0);
input_editor->ensure_cursor_is_visible();
action_add_error->hide();
@@ -1009,8 +1007,12 @@ void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
presets.insert("pvrtc");
presets.insert("debug");
presets.insert("release");
+ presets.insert("editor");
+ presets.insert("standalone");
presets.insert("32");
presets.insert("64");
+ // Not available as an export platform yet, so it needs to be added manually
+ presets.insert("Server");
for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
List<String> p;
@@ -1045,6 +1047,84 @@ void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
}
}
+Variant ProjectSettingsEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
+
+ TreeItem *selected = input_editor->get_selected();
+ if (!selected || selected->get_parent() != input_editor->get_root())
+ return Variant();
+
+ String name = selected->get_text(0);
+ VBoxContainer *vb = memnew(VBoxContainer);
+ HBoxContainer *hb = memnew(HBoxContainer);
+ Label *label = memnew(Label(name));
+ hb->set_modulate(Color(1, 1, 1, 1.0f));
+ hb->add_child(label);
+ vb->add_child(hb);
+ set_drag_preview(vb);
+
+ Dictionary drag_data;
+ drag_data["type"] = "nodes";
+
+ input_editor->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
+
+ return drag_data;
+}
+
+bool ProjectSettingsEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+
+ Dictionary d = p_data;
+ if (!d.has("type") || d["type"] != "nodes")
+ return false;
+
+ TreeItem *selected = input_editor->get_selected();
+ TreeItem *item = input_editor->get_item_at_position(p_point);
+ if (!selected || !item || item->get_parent() == selected)
+ return false;
+
+ return true;
+}
+
+void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+
+ if (!can_drop_data_fw(p_point, p_data, p_from))
+ return;
+
+ TreeItem *selected = input_editor->get_selected();
+ TreeItem *item = input_editor->get_item_at_position(p_point);
+ TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent();
+
+ String selected_name = "input/" + selected->get_text(0);
+ int old_order = ProjectSettings::get_singleton()->get_order(selected_name);
+ String target_name = "input/" + target->get_text(0);
+ int target_order = ProjectSettings::get_singleton()->get_order(target_name);
+
+ int order = old_order;
+ bool is_below = target_order > old_order;
+ TreeItem *iterator = is_below ? selected->get_next() : selected->get_prev();
+
+ undo_redo->create_action(TTR("Moved Input Action Event"));
+ while (iterator != target) {
+
+ String iterator_name = "input/" + iterator->get_text(0);
+ int iterator_order = ProjectSettings::get_singleton()->get_order(iterator_name);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", iterator_name, order);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", iterator_name, iterator_order);
+ order = iterator_order;
+ iterator = is_below ? iterator->get_next() : iterator->get_prev();
+ }
+
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", target_name, order);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", selected_name, target_order);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", target_name, target_order);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_name, old_order);
+
+ undo_redo->add_do_method(this, "_update_actions");
+ undo_redo->add_undo_method(this, "_update_actions");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
+}
+
void ProjectSettingsEditor::_copy_to_platform(int p_which) {
String path = globals_editor->get_inspector()->get_selected_path();
@@ -1312,7 +1392,7 @@ void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p
void ProjectSettingsEditor::_translation_filter_option_changed() {
int sel_id = translation_locale_filter_mode->get_selected_id();
- TreeItem *t = translation_filter->get_selected();
+ TreeItem *t = translation_filter->get_edited();
String locale = t->get_tooltip(0);
bool checked = t->is_checked(0);
@@ -1664,6 +1744,10 @@ void ProjectSettingsEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_editor_restart_close"), &ProjectSettingsEditor::_editor_restart_close);
ClassDB::bind_method(D_METHOD("get_tabs"), &ProjectSettingsEditor::get_tabs);
+
+ ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ProjectSettingsEditor::get_drag_data_fw);
+ ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ProjectSettingsEditor::can_drop_data_fw);
+ ClassDB::bind_method(D_METHOD("drop_data_fw"), &ProjectSettingsEditor::drop_data_fw);
}
ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
@@ -1676,6 +1760,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
tab_container = memnew(TabContainer);
tab_container->set_tab_align(TabContainer::ALIGN_LEFT);
+ tab_container->set_use_hidden_tabs_for_min_size(true);
add_child(tab_container);
VBoxContainer *props_base = memnew(VBoxContainer);
@@ -1845,6 +1930,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
input_editor->connect("item_activated", this, "_action_activated");
input_editor->connect("cell_selected", this, "_action_selected");
input_editor->connect("button_pressed", this, "_action_button_pressed");
+ input_editor->set_drag_forwarding(this);
+
popup_add = memnew(PopupMenu);
add_child(popup_add);
popup_add->connect("id_pressed", this, "_add_item");
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index d302c0d34b..4dfd8ba602 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -158,6 +158,10 @@ class ProjectSettingsEditor : public AcceptDialog {
void _toggle_search_bar(bool p_pressed);
+ Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
+ bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+ void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+
void _copy_to_platform_about_to_show();
ProjectSettingsEditor();
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 82d974cae3..ecb272876d 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -614,7 +614,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
type = Variant::Type(i);
}
}
- if (type)
+ if (type != Variant::NIL)
property_select->select_method_from_basic_type(type, v);
updating = false;
return false;
@@ -859,6 +859,13 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
add_child(color_picker);
color_picker->hide();
color_picker->connect("color_changed", this, "_color_changed");
+
+ // get default color picker mode from editor settings
+ int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
+ if (default_color_mode == 1)
+ color_picker->set_hsv_mode(true);
+ else if (default_color_mode == 2)
+ color_picker->set_raw_mode(true);
}
color_picker->show();
@@ -971,7 +978,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
menu->add_separator();
menu->add_item(TTR("Show in FileSystem"), OBJ_MENU_SHOW_IN_FILE_SYSTEM);
}
- } else {
}
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
diff --git a/editor/property_editor.h b/editor/property_editor.h
index a8ef1d6fc1..029c2211d5 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -46,10 +46,6 @@
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PropertyValueEvaluator;
class CreateDialog;
class PropertySelector;
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 813e24bd61..3bc93c3900 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -337,7 +337,7 @@ void PropertySelector::_item_selected() {
String name = item->get_metadata(0);
String class_type;
- if (type) {
+ if (type != Variant::NIL) {
class_type = Variant::get_type_name(type);
} else {
diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp
index 84cd6da3d9..7cdd900d25 100644
--- a/editor/pvrtc_compress.cpp
+++ b/editor/pvrtc_compress.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "editor_settings.h"
@@ -52,57 +53,75 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
_base_image_compress_pvrtc2_func(p_image);
else if (_base_image_compress_pvrtc4_func)
_base_image_compress_pvrtc4_func(p_image);
-
break;
case Image::COMPRESS_PVRTC4:
if (_base_image_compress_pvrtc4_func)
_base_image_compress_pvrtc4_func(p_image);
-
break;
- default: ERR_FAIL();
+ default:
+ ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module.");
}
return;
}
- String tmppath = EditorSettings::get_singleton()->get_cache_dir();
-
- List<String> args;
+ String tmppath = EditorSettings::get_singleton()->get_cache_dir();
String src_img = tmppath.plus_file("_tmp_src_img.png");
String dst_img = tmppath.plus_file("_tmp_dst_img.pvr");
+ List<String> args;
args.push_back("-i");
args.push_back(src_img);
args.push_back("-o");
args.push_back(dst_img);
args.push_back("-f");
- switch (p_mode) {
- case Image::COMPRESS_PVRTC2: args.push_back("PVRTC2"); break;
- case Image::COMPRESS_PVRTC4: args.push_back("PVRTC4"); break;
- case Image::COMPRESS_ETC: args.push_back("ETC"); break;
- default: ERR_FAIL();
+ switch (p_mode) {
+ case Image::COMPRESS_PVRTC2:
+ args.push_back("PVRTC2");
+ break;
+ case Image::COMPRESS_PVRTC4:
+ args.push_back("PVRTC4");
+ break;
+ case Image::COMPRESS_ETC:
+ args.push_back("ETC");
+ break;
+ default:
+ ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module.");
}
if (EditorSettings::get_singleton()->get("filesystem/import/pvrtc_fast_conversion").operator bool()) {
args.push_back("-pvrtcfast");
}
- if (p_image->has_mipmaps())
+ if (p_image->has_mipmaps()) {
args.push_back("-m");
+ }
+ // Save source PNG.
Ref<ImageTexture> t = memnew(ImageTexture);
t->create_from_image(Ref<Image>(p_image), 0);
ResourceSaver::save(src_img, t);
Error err = OS::get_singleton()->execute(ttpath, args, true);
- ERR_EXPLAIN(TTR("Could not execute PVRTC tool:") + " " + ttpath);
- ERR_FAIL_COND(err != OK);
+ if (err != OK) {
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
+ ERR_FAIL_MSG("Could not execute PVRTC tool: " + ttpath);
+ }
t = ResourceLoader::load(dst_img, "Texture");
-
- ERR_EXPLAIN(TTR("Can't load back converted image using PVRTC tool:") + " " + dst_img);
- ERR_FAIL_COND(t.is_null());
+ if (t.is_null()) {
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
+ ERR_FAIL_MSG("Can't load back converted image using PVRTC tool.");
+ }
p_image->copy_internals_from(t->get_data());
+
+ // Clean up generated files.
+ DirAccess::remove_file_or_error(src_img);
+ DirAccess::remove_file_or_error(dst_img);
}
static void _compress_pvrtc2(Image *p_image) {
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index dc2f098333..4e1c900ee4 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -256,16 +256,16 @@ void EditorQuickOpen::_confirmed() {
void EditorQuickOpen::_notification(int p_what) {
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
connect("confirmed", this, "_confirmed");
- search_box->set_right_icon(get_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
+ FALLTHROUGH;
+ }
+ case NOTIFICATION_THEME_CHANGED: {
+ search_box->set_right_icon(get_icon("Search", "EditorIcons"));
} break;
case NOTIFICATION_EXIT_TREE: {
-
disconnect("confirmed", this, "_confirmed");
} break;
}
@@ -289,7 +289,6 @@ EditorQuickOpen::EditorQuickOpen() {
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
- //set_child_rect(vbc);
search_box = memnew(LineEdit);
vbc->add_margin_child(TTR("Search:"), search_box);
search_box->connect("text_changed", this, "_text_changed");
@@ -302,6 +301,7 @@ EditorQuickOpen::EditorQuickOpen() {
set_hide_on_ok(false);
search_options->connect("item_activated", this, "_confirmed");
search_options->set_hide_root(true);
+ search_options->set_hide_folding(true);
search_options->add_constant_override("draw_guides", 1);
ei = "EditorIcons";
ot = "Object";
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 935946bf24..2ddf1f7056 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -301,6 +301,8 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de
Ref<PackedScene> data = ResourceLoader::load(path);
if (data.is_valid()) {
p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
+ if (!p)
+ continue;
instances.push_back(p);
} else
break;
@@ -338,7 +340,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
tree->edit_selected();
}
} break;
- case TOOL_NEW: {
+ case TOOL_NEW:
+ case TOOL_REPARENT_TO_NEW_NODE: {
if (!profile_allow_editing) {
break;
@@ -394,7 +397,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
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 && !editor_selection->get_selected_node_list().empty())
+ selected = editor_selection->get_selected_node_list().front()->get();
+
+ if (selected)
+ create_dialog->popup_create(false, true, selected->get_class());
+
} break;
case TOOL_ATTACH_SCRIPT: {
@@ -462,8 +472,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *n = Object::cast_to<Node>(selection[i]);
Ref<Script> existing = n->get_script();
- if (existing.is_valid()) {
- const RefPtr empty;
+ Ref<Script> empty = EditorNode::get_singleton()->get_object_custom_type_base(n);
+ if (existing != empty) {
editor_data->get_undo_redo().add_do_method(n, "set_script", empty);
editor_data->get_undo_redo().add_undo_method(n, "set_script", existing);
}
@@ -749,7 +759,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
_delete_confirm();
} else {
- delete_dialog->set_text(TTR("Delete Node(s)?"));
+ if (remove_list.size() >= 2) {
+ delete_dialog->set_text(vformat(TTR("Delete %d nodes?"), remove_list.size()));
+ } else if (remove_list.size() == 1 && remove_list[0] == editor_data->get_edited_scene_root()) {
+ delete_dialog->set_text(vformat(TTR("Delete the root node \"%s\"?"), remove_list[0]->get_name()));
+ } else if (remove_list.size() == 1 && remove_list[0]->get_filename() == "" && remove_list[0]->get_child_count() >= 1) {
+ // Display this message only for non-instanced scenes
+ delete_dialog->set_text(vformat(TTR("Delete node \"%s\" and its children?"), remove_list[0]->get_name()));
+ } else {
+ delete_dialog->set_text(vformat(TTR("Delete node \"%s\"?"), remove_list[0]->get_name()));
+ }
+
+ // Resize the dialog to its minimum size.
+ // This prevents the dialog from being too wide after displaying
+ // a deletion confirmation for a node with a long name.
+ delete_dialog->set_size(Size2());
delete_dialog->popup_centered_minsize();
}
@@ -976,9 +1000,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} else {
new_node = Object::cast_to<Node>(ClassDB::instance(selected_favorite_root));
}
+
if (!new_node) {
- ERR_EXPLAIN("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead.");
new_node = memnew(Node);
+ ERR_PRINTS("Creating root from favorite '" + selected_favorite_root + "' failed. Creating 'Node' instead.");
}
} else {
switch (p_tool) {
@@ -1484,7 +1509,7 @@ bool SceneTreeDock::_validate_no_foreign() {
// When edited_scene inherits from another one the root Node will be the parent Scene,
// we don't want to consider that Node a foreign one otherwise we would not be able to
- // delete it
+ // delete it.
if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) {
continue;
}
@@ -1508,7 +1533,7 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.empty())
- return; //nothing to reparent
+ return; // Nothing to reparent.
Vector<Node *> nodes;
@@ -1524,21 +1549,32 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
Node *new_parent = p_new_parent;
ERR_FAIL_COND(!new_parent);
+ if (p_nodes.size() == 0)
+ return; // Nothing to reparent.
+
+ p_nodes.sort_custom<Node::Comparator>(); //Makes result reliable.
+
+ bool no_change = true;
+ for (int ni = 0; ni < p_nodes.size(); ni++) {
+
+ if (p_nodes[ni] == p_new_parent)
+ return; // Attempt to reparent to itself.
+
+ if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_position_in_parent())
+ no_change = false;
+ }
+
+ if (no_change)
+ return; // Position and parent didn't change.
+
Node *validate = new_parent;
while (validate) {
- if (p_nodes.find(validate) != -1) {
- ERR_EXPLAIN("Selection changed at some point.. can't reparent");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent.");
validate = validate->get_parent();
}
- //ok all valid
-
- if (p_nodes.size() == 0)
- return; //nothing to reparent
- //sort by tree order, so re-adding is easy
+ // Sort by tree order, so re-adding is easy.
p_nodes.sort_custom<Node::Comparator>();
editor_data->get_undo_redo().create_action(TTR("Reparent Node"));
@@ -1550,7 +1586,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
for (int ni = 0; ni < p_nodes.size(); ni++) {
- //no undo for now, sorry
+ // No undo implemented for this yet.
Node *node = p_nodes[ni];
fill_path_renames(node, new_parent, &path_renames);
@@ -1560,14 +1596,11 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
node->get_owned_by(node->get_owner(), &owned);
Array owners;
for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
-
owners.push_back(E->get());
}
- if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni) {
- //if child will generate a gap when moved, adjust
- inc--;
- }
+ if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni)
+ inc--; // If the child will generate a gap when moved, adjust.
editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
editor_data->get_undo_redo().add_do_method(new_parent, "add_child", node);
@@ -1579,17 +1612,17 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
String old_name = former_names[ni];
String new_name = new_parent->validate_child_name(node);
- // name was modified, fix the path renames
+ // Name was modified, fix the path renames.
if (old_name.casecmp_to(new_name) != 0) {
- // Fix the to name to have the new name
+ // Fix the to name to have the new name.
NodePath old_new_name = path_renames[ni].second;
NodePath new_path;
Vector<StringName> unfixed_new_names = old_new_name.get_names();
Vector<StringName> fixed_new_names;
- // Get last name and replace with fixed new name
+ // Get last name and replace with fixed new name.
for (int a = 0; a < (unfixed_new_names.size() - 1); a++) {
fixed_new_names.push_back(unfixed_new_names[a]);
}
@@ -1623,8 +1656,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
inc++;
}
- //add and move in a second step.. (so old order is preserved)
-
+ // Add and move in a second step (so old order is preserved).
for (int ni = 0; ni < p_nodes.size(); ni++) {
Node *node = p_nodes[ni];
@@ -1905,6 +1937,54 @@ Node *SceneTreeDock::_get_selection_group_tail(Node *p_node, List<Node *> p_list
return tail;
}
+void SceneTreeDock::_do_create(Node *p_parent) {
+ Object *c = create_dialog->instance_selected();
+
+ ERR_FAIL_COND(!c);
+ Node *child = Object::cast_to<Node>(c);
+ ERR_FAIL_COND(!child);
+
+ editor_data->get_undo_redo().create_action(TTR("Create Node"));
+
+ if (edited_scene) {
+
+ editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child);
+ editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene);
+ editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
+ editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child);
+ editor_data->get_undo_redo().add_do_reference(child);
+ editor_data->get_undo_redo().add_undo_method(p_parent, "remove_child", child);
+
+ String new_name = p_parent->validate_child_name(child);
+ ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
+ editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", edited_scene->get_path_to(p_parent), child->get_class(), new_name);
+ editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).plus_file(new_name)));
+
+ } else {
+
+ editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child);
+ editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
+ editor_data->get_undo_redo().add_do_reference(child);
+ editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL);
+ }
+
+ editor_data->get_undo_redo().commit_action();
+ editor->push_item(c);
+ editor_selection->clear();
+ editor_selection->add_node(child);
+ if (Object::cast_to<Control>(c)) {
+ //make editor more comfortable, so some controls don't appear super shrunk
+ Control *ct = Object::cast_to<Control>(c);
+
+ Size2 ms = ct->get_minimum_size();
+ if (ms.width < 4)
+ ms.width = 40;
+ if (ms.height < 4)
+ ms.height = 40;
+ ct->set_size(ms);
+ }
+}
+
void SceneTreeDock::_create() {
if (current_option == TOOL_NEW) {
@@ -1923,67 +2003,78 @@ void SceneTreeDock::_create() {
ERR_FAIL_COND(!parent);
}
- Object *c = create_dialog->instance_selected();
-
- ERR_FAIL_COND(!c);
- Node *child = Object::cast_to<Node>(c);
- ERR_FAIL_COND(!child);
-
- editor_data->get_undo_redo().create_action(TTR("Create Node"));
+ _do_create(parent);
- if (edited_scene) {
+ } else if (current_option == TOOL_REPLACE) {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ ERR_FAIL_COND(selection.size() <= 0);
- editor_data->get_undo_redo().add_do_method(parent, "add_child", child);
- editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene);
- editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
- editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", child);
- editor_data->get_undo_redo().add_do_reference(child);
- editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child);
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change type of node(s)"));
- String new_name = parent->validate_child_name(child);
- ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
- editor_data->get_undo_redo().add_do_method(sed, "live_debug_create_node", edited_scene->get_path_to(parent), child->get_class(), new_name);
- editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(new_name)));
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Node *n = E->get();
+ ERR_FAIL_COND(!n);
- } else {
+ Object *c = create_dialog->instance_selected();
- editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child);
- editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
- editor_data->get_undo_redo().add_do_reference(child);
- editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", (Object *)NULL);
- }
+ ERR_FAIL_COND(!c);
+ Node *newnode = Object::cast_to<Node>(c);
+ ERR_FAIL_COND(!newnode);
- editor_data->get_undo_redo().commit_action();
- editor->push_item(c);
- editor_selection->clear();
- editor_selection->add_node(child);
- if (Object::cast_to<Control>(c)) {
- //make editor more comfortable, so some controls don't appear super shrunk
- Control *ct = Object::cast_to<Control>(c);
-
- Size2 ms = ct->get_minimum_size();
- if (ms.width < 4)
- ms.width = 40;
- if (ms.height < 4)
- ms.height = 40;
- ct->set_size(ms);
+ ur->add_do_method(this, "replace_node", n, newnode, true, false);
+ ur->add_do_reference(newnode);
+ ur->add_undo_method(this, "replace_node", newnode, n, false, false);
+ ur->add_undo_reference(n);
}
- } else if (current_option == TOOL_REPLACE) {
+ ur->commit_action();
+ } else if (current_option == TOOL_REPARENT_TO_NEW_NODE) {
List<Node *> selection = editor_selection->get_selected_node_list();
ERR_FAIL_COND(selection.size() <= 0);
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ // Find top level node in selection
+ bool only_one_top_node = true;
+
+ Node *first = selection.front()->get();
+ ERR_FAIL_COND(!first);
+ int smaller_path_to_top = first->get_path_to(scene_root).get_name_count();
+ Node *top_node = first;
+
+ for (List<Node *>::Element *E = selection.front()->next(); E; E = E->next()) {
Node *n = E->get();
ERR_FAIL_COND(!n);
- Object *c = create_dialog->instance_selected();
+ int path_length = n->get_path_to(scene_root).get_name_count();
- ERR_FAIL_COND(!c);
- Node *newnode = Object::cast_to<Node>(c);
- ERR_FAIL_COND(!newnode);
+ if (top_node != n) {
+ if (smaller_path_to_top > path_length) {
+ top_node = n;
+ smaller_path_to_top = path_length;
+ only_one_top_node = true;
+ } else if (smaller_path_to_top == path_length) {
+ if (only_one_top_node && top_node->get_parent() != n->get_parent())
+ only_one_top_node = false;
+ }
+ }
+ }
+
+ Node *parent = NULL;
+ if (only_one_top_node)
+ parent = top_node->get_parent();
+ else
+ parent = top_node->get_parent()->get_parent();
- replace_node(n, newnode);
+ _do_create(parent);
+
+ Vector<Node *> nodes;
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ nodes.push_back(E->get());
}
+
+ // This works because editor_selection was cleared and populated with last created node in _do_create()
+ Node *last_created = editor_selection->get_selected_node_list().front()->get();
+ _do_reparent(last_created, -1, nodes, true);
}
scene_tree->get_scene_tree()->call_deferred("grab_focus");
@@ -2184,8 +2275,7 @@ void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
//drop at above selected node
if (to_node == EditorNode::get_singleton()->get_edited_scene()) {
to_node = NULL;
- ERR_EXPLAIN("Cannot perform drop above the root node!");
- ERR_FAIL();
+ ERR_FAIL_MSG("Cannot perform drop above the root node!");
}
to_pos = to_node->get_index();
@@ -2325,6 +2415,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->clear();
Ref<Script> existing_script;
+ bool exisiting_script_removable = true;
if (selection.size() == 1) {
Node *selected = selection[0];
@@ -2344,6 +2435,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
existing_script = selected->get_script();
+
+ if (EditorNode::get_singleton()->get_object_custom_type_base(selected) == existing_script) {
+ exisiting_script_removable = false;
+ }
}
if (profile_allow_script_editing) {
@@ -2355,7 +2450,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_ATTACH_SCRIPT);
}
}
- if (selection.size() > 1 || existing_script.is_valid()) {
+ if (selection.size() > 1 || (existing_script.is_valid() && exisiting_script_removable)) {
menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
}
menu->add_separator();
@@ -2373,6 +2468,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("MoveDown", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN);
menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
+ menu->add_icon_shortcut(get_icon("ReparentToNewNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE);
menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
}
}
@@ -2637,6 +2733,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_feature_profile_changed"), &SceneTreeDock::_feature_profile_changed);
ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance);
+ ClassDB::bind_method(D_METHOD("get_tree_editor"), &SceneTreeDock::get_tree_editor);
ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node);
ADD_SIGNAL(MethodInfo("remote_tree_selected"));
@@ -2669,6 +2766,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN);
ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D);
ED_SHORTCUT("scene_tree/reparent", TTR("Reparent"));
+ ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node"));
ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root"));
ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene"));
ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 8a2b237b8b..cd582fdf57 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -70,6 +70,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_MOVE_DOWN,
TOOL_DUPLICATE,
TOOL_REPARENT,
+ TOOL_REPARENT_TO_NEW_NODE,
TOOL_MAKE_ROOT,
TOOL_NEW_SCENE_FROM,
TOOL_MERGE_FROM_SCENE,
@@ -142,6 +143,7 @@ class SceneTreeDock : public VBoxContainer {
bool first_enter;
void _create();
+ void _do_create(Node *p_parent);
Node *scene_root;
Node *edited_scene;
EditorNode *editor;
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 445ca3a792..f1fc4eb950 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,13 +211,20 @@ 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() && EditorNode::get_singleton()->get_object_custom_type_base(p_node) != script) {
//has script
item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT);
} else {
- //has no script
+ //has no script (or script is a custom type)
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
+
+ if (!script.is_null()) { // make sure to mark the script if a custom type
+ item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT);
+ item->set_button_disabled(0, item->get_button_count(0) - 1, true);
+ }
+
accent.a *= 0.7;
}
@@ -262,27 +270,63 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->add_button(0, get_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning());
}
- bool has_connections = p_node->has_persistent_signal_connections();
- bool has_groups = p_node->has_persistent_groups();
-
- if (has_connections && has_groups) {
- item->add_button(0, get_icon("SignalsAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s).\nClick to show signals dock."));
- } else if (has_connections) {
- item->add_button(0, get_icon("Signals", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock."));
- } else if (has_groups) {
- item->add_button(0, get_icon("Groups", "EditorIcons"), BUTTON_GROUPS, false, TTR("Node is in group(s).\nClick to show groups dock."));
+ int num_connections = p_node->get_persistent_signal_connection_count();
+ int num_groups = p_node->get_persistent_group_count();
+
+ if (num_connections >= 1 && num_groups >= 1) {
+ item->add_button(
+ 0,
+ get_icon("SignalsAndGroups", "EditorIcons"),
+ BUTTON_SIGNALS,
+ false,
+ vformat(TTR("Node has %s connection(s) and %s group(s).\nClick to show signals dock."), num_connections, num_groups));
+ } else if (num_connections >= 1) {
+ item->add_button(
+ 0,
+ get_icon("Signals", "EditorIcons"),
+ BUTTON_SIGNALS,
+ false,
+ vformat(TTR("Node has %s connection(s).\nClick to show signals dock."), num_connections));
+ } else if (num_groups >= 1) {
+ item->add_button(
+ 0,
+ get_icon("Groups", "EditorIcons"),
+ BUTTON_GROUPS,
+ false,
+ vformat(TTR("Node is in %s group(s).\nClick to show groups dock."), num_groups));
}
}
if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- item->set_tooltip(0, TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class());
- } else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) {
+ String tooltip = TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class();
+ if (p_node->get_editor_description() != String()) {
+ tooltip += "\n\n" + p_node->get_editor_description();
+ }
+
+ item->set_tooltip(0, tooltip);
+ } else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) {
item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- item->set_tooltip(0, TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class());
+
+ String tooltip = TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class();
+ if (p_node->get_editor_description() != String()) {
+ tooltip += "\n\n" + p_node->get_editor_description();
+ }
+
+ item->set_tooltip(0, tooltip);
} else {
- item->set_tooltip(0, String(p_node->get_name()) + "\n" + TTR("Type:") + " " + p_node->get_class());
+ StringName type = EditorNode::get_singleton()->get_object_custom_type_name(p_node);
+ if (type == StringName()) {
+ type = p_node->get_class();
+ }
+
+ String tooltip = TTR("Type:") + " " + type;
+ if (p_node->get_editor_description() != String()) {
+ tooltip += "\n\n" + p_node->get_editor_description();
+ }
+
+ item->set_tooltip(0, tooltip);
}
if (can_open_instance && undo_redo) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes
@@ -290,9 +334,12 @@ 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());
+ if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) {
+ item->set_button_color(0, item->get_button_count(0) - 1, Color(1, 1, 1, 0.5));
+ }
}
if (p_node->is_class("CanvasItem")) {
@@ -981,6 +1028,17 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
return true;
}
+ if (String(d["type"]) == "script_list_element") {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(d["script_list_element"]);
+ if (se) {
+ String sp = se->get_edited_resource()->get_path();
+ if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(sp))) {
+ tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
+ return true;
+ }
+ }
+ }
+
return String(d["type"]) == "nodes";
}
void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
@@ -1018,6 +1076,16 @@ void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data,
emit_signal("files_dropped", files, np, section);
}
}
+
+ if (String(d["type"]) == "script_list_element") {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(d["script_list_element"]);
+ if (se) {
+ String sp = se->get_edited_resource()->get_path();
+ if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(sp))) {
+ emit_signal("script_dropped", sp, np);
+ }
+ }
+ }
}
void SceneTreeEditor::_rmb_select(const Vector2 &p_pos) {
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 61cb59ce6f..b216be3b59 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -37,9 +37,7 @@
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class SceneTreeEditor : public Control {
GDCLASS(SceneTreeEditor, Control);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ed9a24311d..ffb3f5feab 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -34,6 +34,7 @@
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/script_language.h"
+#include "core/string_builder.h"
#include "editor/create_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
@@ -44,6 +45,23 @@ void ScriptCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ String lang = ScriptServer::get_language(i)->get_name();
+ Ref<Texture> lang_icon = get_icon(lang, "EditorIcons");
+ if (lang_icon.is_valid()) {
+ language_menu->set_item_icon(i, lang_icon);
+ }
+ }
+ String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
+ Ref<Texture> last_lang_icon;
+ if (!last_lang.empty()) {
+ last_lang_icon = get_icon(last_lang, "EditorIcons");
+ } else {
+ last_lang_icon = language_menu->get_item_icon(default_language);
+ }
+ if (last_lang_icon.is_valid()) {
+ language_menu->set_icon(last_lang_icon);
+ }
path_button->set_icon(get_icon("Folder", "EditorIcons"));
parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
parent_search_button->set_icon(get_icon("ClassList", "EditorIcons"));
@@ -221,16 +239,22 @@ void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
void ScriptCreateDialog::_template_changed(int p_template) {
- String selected_template = p_template == 0 ? "" : template_menu->get_item_text(template_menu->get_selected());
+ String selected_template = p_template == 0 ? "" : template_menu->get_item_text(p_template);
EditorSettings::get_singleton()->set_project_metadata("script_setup", "last_selected_template", selected_template);
if (p_template == 0) {
//default
script_template = "";
return;
}
- String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension();
- String name = template_list[p_template - 1] + "." + ext;
- script_template = EditorSettings::get_singleton()->get_script_templates_dir().plus_file(name);
+ int selected_id = template_menu->get_selected_id();
+
+ for (int i = 0; i < template_list.size(); i++) {
+ const ScriptTemplateInfo &sinfo = template_list[i];
+ if (sinfo.id == selected_id) {
+ script_template = sinfo.dir.plus_file(sinfo.name + "." + sinfo.extension);
+ break;
+ }
+ }
}
void ScriptCreateDialog::ok_pressed() {
@@ -351,23 +375,77 @@ void ScriptCreateDialog::_lang_changed(int l) {
bool use_templates = language->is_using_templates();
template_menu->set_disabled(!use_templates);
template_menu->clear();
- if (use_templates) {
- template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+ if (use_templates) {
+ _update_script_templates(language->get_extension());
String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
String last_template = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_template", "");
template_menu->add_item(TTR("Default"));
+
+ ScriptTemplateInfo *templates = template_list.ptrw();
+
+ Vector<String> origin_names;
+ origin_names.push_back(TTR("Project"));
+ origin_names.push_back(TTR("Editor"));
+ int cur_origin = -1;
+
+ // Populate script template items previously sorted and now grouped by origin
for (int i = 0; i < template_list.size(); i++) {
- String s = template_list[i].capitalize();
- template_menu->add_item(s);
- if (language_menu->get_item_text(language_menu->get_selected()) == last_lang && last_template == s) {
- template_menu->select(i + 1);
+
+ if (int(templates[i].origin) != cur_origin) {
+ template_menu->add_separator();
+
+ String origin_name = origin_names[templates[i].origin];
+
+ int last_index = template_menu->get_item_count() - 1;
+ template_menu->set_item_text(last_index, origin_name);
+
+ cur_origin = templates[i].origin;
}
+ String item_name = templates[i].name.capitalize();
+ template_menu->add_item(item_name);
+
+ int new_id = template_menu->get_item_count() - 1;
+ templates[i].id = new_id;
}
- } else {
+ // Disable overridden
+ for (Map<String, Vector<int> >::Element *E = template_overrides.front(); E; E = E->next()) {
+ const Vector<int> &overrides = E->get();
+
+ if (overrides.size() == 1) {
+ continue; // doesn't override anything
+ }
+ const ScriptTemplateInfo &extended = template_list[overrides[0]];
+
+ StringBuilder override_info;
+ override_info += TTR("Overrides");
+ override_info += ": ";
+ for (int i = 1; i < overrides.size(); i++) {
+ const ScriptTemplateInfo &overridden = template_list[overrides[i]];
+
+ int disable_index = template_menu->get_item_index(overridden.id);
+ template_menu->set_item_disabled(disable_index, true);
+
+ override_info += origin_names[overridden.origin];
+ if (i < overrides.size() - 1) {
+ override_info += ", ";
+ }
+ }
+ template_menu->set_item_icon(extended.id, get_icon("Override", "EditorIcons"));
+ template_menu->get_popup()->set_item_tooltip(extended.id, override_info.as_string());
+ }
+ // Reselect last selected template
+ for (int i = 0; i < template_menu->get_item_count(); i++) {
+ const String &ti = template_menu->get_item_text(i);
+ if (language_menu->get_item_text(language_menu->get_selected()) == last_lang && last_template == ti) {
+ template_menu->select(i);
+ break;
+ }
+ }
+ } else {
template_menu->add_item(TTR("N/A"));
script_template = "";
}
@@ -379,6 +457,41 @@ void ScriptCreateDialog::_lang_changed(int l) {
_update_dialog();
}
+void ScriptCreateDialog::_update_script_templates(const String &p_extension) {
+
+ template_list.clear();
+ template_overrides.clear();
+
+ Vector<String> dirs;
+
+ // Ordered from local to global for correct override mechanism
+ dirs.push_back(EditorSettings::get_singleton()->get_project_script_templates_dir());
+ dirs.push_back(EditorSettings::get_singleton()->get_script_templates_dir());
+
+ for (int i = 0; i < dirs.size(); i++) {
+
+ Vector<String> list = EditorSettings::get_singleton()->get_script_templates(p_extension, dirs[i]);
+
+ for (int j = 0; j < list.size(); j++) {
+ ScriptTemplateInfo sinfo;
+ sinfo.origin = ScriptOrigin(i);
+ sinfo.dir = dirs[i];
+ sinfo.name = list[j];
+ sinfo.extension = p_extension;
+ template_list.push_back(sinfo);
+
+ if (!template_overrides.has(sinfo.name)) {
+ Vector<int> overrides;
+ overrides.push_back(template_list.size() - 1); // first one
+ template_overrides.insert(sinfo.name, overrides);
+ } else {
+ Vector<int> &overrides = template_overrides[sinfo.name];
+ overrides.push_back(template_list.size() - 1);
+ }
+ }
+ }
+}
+
void ScriptCreateDialog::_built_in_pressed() {
if (internal->is_pressed()) {
@@ -671,13 +784,13 @@ ScriptCreateDialog::ScriptCreateDialog() {
gc->add_child(l);
gc->add_child(language_menu);
- int default_lang = 0;
+ default_language = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
String lang = ScriptServer::get_language(i)->get_name();
language_menu->add_item(lang);
if (lang == "GDScript") {
- default_lang = i;
+ default_language = i;
}
}
@@ -691,8 +804,8 @@ ScriptCreateDialog::ScriptCreateDialog() {
}
}
} else {
- language_menu->select(default_lang);
- current_language = default_lang;
+ language_menu->select(default_language);
+ current_language = default_language;
}
language_menu->connect("item_selected", this, "_lang_changed");
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 288b8f604b..31cf2478cf 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -76,9 +76,27 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_built_in;
bool built_in_enabled;
int current_language;
+ int default_language;
bool re_check_path;
+
+ enum ScriptOrigin {
+ SCRIPT_ORIGIN_PROJECT,
+ SCRIPT_ORIGIN_EDITOR,
+ };
+ struct ScriptTemplateInfo {
+ int id;
+ ScriptOrigin origin;
+ String dir;
+ String name;
+ String extension;
+ };
+
String script_template;
- Vector<String> template_list;
+ Vector<ScriptTemplateInfo> template_list;
+ Map<String, Vector<int> > template_overrides; // name : indices
+
+ void _update_script_templates(const String &p_extension);
+
String base_type;
void _path_hbox_sorted();
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 8fd1064427..6ba507fb9c 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -33,6 +33,7 @@
#include "core/io/marshalls.h"
#include "core/project_settings.h"
#include "core/ustring.h"
+#include "editor_network_profiler.h"
#include "editor_node.h"
#include "editor_profiler.h"
#include "editor_settings.h"
@@ -201,6 +202,21 @@ void ScriptEditorDebugger::debug_copy() {
OS::get_singleton()->set_clipboard(msg);
}
+void ScriptEditorDebugger::debug_skip_breakpoints() {
+ skip_breakpoints_value = !skip_breakpoints_value;
+ if (skip_breakpoints_value)
+ skip_breakpoints->set_icon(get_icon("DebugSkipBreakpointsOn", "EditorIcons"));
+ else
+ skip_breakpoints->set_icon(get_icon("DebugSkipBreakpointsOff", "EditorIcons"));
+
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("set_skip_breakpoints");
+ msg.push_back(skip_breakpoints_value);
+ ppeer->put_var(msg);
+ }
+}
+
void ScriptEditorDebugger::debug_next() {
ERR_FAIL_COND(!breaked);
@@ -383,6 +399,83 @@ void ScriptEditorDebugger::_scene_tree_request() {
ppeer->put_var(msg);
}
+/// Populates inspect_scene_tree recursively given data in nodes.
+/// Nodes is an array containing 4 elements for each node, it follows this pattern:
+/// nodes[i] == number of direct children of this node
+/// nodes[i + 1] == node name
+/// nodes[i + 2] == node class
+/// nodes[i + 3] == node instance id
+///
+/// Returns the number of items parsed in nodes from current_index.
+///
+/// Given a nodes array like [R,A,B,C,D,E] the following Tree will be generated, assuming
+/// filter is an empty String, R and A child count are 2, B is 1 and C, D and E are 0.
+///
+/// R
+/// |-A
+/// | |-B
+/// | | |-C
+/// | |
+/// | |-D
+/// |
+/// |-E
+///
+int ScriptEditorDebugger::_update_scene_tree(TreeItem *parent, const Array &nodes, int current_index) {
+ String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter();
+ String item_text = nodes[current_index + 1];
+ bool keep = filter.is_subsequence_ofi(item_text);
+
+ TreeItem *item = inspect_scene_tree->create_item(parent);
+ item->set_text(0, item_text);
+ ObjectID id = ObjectID(nodes[current_index + 3]);
+ Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(nodes[current_index + 2], "");
+ if (icon.is_valid()) {
+ item->set_icon(0, icon);
+ }
+ item->set_metadata(0, id);
+
+ if (id == inspected_object_id) {
+ TreeItem *cti = item->get_parent();
+ while (cti) {
+ cti->set_collapsed(false);
+ cti = cti->get_parent();
+ }
+ item->select(0);
+ }
+
+ // Set current item as collapsed if necessary
+ if (parent) {
+ if (!unfold_cache.has(id)) {
+ item->set_collapsed(true);
+ }
+ }
+
+ int children_count = nodes[current_index];
+ // Tracks the total number of items parsed in nodes, this is used to skips nodes that
+ // are not direct children of the current node since we can't know in advance the total
+ // number of children, direct and not, of a node without traversing the nodes array previously.
+ // Keeping track of this allows us to build our remote scene tree by traversing the node
+ // array just once.
+ int items_count = 1;
+ for (int i = 0; i < children_count; i++) {
+ // Called for each direct child of item.
+ // Direct children of current item might not be adjacent so items_count must
+ // be incremented by the number of items parsed until now, otherwise we would not
+ // be able to access the next child of the current item.
+ // items_count is multiplied by 4 since that's the number of elements in the nodes
+ // array needed to represent a single node.
+ items_count += _update_scene_tree(item, nodes, current_index + items_count * 4);
+ }
+
+ // If item has not children and should not be kept delete it
+ if (!keep && !item->get_children() && parent) {
+ parent->remove_child(item);
+ memdelete(item);
+ }
+
+ return items_count;
+}
+
void ScriptEditorDebugger::_video_mem_request() {
ERR_FAIL_COND(connection.is_null());
@@ -455,48 +548,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
updating_scene_tree = true;
- for (int i = 0; i < p_data.size(); i += 4) {
-
- TreeItem *p;
- int level = p_data[i];
- if (level == 0) {
- p = NULL;
- } else {
- ERR_CONTINUE(!lv.has(level - 1));
- p = lv[level - 1];
- }
+ _update_scene_tree(NULL, p_data, 0);
- TreeItem *it = inspect_scene_tree->create_item(p);
-
- ObjectID id = ObjectID(p_data[i + 3]);
-
- it->set_text(0, p_data[i + 1]);
- Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_data[i + 2], "");
- if (icon.is_valid())
- it->set_icon(0, icon);
- it->set_metadata(0, id);
-
- if (id == inspected_object_id) {
- TreeItem *cti = it->get_parent(); //ensure selected is always uncollapsed
- while (cti) {
- cti->set_collapsed(false);
- cti = cti->get_parent();
- }
- it->select(0);
- }
-
- if (p) {
- if (!unfold_cache.has(id)) {
- it->set_collapsed(true);
- }
- } else {
- if (unfold_cache.has(id)) { //reverse for root
- it->set_collapsed(true);
- }
- }
-
- lv[level] = it;
- }
updating_scene_tree = false;
le_clear->set_disabled(false);
@@ -949,7 +1002,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
profiler->add_frame_metric(metric, false);
else
profiler->add_frame_metric(metric, true);
-
+ } else if (p_msg == "network_profile") {
+ int frame_size = 6;
+ for (int i = 0; i < p_data.size(); i += frame_size) {
+ MultiplayerAPI::ProfilingInfo pi;
+ pi.node = p_data[i + 0];
+ pi.node_path = p_data[i + 1];
+ pi.incoming_rpc = p_data[i + 2];
+ pi.incoming_rset = p_data[i + 3];
+ pi.outgoing_rpc = p_data[i + 4];
+ pi.outgoing_rset = p_data[i + 5];
+ network_profiler->add_node_frame_data(pi);
+ }
+ } else if (p_msg == "network_bandwidth") {
+ network_profiler->set_bandwidth(p_data[0], p_data[1]);
} else if (p_msg == "kill_me") {
editor->call_deferred("stop_child_process");
@@ -985,14 +1051,15 @@ void ScriptEditorDebugger::_performance_draw() {
which.push_back(i);
}
- Ref<Font> graph_font = get_font("font", "TextEdit");
-
if (which.empty()) {
- perf_draw->draw_string(graph_font, Point2(0, graph_font->get_ascent()), TTR("Pick one or more items from the list to display the graph."), get_color("font_color", "Label"), perf_draw->get_size().x);
+ info_message->show();
return;
}
+ info_message->hide();
+
Ref<StyleBox> graph_sb = get_stylebox("normal", "TextEdit");
+ Ref<Font> graph_font = get_font("font", "TextEdit");
int cols = Math::ceil(Math::sqrt((float)which.size()));
int rows = Math::ceil((float)which.size() / cols);
@@ -1052,7 +1119,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
inspector->edit(variables);
-
+ skip_breakpoints->set_icon(get_icon("DebugSkipBreakpointsOff", "EditorIcons"));
copy->set_icon(get_icon("ActionCopy", "EditorIcons"));
step->set_icon(get_icon("DebugStep", "EditorIcons"));
@@ -1061,7 +1128,6 @@ void ScriptEditorDebugger::_notification(int p_what) {
forward->set_icon(get_icon("Forward", "EditorIcons"));
dobreak->set_icon(get_icon("Pause", "EditorIcons"));
docontinue->set_icon(get_icon("DebugContinue", "EditorIcons"));
- //scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
le_set->connect("pressed", this, "_live_edit_set");
le_clear->connect("pressed", this, "_live_edit_clear");
error_tree->connect("item_selected", this, "_error_selected");
@@ -1133,7 +1199,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
if (connection.is_null())
break;
- EditorNode::get_log()->add_message("** Debug Process Started **");
+ EditorNode::get_log()->add_message("--- Debugging process started ---", EditorLog::MSG_TYPE_EDITOR);
ppeer->set_stream_peer(connection);
@@ -1143,7 +1209,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
dobreak->set_disabled(false);
tabs->set_current_tab(0);
- _set_reason_text(TTR("Child Process Connected"), MESSAGE_SUCCESS);
+ _set_reason_text(TTR("Child process connected."), MESSAGE_SUCCESS);
profiler->clear();
inspect_scene_tree->clear();
@@ -1162,6 +1228,10 @@ void ScriptEditorDebugger::_notification(int p_what) {
if (profiler->is_profiling()) {
_profiler_activate(true);
}
+
+ if (network_profiler->is_profiling()) {
+ _network_profiler_activate(true);
+ }
}
}
@@ -1327,7 +1397,7 @@ void ScriptEditorDebugger::stop() {
ppeer->set_stream_peer(Ref<StreamPeer>());
if (connection.is_valid()) {
- EditorNode::get_log()->add_message("** Debug Process Stopped **");
+ EditorNode::get_log()->add_message("--- Debugging process stopped ---", EditorLog::MSG_TYPE_EDITOR);
connection.unref();
reason->set_text("");
@@ -1381,6 +1451,25 @@ void ScriptEditorDebugger::_profiler_activate(bool p_enable) {
}
}
+void ScriptEditorDebugger::_network_profiler_activate(bool p_enable) {
+
+ if (!connection.is_valid())
+ return;
+
+ if (p_enable) {
+ Array msg;
+ msg.push_back("start_network_profiling");
+ ppeer->put_var(msg);
+ print_verbose("Starting network profiling.");
+
+ } else {
+ Array msg;
+ msg.push_back("stop_network_profiling");
+ ppeer->put_var(msg);
+ print_verbose("Ending network profiling.");
+ }
+}
+
void ScriptEditorDebugger::_profiler_seeked() {
if (!connection.is_valid() || !connection->is_connected_to_host())
@@ -1754,6 +1843,10 @@ void ScriptEditorDebugger::reload_scripts() {
}
}
+bool ScriptEditorDebugger::is_skip_breakpoints() {
+ return skip_breakpoints_value;
+}
+
void ScriptEditorDebugger::_error_activated() {
TreeItem *selected = error_tree->get_selected();
@@ -1949,6 +2042,7 @@ void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected);
+ ClassDB::bind_method(D_METHOD("debug_skip_breakpoints"), &ScriptEditorDebugger::debug_skip_breakpoints);
ClassDB::bind_method(D_METHOD("debug_copy"), &ScriptEditorDebugger::debug_copy);
ClassDB::bind_method(D_METHOD("debug_next"), &ScriptEditorDebugger::debug_next);
@@ -1969,6 +2063,7 @@ void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_expand_errors_list"), &ScriptEditorDebugger::_expand_errors_list);
ClassDB::bind_method(D_METHOD("_collapse_errors_list"), &ScriptEditorDebugger::_collapse_errors_list);
ClassDB::bind_method(D_METHOD("_profiler_activate"), &ScriptEditorDebugger::_profiler_activate);
+ ClassDB::bind_method(D_METHOD("_network_profiler_activate"), &ScriptEditorDebugger::_network_profiler_activate);
ClassDB::bind_method(D_METHOD("_profiler_seeked"), &ScriptEditorDebugger::_profiler_seeked);
ClassDB::bind_method(D_METHOD("_clear_errors_list"), &ScriptEditorDebugger::_clear_errors_list);
@@ -2036,6 +2131,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
hbc->add_child(memnew(VSeparator));
+ skip_breakpoints = memnew(ToolButton);
+ hbc->add_child(skip_breakpoints);
+ skip_breakpoints->set_tooltip(TTR("Skip Breakpoints"));
+ skip_breakpoints->connect("pressed", this, "debug_skip_breakpoints");
+
+ hbc->add_child(memnew(VSeparator));
+
copy = memnew(ToolButton);
hbc->add_child(copy);
copy->set_tooltip(TTR("Copy Error"));
@@ -2046,11 +2148,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
step = memnew(ToolButton);
hbc->add_child(step);
step->set_tooltip(TTR("Step Into"));
+ step->set_shortcut(ED_GET_SHORTCUT("debugger/step_into"));
step->connect("pressed", this, "debug_step");
next = memnew(ToolButton);
hbc->add_child(next);
next->set_tooltip(TTR("Step Over"));
+ next->set_shortcut(ED_GET_SHORTCUT("debugger/step_over"));
next->connect("pressed", this, "debug_next");
hbc->add_child(memnew(VSeparator));
@@ -2058,11 +2162,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
dobreak = memnew(ToolButton);
hbc->add_child(dobreak);
dobreak->set_tooltip(TTR("Break"));
+ dobreak->set_shortcut(ED_GET_SHORTCUT("debugger/break"));
dobreak->connect("pressed", this, "debug_break");
docontinue = memnew(ToolButton);
hbc->add_child(docontinue);
docontinue->set_tooltip(TTR("Continue"));
+ docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue"));
docontinue->connect("pressed", this, "debug_continue");
back = memnew(Button);
@@ -2187,6 +2293,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
profiler->connect("break_request", this, "_profiler_seeked");
}
+ { //network profiler
+ network_profiler = memnew(EditorNetworkProfiler);
+ network_profiler->set_name(TTR("Network Profiler"));
+ tabs->add_child(network_profiler);
+ network_profiler->connect("enable_profiling", this, "_network_profiler_activate");
+ }
+
{ //monitors
HSplitContainer *hsp = memnew(HSplitContainer);
@@ -2196,11 +2309,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
perf_monitors->set_column_title(0, TTR("Monitor"));
perf_monitors->set_column_title(1, TTR("Value"));
perf_monitors->set_column_titles_visible(true);
- hsp->add_child(perf_monitors);
perf_monitors->connect("item_edited", this, "_performance_select");
+ hsp->add_child(perf_monitors);
+
perf_draw = memnew(Control);
+ perf_draw->set_clip_contents(true);
perf_draw->connect("draw", this, "_performance_draw");
hsp->add_child(perf_draw);
+
hsp->set_name(TTR("Monitors"));
hsp->set_split_offset(340 * EDSCALE);
tabs->add_child(hsp);
@@ -2234,6 +2350,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
perf_items.push_back(it);
perf_max.write[i] = 0;
}
+
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Pick one or more items from the list to display the graph."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ perf_draw->add_child(info_message);
}
{ //vmem inspect
@@ -2245,7 +2369,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_hb->add_child(memnew(Label(TTR("Total:") + " ")));
vmem_total = memnew(LineEdit);
vmem_total->set_editable(false);
- vmem_total->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
+ vmem_total->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
vmem_hb->add_child(vmem_total);
vmem_refresh = memnew(ToolButton);
vmem_hb->add_child(vmem_refresh);
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 05dcab0f80..cc284476c0 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -50,6 +50,7 @@ class TreeItem;
class HSplitContainer;
class ItemList;
class EditorProfiler;
+class EditorNetworkProfiler;
class ScriptEditorDebuggerInspectedObject;
@@ -109,12 +110,15 @@ class ScriptEditorDebugger : public Control {
bool hide_on_stop;
bool enable_external_editor;
+
+ bool skip_breakpoints_value = false;
Ref<Script> stack_script;
TabContainer *tabs;
Label *reason;
+ Button *skip_breakpoints;
Button *copy;
Button *step;
Button *next;
@@ -131,6 +135,7 @@ class ScriptEditorDebugger : public Control {
Tree *perf_monitors;
Control *perf_draw;
+ Label *info_message;
Tree *vmem_tree;
Button *vmem_refresh;
@@ -152,6 +157,7 @@ class ScriptEditorDebugger : public Control {
Map<String, int> res_path_cache;
EditorProfiler *profiler;
+ EditorNetworkProfiler *network_profiler;
EditorNode *editor;
@@ -173,6 +179,7 @@ class ScriptEditorDebugger : public Control {
void _set_reason_text(const String &p_reason, MessageType p_type);
void _scene_tree_property_select_object(ObjectID p_object);
void _scene_tree_property_value_edited(const String &p_prop, const Variant &p_value);
+ int _update_scene_tree(TreeItem *parent, const Array &nodes, int current_index);
void _video_mem_request();
@@ -195,6 +202,8 @@ class ScriptEditorDebugger : public Control {
void _profiler_activate(bool p_enable);
void _profiler_seeked();
+ void _network_profiler_activate(bool p_enable);
+
void _paused();
void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj);
@@ -218,6 +227,7 @@ public:
void unpause();
void stop();
+ void debug_skip_breakpoints();
void debug_copy();
void debug_next();
@@ -255,6 +265,8 @@ public:
void reload_scripts();
+ bool is_skip_breakpoints();
+
virtual Size2 get_minimum_size() const;
ScriptEditorDebugger(EditorNode *p_editor = NULL);
~ScriptEditorDebugger();
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index b4643231d7..c9c1f9c3e0 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -110,7 +110,7 @@ void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) {
}
void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_name) {
- EditorNode::get_log()->add_message(p_name);
+ EditorNode::get_log()->add_message(p_name, EditorLog::MSG_TYPE_EDITOR);
}
void EditorSettingsDialog::_notification(int p_what) {
@@ -151,7 +151,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("editor/undo", p_event)) {
String action = undo_redo->get_current_action_name();
if (action != "")
- EditorNode::get_log()->add_message("UNDO: " + action);
+ EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
undo_redo->undo();
handled = true;
}
@@ -159,7 +159,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
undo_redo->redo();
String action = undo_redo->get_current_action_name();
if (action != "")
- EditorNode::get_log()->add_message("REDO: " + action);
+ EditorNode::get_log()->add_message("Redo: " + action, EditorLog::MSG_TYPE_EDITOR);
handled = true;
}
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index cbfd0f3742..9f940c46e6 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -36,6 +36,7 @@
#include "scene/3d/baked_lightmap.h"
#include "scene/3d/collision_polygon.h"
#include "scene/3d/collision_shape.h"
+#include "scene/3d/cpu_particles.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/light.h"
#include "scene/3d/listener.h"
@@ -171,8 +172,8 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base, bool p_hidde
instance = VS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_id(instance, p_base->get_instance_id());
- if (skeleton.is_valid())
- VS::get_singleton()->instance_attach_skeleton(instance, skeleton);
+ if (skin_reference.is_valid())
+ VS::get_singleton()->instance_attach_skeleton(instance, skin_reference->get_skeleton());
if (extra_margin)
VS::get_singleton()->instance_set_extra_visibility_margin(instance, 1);
VS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance, VS::SHADOW_CASTING_SETTING_OFF);
@@ -180,14 +181,14 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base, bool p_hidde
VS::get_singleton()->instance_set_layer_mask(instance, layer); //gizmos are 26
}
-void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const RID &p_skeleton, const Ref<Material> &p_material) {
+void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const Ref<SkinReference> &p_skin_reference, const Ref<Material> &p_material) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
ins.billboard = p_billboard;
ins.mesh = p_mesh;
- ins.skeleton = p_skeleton;
+ ins.skin_reference = p_skin_reference;
ins.material = p_material;
if (valid) {
ins.create_instance(spatial_node, hidden);
@@ -782,9 +783,10 @@ Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
LightSpatialGizmoPlugin::LightSpatialGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2));
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.7));
- create_material("lines", gizmo_color);
+ create_material("lines_primary", gizmo_color);
+ create_material("lines_secondary", gizmo_color * Color(1, 1, 1, 0.35));
create_material("lines_billboard", gizmo_color, true);
create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
@@ -936,7 +938,7 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
if (Object::cast_to<DirectionalLight>(light)) {
- Ref<Material> material = get_material("lines", p_gizmo);
+ Ref<Material> material = get_material("lines_primary", p_gizmo);
Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
const int arrow_points = 7;
@@ -974,31 +976,39 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
if (Object::cast_to<OmniLight>(light)) {
- Ref<Material> material = get_material("lines_billboard", p_gizmo);
- Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
+ // Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
+ const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
+ const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
+ const Ref<Material> icon = get_material("light_omni_icon", p_gizmo);
OmniLight *on = Object::cast_to<OmniLight>(light);
-
- float r = on->get_param(Light::PARAM_RANGE);
-
+ const float r = on->get_param(Light::PARAM_RANGE);
Vector<Vector3> points;
+ Vector<Vector3> points_billboard;
- for (int i = 0; i <= 360; i++) {
+ for (int i = 0; i < 120; i++) {
- float ra = Math::deg2rad((float)i);
- float rb = Math::deg2rad((float)i + 1);
- Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
- Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
+ // Create a circle
+ const float ra = Math::deg2rad((float)(i * 3));
+ const float rb = Math::deg2rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
- /*points.push_back(Vector3(a.x,0,a.y));
- points.push_back(Vector3(b.x,0,b.y));
- points.push_back(Vector3(0,a.x,a.y));
- points.push_back(Vector3(0,b.x,b.y));*/
+ // Draw axis-aligned circles
+ points.push_back(Vector3(a.x, 0, a.y));
+ points.push_back(Vector3(b.x, 0, b.y));
+ points.push_back(Vector3(0, a.x, a.y));
+ points.push_back(Vector3(0, b.x, b.y));
points.push_back(Vector3(a.x, a.y, 0));
points.push_back(Vector3(b.x, b.y, 0));
+
+ // Draw a billboarded circle
+ points_billboard.push_back(Vector3(a.x, a.y, 0));
+ points_billboard.push_back(Vector3(b.x, b.y, 0));
}
- p_gizmo->add_lines(points, material, true);
+ p_gizmo->add_lines(points, lines_material, true);
+ p_gizmo->add_lines(points_billboard, lines_billboard_material, true);
p_gizmo->add_unscaled_billboard(icon, 0.05);
Vector<Vector3> handles;
@@ -1008,40 +1018,44 @@ void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
if (Object::cast_to<SpotLight>(light)) {
- Ref<Material> material = get_material("lines", p_gizmo);
- Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
+ const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
+ const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
+ const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
- Vector<Vector3> points;
+ Vector<Vector3> points_primary;
+ Vector<Vector3> points_secondary;
SpotLight *sl = Object::cast_to<SpotLight>(light);
float r = sl->get_param(Light::PARAM_RANGE);
float w = r * Math::sin(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE)));
float d = r * Math::cos(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE)));
- for (int i = 0; i < 360; i++) {
-
- float ra = Math::deg2rad((float)i);
- float rb = Math::deg2rad((float)i + 1);
- Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
- Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
+ for (int i = 0; i < 120; i++) {
- points.push_back(Vector3(a.x, a.y, -d));
- points.push_back(Vector3(b.x, b.y, -d));
+ // Draw a circle
+ const float ra = Math::deg2rad((float)(i * 3));
+ const float rb = Math::deg2rad((float)((i + 1) * 3));
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
+ const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
- if (i % 90 == 0) {
+ points_primary.push_back(Vector3(a.x, a.y, -d));
+ points_primary.push_back(Vector3(b.x, b.y, -d));
- points.push_back(Vector3(a.x, a.y, -d));
- points.push_back(Vector3());
+ if (i % 15 == 0) {
+ // Draw 8 lines from the cone origin to the sides of the circle
+ points_secondary.push_back(Vector3(a.x, a.y, -d));
+ points_secondary.push_back(Vector3());
}
}
- points.push_back(Vector3(0, 0, -r));
- points.push_back(Vector3());
+ points_primary.push_back(Vector3(0, 0, -r));
+ points_primary.push_back(Vector3());
- p_gizmo->add_lines(points, material);
+ p_gizmo->add_lines(points_primary, material_primary);
+ p_gizmo->add_lines(points_secondary, material_secondary);
- float ra = 16 * Math_PI * 2.0 / 64.0;
- Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
+ const float ra = 16 * Math_PI * 2.0 / 64.0;
+ const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, -r));
@@ -1788,7 +1802,7 @@ void SkeletonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
}
Ref<ArrayMesh> m = surface_tool->commit();
- p_gizmo->add_mesh(m, false, skel->get_skeleton());
+ p_gizmo->add_mesh(m, false, skel->register_skin(Ref<Skin>()));
}
////
@@ -2036,8 +2050,11 @@ PortalSpatialGizmo::PortalSpatialGizmo(Portal *p_portal) {
RayCastSpatialGizmoPlugin::RayCastSpatialGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
+ const float gizmo_value = gizmo_color.get_v();
+ const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
+ create_material("shape_material_disabled", gizmo_color_disabled);
}
bool RayCastSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
@@ -2063,7 +2080,8 @@ void RayCastSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
lines.push_back(Vector3());
lines.push_back(raycast->get_cast_to());
- Ref<SpatialMaterial> material = get_material("shape_material", p_gizmo);
+ const Ref<SpatialMaterial> material =
+ get_material(raycast->is_enabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
@@ -2415,6 +2433,33 @@ void VisibilityNotifierGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
////
+CPUParticlesGizmoPlugin::CPUParticlesGizmoPlugin() {
+ create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoCPUParticles", "EditorIcons"));
+}
+
+bool CPUParticlesGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ return Object::cast_to<CPUParticles>(p_spatial) != NULL;
+}
+
+String CPUParticlesGizmoPlugin::get_name() const {
+ return "CPUParticles";
+}
+
+int CPUParticlesGizmoPlugin::get_priority() const {
+ return -1;
+}
+
+bool CPUParticlesGizmoPlugin::is_selectable_when_hidden() const {
+ return true;
+}
+
+void CPUParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+ Ref<Material> icon = get_material("particles_icon", p_gizmo);
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
+}
+
+////
+
ParticlesGizmoPlugin::ParticlesGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
create_material("particles_material", gizmo_color);
@@ -3080,8 +3125,11 @@ void BakedIndirectLightGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
////
CollisionShapeSpatialGizmoPlugin::CollisionShapeSpatialGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
+ const float gizmo_value = gizmo_color.get_v();
+ const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
+ create_material("shape_material_disabled", gizmo_color_disabled);
create_handle_material("handles");
}
@@ -3404,7 +3452,8 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
if (s.is_null())
return;
- Ref<Material> material = get_material("shape_material", p_gizmo);
+ const Ref<Material> material =
+ get_material(!cs->is_disabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
Ref<Material> handles_material = get_material("handles");
if (Object::cast_to<SphereShape>(*s)) {
@@ -3676,7 +3725,7 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
Ref<ConcavePolygonShape> cs2 = s;
Ref<ArrayMesh> mesh = cs2->get_debug_mesh();
- p_gizmo->add_mesh(mesh, false, RID(), material);
+ p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material);
}
if (Object::cast_to<RayShape>(*s)) {
@@ -3698,15 +3747,18 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
Ref<HeightMapShape> hms = s;
Ref<ArrayMesh> mesh = hms->get_debug_mesh();
- p_gizmo->add_mesh(mesh, false, RID(), material);
+ p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material);
}
}
/////
CollisionPolygonSpatialGizmoPlugin::CollisionPolygonSpatialGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
+ const float gizmo_value = gizmo_color.get_v();
+ const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
+ create_material("shape_material_disabled", gizmo_color_disabled);
}
bool CollisionPolygonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
@@ -3742,7 +3794,8 @@ void CollisionPolygonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
lines.push_back(Vector3(points[i].x, points[i].y, -depth));
}
- Ref<Material> material = get_material("shape_material", p_gizmo);
+ const Ref<Material> material =
+ get_material(!polygon->is_disabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 3661df4bad..317ea0c570 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -249,6 +249,18 @@ public:
VisibilityNotifierGizmoPlugin();
};
+class CPUParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
+ GDCLASS(CPUParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
+
+public:
+ bool has_gizmo(Spatial *p_spatial);
+ String get_name() const;
+ int get_priority() const;
+ bool is_selectable_when_hidden() const;
+ void redraw(EditorSpatialGizmo *p_gizmo);
+ CPUParticlesGizmoPlugin();
+};
+
class ParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
GDCLASS(ParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
diff --git a/editor/translations/af.po b/editor/translations/af.po
index 9cce062127..5c4eb539a8 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -61,7 +61,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Bevry"
@@ -137,6 +136,31 @@ msgstr "Anim Verander Roep"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Verander Waarde"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Verander Oorgang"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Verander Transform"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Verander Waarde"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Verander Roep"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Verander Anim Lente"
@@ -647,17 +671,18 @@ msgid "Line Number:"
msgstr "Reël Nommer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Het %d verskynsel(s) vervang."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Geen Pasmaats"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Het %d verskynsel(s) vervang."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Pas Letterkas"
@@ -896,8 +921,7 @@ msgstr "Gunstelinge:"
msgid "Recent:"
msgstr "Onlangse:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1001,7 +1025,7 @@ msgstr ""
"reg kan werk.\n"
"Verwyder die lêers in elk geval? (geen ontdoen)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "Kan nie verwyder nie:\n"
@@ -1040,7 +1064,7 @@ msgstr "Skrap %d item(s) permanent? (Geen ontdoen!)"
msgid "Show Dependencies"
msgstr "Afhanklikhede"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Verweerde Hulpbron Verkenner"
@@ -1130,14 +1154,16 @@ msgid "License"
msgstr "Lisensie"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Derdeparty-lisensie"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Enjin maak staat op 'n nommer derdeparty vry en oopbron biblioteke, "
@@ -1158,7 +1184,8 @@ msgid "Licenses"
msgstr "Lisensies"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Fout met oopmaak, die pakket-lêer is nie in zip format nie."
#: editor/editor_asset_installer.cpp
@@ -1176,7 +1203,6 @@ msgid "Success!"
msgstr "Sukses!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installeer"
@@ -1668,12 +1694,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1741,7 +1766,7 @@ msgstr "Open 'n Lêer"
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Verfris"
@@ -1792,7 +1817,7 @@ msgstr "Gaan Vorentoe"
msgid "Go Up"
msgstr "Gaan Op"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Wissel Versteekte Lêers"
@@ -1818,27 +1843,32 @@ msgstr "Skuif Gunsteling Af"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Voorskou:"
+msgid "Go to previous folder."
+msgstr "Gaan na ouer vouer"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Skep Vouer"
+msgid "Go to next folder."
+msgstr "Gaan na ouer vouer"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Gaan na ouer vouer"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Deursoek Klasse"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Kon nie vouer skep nie."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Wissel Versteekte Lêers"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2097,6 +2127,10 @@ msgstr "Vee uit"
msgid "Clear Output"
msgstr "Afvoer:"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2394,6 +2428,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Open Lêer(s)"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2489,6 +2532,11 @@ msgstr ""
msgid "Close Tab"
msgstr "Maak Toe"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Maak Toe"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2543,6 +2591,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Verwyder Seleksie"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2570,6 +2623,10 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr ""
@@ -2580,14 +2637,6 @@ msgid "Save All Scenes"
msgstr "Stoor As"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2617,16 +2666,20 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2634,11 +2687,16 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "Projek Stigters"
-#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Verweerde Hulpbron Verkenner"
+
+#: editor/editor_node.cpp
msgid "Quit to Project List"
msgstr ""
@@ -2715,13 +2773,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Oorgange"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2736,14 +2795,6 @@ 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 ""
@@ -2765,14 +2816,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2780,12 +2831,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Soek"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3058,6 +3110,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Lede"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3221,7 +3278,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3238,6 +3295,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3299,12 +3360,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3318,14 +3377,20 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kan nie verwyder nie:\n"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
-msgstr ""
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "Fout terwyl laai:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3412,20 +3477,12 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Gunstelinge:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3461,11 +3518,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3531,6 +3588,11 @@ msgstr "Dupliseer"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Stoor Hulpbron As..."
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3600,6 +3662,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Skep Vouer"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3668,6 +3735,14 @@ msgid "Search complete"
msgstr "Deursoek Teks"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "AutoLaai '%s' bestaan reeds!"
@@ -3677,12 +3752,22 @@ msgstr "AutoLaai '%s' bestaan reeds!"
msgid "Invalid group name."
msgstr "Ongeldige naam."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Hernoem Oudio-Bus"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Skrap"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3695,12 +3780,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Afhanklikheid Bewerker"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3910,7 +3996,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4691,10 +4777,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4707,14 +4789,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kan nie verwyder nie:\n"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4755,6 +4866,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Installeer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4784,13 +4900,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Ek sien..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4798,7 +4917,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4811,7 +4930,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4823,6 +4942,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Laai"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4873,31 +4997,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Skep Vouer"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Verwyder ongeldige sleutels"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Skep Vouer"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Verwyder ongeldige sleutels"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4980,6 +5108,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Vee uit"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -5010,6 +5143,7 @@ msgid "Zoom Reset"
msgstr "Zoem Uit"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5030,14 +5164,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Wissel Modus"
@@ -5062,6 +5199,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5078,11 +5216,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5095,6 +5228,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5307,16 +5445,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5634,14 +5762,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5725,19 +5845,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6072,7 +6196,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6181,12 +6304,7 @@ msgstr "Leêr word gebêre:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Kon nie vouer skep nie."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Kon nie vouer skep nie."
#: editor/plugins/script_editor_plugin.cpp
@@ -6215,7 +6333,7 @@ msgid "Error Importing"
msgstr "Fout terwyl laai:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6301,6 +6419,11 @@ msgid "Open..."
msgstr "Oop"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Afhanklikheid Bewerker"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6340,11 +6463,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6434,6 +6557,10 @@ msgstr ""
msgid "Search Results"
msgstr "Deursoek Hulp"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6506,6 +6633,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6541,26 +6669,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Wissel Modus"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Gaan na Volgende Stap"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Gaan na Vorige Stap"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Hernoem AutoLaai"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6581,6 +6689,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skaal Seleksie"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6597,32 +6710,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Vind"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Gaan na Volgende Stap"
+msgid "Toggle Bookmark"
+msgstr "Wissel Modus"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Gaan na Vorige Stap"
+msgid "Go to Next Bookmark"
+msgstr "Gaan na Volgende Stap"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Gaan na Vorige Stap"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Vind"
+msgid "Remove All Bookmarks"
+msgstr "Hernoem AutoLaai"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6635,9 +6753,24 @@ msgid "Go to Line..."
msgstr "Gaan na Reël"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Gaan na Volgende Stap"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Gaan na Vorige Stap"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6816,7 +6949,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6872,8 +7009,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Verander Anim Lente"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6926,7 +7064,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6937,27 +7075,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7001,26 +7119,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7075,7 +7173,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7380,10 +7478,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7472,11 +7566,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7585,14 +7679,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7606,8 +7692,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7909,6 +7995,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7991,6 +8081,11 @@ msgid "Duplicate Nodes"
msgstr "Anim Dupliseer Sleutels"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Skrap"
@@ -8013,6 +8108,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Skep Vouer"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Skep Vouer"
@@ -8090,6 +8190,22 @@ msgid "Color uniform."
msgstr "Anim Verander Transform"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8097,10 +8213,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8190,7 +8340,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8198,7 +8348,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8210,7 +8360,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8227,7 +8377,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8296,11 +8446,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8316,7 +8466,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8327,7 +8477,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8336,7 +8486,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8344,11 +8494,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8389,11 +8539,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8403,7 +8557,7 @@ msgstr "Skep Intekening"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8421,15 +8575,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8481,7 +8635,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8496,6 +8650,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8509,19 +8667,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8530,7 +8688,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8539,14 +8697,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8591,47 +8749,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8798,6 +8963,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8948,6 +9117,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Kan nie '%s' oopmaak nie."
@@ -9018,8 +9195,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9039,8 +9216,9 @@ msgid "Project Manager"
msgstr "Projek Bestuurder"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projek Stigters"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9064,10 +9242,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9405,6 +9579,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9457,14 +9635,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9757,6 +9927,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9802,6 +9976,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Skep Nuwe"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9877,19 +10056,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9983,6 +10162,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10012,7 +10195,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10174,6 +10357,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10588,10 +10775,31 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ongeldige naam. Dit moet nie met bestaande ingeboude tiepename bots nie."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Skep Nuwe"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Skep Nuwe"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Skep Intekening"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10778,10 +10986,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Lede"
@@ -11526,22 +11730,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11554,6 +11742,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11571,6 +11763,18 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Kon nie vouer skep nie."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Voorskou:"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Skep Vouer"
+
+#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "Kon nie vouer skep nie."
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 5f9f0aee4c..341617c1b8 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -28,12 +28,14 @@
# DiscoverSquishy <noaimi@discoversquishy.me>, 2019.
# ButterflyOfFire <ButterflyOfFire@protonmail.com>, 2019.
# PhoenixHO <oussamahaddouche0@gmail.com>, 2019.
+# orcstudio <orcstudio@orcstudio.org>, 2019.
+# Rachid Graphicos <graphicos1d@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:47+0000\n"
-"Last-Translator: PhoenixHO <oussamahaddouche0@gmail.com>\n"
+"PO-Revision-Date: 2019-08-15 10:23+0000\n"
+"Last-Translator: Rachid Graphicos <graphicos1d@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -42,7 +44,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.8-dev\n"
+"X-Generator: Weblate 3.8\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -84,7 +86,6 @@ msgid "On call to '%s':"
msgstr "عند الأستدعاء إلى '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "مجاني/Ùارغ"
@@ -154,6 +155,31 @@ msgid "Anim Change Call"
msgstr "نداء تغيير التحريك"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "تغيير وقت الإطار الرئيسي للحركة"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "تغيير المقطع الإنتقالي"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "تحويل تغيير التحريك"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "تغيير قيمة الإطار الأساسي للحركة"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "نداء تغيير التحريك"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "تعديل طول عرض الحركة"
@@ -469,7 +495,7 @@ 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 ""
+msgstr "تحديد الكل"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -653,17 +679,18 @@ msgid "Line Number:"
msgstr "رقم الخط:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "إستبÙدل %d حادثة(حوادث)."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "لا مطابقة"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "إستبÙدل %d حادثة(حوادث)."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "قضية تشابه"
@@ -733,9 +760,8 @@ msgid "Connect to Node:"
msgstr "صلها بالعقدة:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "لا يمكن الإتصال بالمÙضيÙ:"
+msgstr "الإتصال بالمخطوطة:"
#: editor/connections_dialog.cpp
#, fuzzy
@@ -773,9 +799,8 @@ msgid "Extra Call Arguments:"
msgstr "وسائط إستدعاء إضاÙية :"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "إعدادات الكبس"
+msgstr "إعدادات متقدمة"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -898,8 +923,7 @@ msgstr "المÙضلة:"
msgid "Recent:"
msgstr "الحالي:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1002,7 +1026,7 @@ msgstr ""
"المل٠الذي ÙŠÙمسح مطلوب من موارد أخري لكل تعمل جيداً.\n"
"إمسح علي أية حال؟ (لا رجعة)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "لا يمكن المسح:"
@@ -1039,7 +1063,7 @@ msgstr "إمسح نهائيا %d عنصر(عناصر)؟ (بلا رجعة!)"
msgid "Show Dependencies"
msgstr "التبعيات"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "متصÙØ­ الموارد أورÙان"
@@ -1128,14 +1152,16 @@ msgid "License"
msgstr "الرخصة"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "ترخيص الطر٠الثالث"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"محرك \"Godot\" يعتمد على عدد من المكتبات و المكونات البرمجية لملاك اخرين و "
@@ -1156,7 +1182,8 @@ msgid "Licenses"
msgstr "تراخيص"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "خطأ عندÙتح مل٠الحزمة بسبب أن المل٠ليس ÙÙŠ صيغة \"ZIP\"."
#: editor/editor_asset_installer.cpp
@@ -1173,7 +1200,6 @@ msgid "Success!"
msgstr "تم بشكل ناجح!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "تثبيت"
@@ -1667,12 +1693,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "إستيراد"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "تصدير"
@@ -1743,7 +1768,7 @@ msgstr "أظهر ÙÙŠ مدير الملÙات"
msgid "New Folder..."
msgstr "مجلد جديد..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "تحديث"
@@ -1794,7 +1819,7 @@ msgstr "إذهب للأمام"
msgid "Go Up"
msgstr "إذهب للأعلي"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "أظهر الملÙات المخÙية"
@@ -1819,27 +1844,33 @@ msgid "Move Favorite Down"
msgstr "حرك المÙÙضلة للأسÙÙ„"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "المجلد السابق"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "إذهب إلي المجلد السابق"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "المجلد اللاحق"
+msgid "Go to next folder."
+msgstr "إذهب إلي المجلد السابق"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "إذهب إلي المجلد السابق"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "إبحث ÙÙŠ الأصناÙ"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "لا يمكن إنشاء المجلد."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "أظهر الملÙات المخÙية"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2091,6 +2122,10 @@ msgstr "خالي"
msgid "Clear Output"
msgstr "أخلاء الخرج"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "تصدير المشروع Ùشل, رمز الخطأ %d."
@@ -2410,6 +2445,15 @@ msgid "Pick a Main Scene"
msgstr "إختر المشهد الأساسي"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "اغلاق المشهد"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "اغلاق المشهد"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "غير قادر علي تÙعيل إضاÙØ© البرنامج المÙساعد ÙÙŠ: '%s' تحميل الظبط Ùشل."
@@ -2522,6 +2566,11 @@ msgstr "تشغيل المشهد"
msgid "Close Tab"
msgstr "اغلاق"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "اغلاق"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2576,6 +2625,11 @@ msgid "Go to previously opened scene."
msgstr "اذهب الي المشهد المÙتوح مسبقا."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "نسخ المسار"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "التبويب التالي"
@@ -2603,6 +2657,10 @@ msgstr "مشهد مورث جديد..."
msgid "Open Scene..."
msgstr "اÙتح مشهد..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "ÙÙتح مؤخراً"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Ø­Ùظ المشهد"
@@ -2613,14 +2671,6 @@ msgid "Save All Scenes"
msgstr "Ø­Ùظ جميع المشاهد"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "اغلاق المشهد"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "ÙÙتح مؤخراً"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "تحويل الي..."
@@ -2650,26 +2700,37 @@ msgstr "إعادة المشهد"
msgid "Miscellaneous project or scene-wide tools."
msgstr "ادوات لكل-المشهد او لمشاريع متنوعه."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "مشروع"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "إعدادات المشروع"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ادوات"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "تصدير"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Ùتح مدير المشروع؟"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ادوات"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "متصÙØ­ الموارد أورÙان"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2765,12 +2826,13 @@ msgstr ""
"حينما يتم إستخدامة عن بعد علي جهاز، سيكون هذا أكثر Ùعالية مع نظام شبكات "
"الملÙات."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "المÙعدل"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "إعدادات المÙعدل"
#: editor/editor_node.cpp
@@ -2788,15 +2850,6 @@ 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 "إلغاء/تÙعيل وضع الشاشة الكاملة"
@@ -2821,14 +2874,15 @@ msgstr "إعدادات المÙعدل"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "إدارة قوالب التصدير"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "إدارة قوالب التصدير"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "مساعدة"
@@ -2836,12 +2890,13 @@ msgstr "مساعدة"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "بحث"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "مستندات الإنترنت"
@@ -3123,6 +3178,11 @@ msgstr "الوقت"
msgid "Calls"
msgstr "ندائات"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "الأعضاء"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3290,7 +3350,8 @@ msgid "Import From Node:"
msgstr "إستيراد من عقدة:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "اعادة التحميل"
#: editor/export_template_manager.cpp
@@ -3307,6 +3368,10 @@ msgid "Download"
msgstr "تنزيل"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Ù…Ùقود)"
@@ -3371,12 +3436,10 @@ msgid "No response."
msgstr "لا يوجد إستجابة."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Ùشل الطلب."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "اعادة توجيه حلقة التكرار."
@@ -3390,13 +3453,19 @@ msgid "Download Complete."
msgstr "التحميل إكتمل."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "لا يمكن المسح:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "خطأ ÙÙŠ طلب الرابط: "
#: editor/export_template_manager.cpp
@@ -3484,21 +3553,12 @@ msgstr "تنزيل القوالب"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "حدد السرÙر من القائمة: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"لا يمكن Ùتح file_type_cache.cch من إجل الكتابة، لا يمكن Ø­Ùظ خبأ أنواع الملÙ!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "المÙضلة:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "لا يمكن التنقل إلي '%s' حيث لم يتم العثور عليها ÙÙŠ نظام الملÙات!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "الحالة: إستيراد المل٠Ùشل. من Ùضلك أصلح المل٠و أعد إستيراده يدوياً."
@@ -3532,14 +3592,14 @@ msgid "Provided name contains invalid characters."
msgstr "الأسم المÙقدم يحتوي علي حرو٠خاطئة"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "الأسم يحتوي علي أحر٠غير صالحة."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "مل٠أو مجلد مع هذا الأسم موجود بالÙعل."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "الأسم يحتوي علي أحر٠غير صالحة."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "إعادة تسمية ملÙ:"
@@ -3599,6 +3659,11 @@ msgstr "تكرير..."
msgid "Move To..."
msgstr "تحريك إلي..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "مشهد جديد"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3673,6 +3738,11 @@ msgstr "مل٠أو مجلد مع هذا الأسم موجود بالÙعل."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Ø­Ùظ المشهد"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3742,6 +3812,14 @@ msgid "Search complete"
msgstr "إبحث عن كتابة"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "إضاÙØ© إلي مجموعة"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "حذ٠من المجموعة"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "خطأ: إسم الحركة موجود بالÙعل!"
@@ -3751,13 +3829,23 @@ msgstr "خطأ: إسم الحركة موجود بالÙعل!"
msgid "Invalid group name."
msgstr "اسم غير صالح."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "المجموعات"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "مسح المخطط"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "المجموعات"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "إضاÙØ© إلي مجموعة"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3771,12 +3859,13 @@ msgid "Nodes in Group"
msgstr "إضاÙØ© إلي مجموعة"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "إضاÙØ© إلي مجموعة"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "حذ٠من المجموعة"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Ùتح Ù…Ùعدل الكود"
#: editor/groups_editor.cpp
#, fuzzy
@@ -3987,7 +4076,8 @@ msgid "MultiNode Set"
msgstr "تحديد عقد متعددة"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "حدد عقدة لكي تÙعدل الإشارات والمجموعات."
#: editor/plugin_config_dialog.cpp
@@ -4786,10 +4876,6 @@ msgid "View Files"
msgstr "إظهار الملÙات"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "لا يمكن حل أسم المÙضيÙ:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "خطأ ÙÙŠ الإتصال، من Ùضلك حاول مجدداً."
@@ -4802,14 +4888,47 @@ msgid "No response from host:"
msgstr "لا ردّ من المÙضيÙ:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "لا يمكن حل أسم المÙضيÙ:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Ùشل إتمام الطلب٫ الرمز الذي تم إرجاعه:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Ùشل الطلب."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "لا يمكن المسح:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Ùشل الطلب٫ السبب هو اعادة التحويل مرات اكثر من اللازم"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "اعادة توجيه حلقة التكرار."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Ùشل إتمام الطلب٫ الرمز الذي تم إرجاعه:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "الوقت"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "تجزئة تحميل سيئة، من المتوقع أن يكون المل٠قد تم العبث به."
@@ -4852,6 +4971,11 @@ msgid "Idle"
msgstr "عاطل"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "تثبيت"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "إعادة المحاولة"
@@ -4882,13 +5006,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "الكل"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "إستيراد"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "إضاÙات"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4896,8 +5024,9 @@ msgid "Sort:"
msgstr "ترتيب:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "عكس"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "جار الطلب..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4909,7 +5038,8 @@ msgid "Site:"
msgstr "الموقع:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "الدعم..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4921,6 +5051,11 @@ msgid "Testing"
msgstr "أختبار"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "تحميل"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "مل٠أصول مضغوط"
@@ -4976,31 +5111,38 @@ msgid "Rotation Step:"
msgstr "خطوة الدوران:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "تحريك الموجه العمودي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "إنشاء موجه عمودي جديد"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "مسح الموجه العمودي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "تحريك الموجه الأÙقي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "إنشاء موجه Ø£Ùقي جديد"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "مسح الموجه الأÙقي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "إنشاء موجه عمودي وأÙقي جديد"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5084,6 +5226,11 @@ msgstr "لصق الوضع"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "إخلاء الوضع"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "أنشئ نقاط إنبعاث من الشبكة"
@@ -5113,6 +5260,7 @@ msgid "Zoom Reset"
msgstr "إعادة تعيين التكبير"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "تحديد الوضع"
@@ -5133,14 +5281,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+زر الÙأرة الأيمن: تحديد قائمة العمق"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "وضع التحريك"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "وضع التدوير"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "تحديد الوضع"
@@ -5168,6 +5319,7 @@ msgid "Toggle snapping."
msgstr "إلغاء/تÙعيل الكبس"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "إستخدم الكبس"
@@ -5186,11 +5338,6 @@ msgid "Use Rotation Snap"
msgstr "إستعمال كبس التدوير"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "تعديل الكبس..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "نسبية الكبس"
@@ -5204,6 +5351,11 @@ msgid "Smart Snapping"
msgstr "الكبس الذكي"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "تعديل الكبس..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "الكبس إلي الطÙÙ„"
@@ -5426,16 +5578,6 @@ msgstr "حدد المعامل"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "خطأ تحميل الصورة:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "لا بيكسل بشÙاÙية > 128 ÙÙŠ الصورة..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "حمل قناع الانبعاث"
@@ -5759,14 +5901,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "مصدر السطح خاطئ (لا وجوه)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "الأب ليس لديه وجوه ثابته لكي تتزايد."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "لا يمكنه تخطيط المنطقة."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "حدد مصدر ميش:"
@@ -5852,20 +5986,27 @@ msgid "Generation Time (sec):"
msgstr "وقت التوليد (تانية):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "الوجوه لا تحتوي على منطقة!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "العقدة لا تحتوي على هندسة (الوجوه)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "لا وجوه!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "العقدة لا تحتوي على هندسة."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "العقدة لا تحتوي على هندسة (الوجوه)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "العقدة لا تحتوي على هندسة."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6207,7 +6348,6 @@ msgid "Grid Settings"
msgstr "إعدادات المÙعدل"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6321,12 +6461,7 @@ msgstr "خطأ ÙÙŠ Ø­Ùظ مجموعة البلاط!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "لا يمكن إنشاء المجلد."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "لا يمكن إنشاء المجلد."
#: editor/plugins/script_editor_plugin.cpp
@@ -6356,7 +6491,7 @@ msgstr "خطأ ÙÙŠ تحريك:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "مجلد جديد..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6379,7 +6514,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving"
-msgstr ""
+msgstr "خطأ ÙÙŠ الحÙظ"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
@@ -6393,7 +6528,7 @@ msgstr " مرجع الصنÙ"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr ""
+msgstr "بحث عن التالي"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6417,13 +6552,13 @@ msgstr "ترتيب"
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Up"
-msgstr ""
+msgstr "تحريك لأعلى"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Down"
-msgstr ""
+msgstr "تحرك لأسÙÙ„"
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
@@ -6435,7 +6570,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "File"
-msgstr ""
+msgstr "ملÙ"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6443,8 +6578,13 @@ msgid "Open..."
msgstr "Ø¥Ùتح"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Ùتح الكود"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr ""
+msgstr "احÙظ الكل"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
@@ -6482,11 +6622,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6577,6 +6717,11 @@ msgstr ""
msgid "Search Results"
msgstr "إبحث ÙÙŠ المساعدة"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "إخلاء المشاهد الحالية"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6649,6 +6794,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6684,26 +6830,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "إلغاء/تÙعيل وضع النظرة الحرة"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "إذهب إلي الخطوة التالية"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "إذهب إلي الخطوة السابقة"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "مسح الكل"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "إلغاء/تÙعيل طي الخط"
@@ -6724,6 +6850,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "تكبير المحدد"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6742,32 +6873,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Ùلتر الملÙات..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "إذهب إلي الخطوة التالية"
+msgid "Toggle Bookmark"
+msgstr "إلغاء/تÙعيل وضع النظرة الحرة"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "إذهب إلي الخطوة السابقة"
+msgid "Go to Next Bookmark"
+msgstr "إذهب إلي الخطوة التالية"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "إذهب إلي الخطوة السابقة"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Ùلتر الملÙات..."
+msgid "Remove All Bookmarks"
+msgstr "مسح الكل"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6780,9 +6916,24 @@ msgid "Go to Line..."
msgstr "إذهب إلي الخط"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "إذهب إلي الخطوة التالية"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "إذهب إلي الخطوة السابقة"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6964,7 +7115,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7020,8 +7175,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "تغيير خط الحركة"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7076,8 +7232,8 @@ msgid "Snap Nodes To Floor"
msgstr "الكبس إلي الشبكة"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "تحديد الوضع (ض)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7087,30 +7243,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "وضع الكبس (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7151,26 +7287,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "إلغاء/تÙعيل وضع النظرة الحرة"
@@ -7226,8 +7342,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "جاري الإعداد..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7537,10 +7654,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7635,12 +7748,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "عنصر"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "عنصر"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7751,14 +7864,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7773,8 +7878,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8093,6 +8198,10 @@ msgid "TileSet"
msgstr "مجموعة البلاط"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "أض٠مدخله"
@@ -8182,6 +8291,11 @@ msgid "Duplicate Nodes"
msgstr "Ù…Ùاتيح نسخ التحريك"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "إنشاء عقدة"
@@ -8205,6 +8319,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "إنشاء عقدة"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "إنشاء عقدة"
@@ -8283,6 +8402,22 @@ msgid "Color uniform."
msgstr "تحويل تغيير التحريك"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8290,10 +8425,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8384,7 +8553,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8392,7 +8561,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8404,7 +8573,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8421,7 +8590,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8490,11 +8659,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8510,7 +8679,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8521,7 +8690,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8530,7 +8699,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8538,11 +8707,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8583,11 +8752,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8597,7 +8770,7 @@ msgstr "إنشاء بولي"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8615,15 +8788,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8675,7 +8848,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8690,6 +8863,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8703,19 +8880,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8724,7 +8901,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8733,14 +8910,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8786,47 +8963,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9001,6 +9185,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "إدارة قوالب التصدير"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9149,6 +9337,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "بناء المشروع"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "لا يمكن Ùتح المشروع"
@@ -9221,8 +9418,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9242,8 +9439,9 @@ msgid "Project Manager"
msgstr "مدير المشروع"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "مشروع"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9267,10 +9465,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9609,6 +9803,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "إضاÙات"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9661,14 +9859,6 @@ msgstr "إختر طريقة Ø¥Ùتراضية"
msgid "Select Method"
msgstr "إختر طريقة"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9969,6 +10159,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10015,6 +10209,11 @@ msgstr "Ùتح الكود"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "إنشاء %s جديد"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Ø­Ùظ المشهد"
@@ -10091,19 +10290,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10200,6 +10399,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10233,7 +10436,7 @@ msgid "Script is valid."
msgstr "شجرة الحركة صحيحة."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10398,6 +10601,10 @@ msgid "Change Shortcut"
msgstr "تغيير المرتكزات"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "إعدادات المÙعدل"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10823,10 +11030,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "إسم غير صالح، يجب أن لا يتصادم مع الأسماء المبنية تلقائياً الموجودة."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "إنشاء %s جديد"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "إنشاء %s جديد"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "أنشئ شكل جديد من لا شئ."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11014,10 +11241,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "الأعضاء"
@@ -11772,35 +11995,22 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "خطأ ÙÙŠ معرÙØ© النوع الحر."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "صيغة الخط غير معروÙØ©."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "حدث خطأ أثناء تحميل الخط."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "حجم الخط غير مناسب."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "إدخال"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "مصدر غير صالح لتظليل."
+msgstr "مصدر غير صالح للمعاينة."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "مصدر غير صالح لتظليل."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "comparison function غير صالحة لهذا النوع."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "التعيين لتعمل."
@@ -11817,6 +12027,69 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ."
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "لا يمكن Ùتح file_type_cache.cch من إجل الكتابة، لا يمكن Ø­Ùظ خبأ أنواع "
+#~ "الملÙ!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "لا يمكن التنقل إلي '%s' حيث لم يتم العثور عليها ÙÙŠ نظام الملÙات!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "خطأ تحميل الصورة:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "لا بيكسل بشÙاÙية > 128 ÙÙŠ الصورة..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "الأب ليس لديه وجوه ثابته لكي تتزايد."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "لا يمكنه تخطيط المنطقة."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "الوجوه لا تحتوي على منطقة!"
+
+#~ msgid "No faces!"
+#~ msgstr "لا وجوه!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "لا يمكن إنشاء المجلد."
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "تحديد الوضع (ض)"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "وضع الكبس (%s)"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "خطأ ÙÙŠ معرÙØ© النوع الحر."
+
+#~ msgid "Unknown font format."
+#~ msgstr "صيغة الخط غير معروÙØ©."
+
+#~ msgid "Error loading font."
+#~ msgstr "حدث خطأ أثناء تحميل الخط."
+
+#~ msgid "Invalid font size."
+#~ msgstr "حجم الخط غير مناسب."
+
+#~ msgid "Previous Folder"
+#~ msgstr "المجلد السابق"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "المجلد اللاحق"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Ùتح ÙÙŠ المÙعدل التالي"
+
+#~ msgid "Reverse"
+#~ msgstr "عكس"
+
#~ msgid "Generating solution..."
#~ msgstr "إنشاء الحل..."
@@ -11835,9 +12108,6 @@ msgstr ""
#~ msgid "Create C# solution"
#~ msgstr "إنشاء حل C#‎"
-#~ msgid "Build Project"
-#~ msgstr "بناء المشروع"
-
#, fuzzy
#~ msgid "View log"
#~ msgstr "إظهار الملÙات"
@@ -12223,9 +12493,6 @@ msgstr ""
#~ msgid "Could not save atlas subtexture:"
#~ msgstr "لا يمكن Ø­Ùظ النسيج الÙرعي للأطلس:"
-#~ msgid "Setting Up..."
-#~ msgstr "جاري الإعداد..."
-
#~ msgid "The quick brown fox jumps over the lazy dog."
#~ msgstr "أبجد هوز حطي كلمن صعÙص قرشت ثخذ ضظغ."
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 7e37605159..eab5310b25 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -66,7 +66,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Free"
msgstr "Свободен"
@@ -139,6 +138,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Length"
msgstr "Промени Името на ÐнимациÑта:"
@@ -647,17 +666,18 @@ msgid "Line Number:"
msgstr "Ðомер на Реда:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+#, fuzzy
+msgid "Replaced %d occurrence(s)."
+msgstr "Готово - %d замеÑтване(ниÑ)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "ÐÑма СъвпадениÑ"
+msgid "%d match."
+msgstr ""
-#: editor/code_editor.cpp
+#: editor/code_editor.cpp editor/editor_help.cpp
#, fuzzy
-msgid "Replaced %d occurrence(s)."
-msgstr "Готово - %d замеÑтване(ниÑ)."
+msgid "%d matches."
+msgstr "ÐÑма СъвпадениÑ"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -890,8 +910,7 @@ msgstr "Любими:"
msgid "Recent:"
msgstr "Скорошни:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -986,7 +1005,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Ðе може да Ñе премахне:"
@@ -1024,7 +1043,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr "ЗавиÑимоÑти"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1114,14 +1133,14 @@ msgid "License"
msgstr "Лиценз"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1138,7 +1157,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1155,7 +1174,6 @@ msgid "Success!"
msgstr "Готово!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "ИнÑталиране"
@@ -1639,12 +1657,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "ВнаÑÑне"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "ИзнаÑÑне"
@@ -1714,7 +1731,7 @@ msgstr "Покажи във Файлов Мениджър"
msgid "New Folder..."
msgstr "Ðова папка..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1765,7 +1782,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Покажи Скрити Файлове"
@@ -1791,27 +1808,32 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Предишен подпрозорец"
+msgid "Go to previous folder."
+msgstr "Към горната папка"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Създаване на папка"
+msgid "Go to next folder."
+msgstr "Към горната папка"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Към горната папка"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "ТърÑене"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "ÐеуÑпешно Ñъздаване на папка."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Покажи Скрити Файлове"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2062,6 +2084,10 @@ msgstr "ИзчиÑтване"
msgid "Clear Output"
msgstr "Ðова Ñцена"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2362,6 +2388,15 @@ msgid "Pick a Main Scene"
msgstr "Изберете главна Ñцена"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "ЗатварÑне на Ñцената"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "ЗатварÑне на Ñцената"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2460,6 +2495,11 @@ msgstr "Възпроизвеждане на Ñцената"
msgid "Close Tab"
msgstr "ЗатварÑне"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "ЗатварÑне"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2516,6 +2556,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Копиране"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Следващ подпрозорец"
@@ -2543,6 +2588,10 @@ msgstr ""
msgid "Open Scene..."
msgstr "ОтварÑне на Ñцена..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Запазване на Ñцената"
@@ -2553,14 +2602,6 @@ msgid "Save All Scenes"
msgstr "Запазване на вÑички Ñцени"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "ЗатварÑне на Ñцената"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2590,25 +2631,35 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Проект"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "ÐаÑтройки на проекта"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Сечива"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "ИзнаÑÑне"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "ДиÑпечер на проектите"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Сечива"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2688,12 +2739,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "ÐаÑтройки на редактора"
#: editor/editor_node.cpp
@@ -2711,14 +2763,6 @@ 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 ""
@@ -2742,14 +2786,15 @@ msgid "Open Editor Settings Folder"
msgstr "ÐаÑтройки на редактора"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr "Шаблони"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2757,12 +2802,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "ТърÑене"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3038,6 +3084,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Файл:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3201,8 +3252,9 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
-msgstr ""
+#, fuzzy
+msgid "Redownload"
+msgstr "Презареди"
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -3219,6 +3271,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3281,13 +3337,11 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "Запитване..."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3301,14 +3355,19 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Ðе може да Ñе премахне:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr "Имаше грешка при внаÑÑнето:"
#: editor/export_template_manager.cpp
@@ -3401,20 +3460,12 @@ msgstr "Шаблони"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Любими:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3450,14 +3501,14 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Вече ÑъщеÑтвува файл или папка Ñ Ñ‚Ð¾Ð²Ð° име."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Renaming file:"
msgstr "Имаше грешка при внаÑÑнето:"
@@ -3519,6 +3570,11 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ðова Ñцена"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3589,6 +3645,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Запазване на Ñцената"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3654,6 +3715,14 @@ msgid "Search complete"
msgstr "ТърÑенето е завършено"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува."
@@ -3663,12 +3732,22 @@ msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува."
msgid "Invalid group name."
msgstr "невалидно име на Група."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Ðов проект"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Избиране на вÑичко"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Групи"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3682,12 +3761,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Отвори Кодов Редактор"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3911,7 +3991,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4705,10 +4785,6 @@ msgid "View Files"
msgstr "Преглед на файловете"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Грешка във връзката, Ð¼Ð¾Ð»Ñ Ð¾Ð¿Ð¸Ñ‚Ð°Ð¹ отново."
@@ -4721,14 +4797,45 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "ЗаÑвката Ñе провали, върнат код:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Запитване..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Ðе може да Ñе премахне:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "ЗаÑвката Ñе провали, твърде много пренаÑочваниÑ"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "ЗаÑвката Ñе провали, върнат код:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4769,6 +4876,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "ИнÑталиране"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Опитай пак"
@@ -4798,13 +4910,17 @@ msgid "Last"
msgstr "ПоÑледна"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Ð’Ñички"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Повторно внаÑÑне..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "ПриÑтавки"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4812,8 +4928,9 @@ msgid "Sort:"
msgstr "Подреждане:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "В обратен ред"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Запитване..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4825,7 +4942,8 @@ msgid "Site:"
msgstr "ÐœÑÑто:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Поддръжка..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4837,6 +4955,11 @@ msgid "Testing"
msgstr "ТеÑтова"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Зареди..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4888,33 +5011,38 @@ msgid "Rotation Step:"
msgstr "Съпка при Завъртане:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "ПемеÑти вертикална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "Създай нова вертикална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Премахни вертикална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "ПремеÑти хоризонтална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Създай нова хоризонтална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Премахни хоризонтална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Създай нова хоризонтална и вертикална помощна линиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4998,6 +5126,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Възпроизвеждане на Ñцена по избор"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Възпроизвеждане на Ñцена по избор"
@@ -5028,6 +5161,7 @@ msgid "Zoom Reset"
msgstr "Оригинално увеличение"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Режим на Селектиране"
@@ -5048,14 +5182,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Режим на ПремеÑтване"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Режим на Завъртане"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Режим на Селектиране"
@@ -5082,6 +5219,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5098,11 +5236,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5115,6 +5248,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5332,16 +5470,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5659,14 +5787,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5750,20 +5870,27 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "ÐÑма лица!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Възелът не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ (лица)."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Възелът не Ñъдържа геометриÑ."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Възелът не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ (лица)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Възелът не Ñъдържа геометриÑ."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6100,7 +6227,6 @@ msgid "Grid Settings"
msgstr "ÐаÑтройки"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6207,11 +6333,7 @@ msgstr "Грешка при запиÑване на TextFile:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Грешка, не можа да Ñе зареди файла."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Грешка, не можа да Ñе зареди файла."
#: editor/plugins/script_editor_plugin.cpp
@@ -6239,7 +6361,8 @@ msgid "Error Importing"
msgstr "Имаше грешка при внаÑÑнето"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Ðов TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6324,6 +6447,11 @@ msgid "Open..."
msgstr "Отвори"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Ðова Ñцена"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Запази Ð’Ñичко"
@@ -6363,13 +6491,13 @@ msgid "Save Theme"
msgstr "Запази Темата"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Затвори ДокументациÑта"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "ЗатварÑне на вÑичко"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Затвори ДокументациÑта"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "ПуÑкане"
@@ -6460,6 +6588,11 @@ msgstr "ОтÑтранител на грешки"
msgid "Search Results"
msgstr "ТърÑене"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ЗатварÑне на Ñцената"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6529,6 +6662,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6564,26 +6698,6 @@ msgid "Toggle Comment"
msgstr "Вкарай Коментар"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Добави Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Отиди на ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Отиди на ÐŸÑ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Премахни Ð’Ñички Breakpoint-ове"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Разтвори/Събери Реда"
@@ -6605,6 +6719,11 @@ msgstr "Завърши Символа (Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð·Ð° довършÐ
#: editor/plugins/script_text_editor.cpp
#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Центрирай върху СелекциÑта"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
msgid "Trim Trailing Whitespace"
msgstr "Премахни Празните Ñимволи в ÐºÑ€Ð°Ñ Ð½Ð° реда"
@@ -6621,32 +6740,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Добави Breakpoint"
+msgid "Find Previous"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Премахни Ð’Ñички Breakpoint-ове"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Ðамери във файлове"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Отиди на ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Breakpoint"
+msgid "Toggle Bookmark"
+msgstr "Добави Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Отиди на ÐŸÑ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ Breakpoint"
+msgid "Go to Next Bookmark"
+msgstr "Отиди на ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Breakpoint"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Отиди на ÐŸÑ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Ðамери във файлове"
+msgid "Remove All Bookmarks"
+msgstr "Премахни Ð’Ñички Breakpoint-ове"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6658,8 +6782,23 @@ msgid "Go to Line..."
msgstr "Отиди на Ред"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr ""
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Добави Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Премахни Ð’Ñички Breakpoint-ове"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Отиди на ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Отиди на ÐŸÑ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ Breakpoint"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6842,7 +6981,12 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr "Изглед ОтдÑÑно."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr "Изглед ОтдÑÑно."
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6899,8 +7043,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Позволи филтриране"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6953,8 +7098,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Режим на Селектиране (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6964,31 +7109,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Избиране на вÑичко"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7029,26 +7153,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7103,7 +7207,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "ÐаÑтройки"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7413,10 +7518,6 @@ msgid "TextureRegion"
msgstr "Двуизмерна текÑтура"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7506,11 +7607,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7619,14 +7720,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7641,8 +7734,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7963,6 +8056,10 @@ msgid "TileSet"
msgstr "Файл:"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -8050,6 +8147,11 @@ msgid "Duplicate Nodes"
msgstr "Ðаправи дупликат на Key(s)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "ПоÑтавÑне на възелите"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Избиране на вÑичко"
@@ -8072,6 +8174,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Създай Възел"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Създай Възел"
@@ -8147,6 +8254,22 @@ msgid "Color uniform."
msgstr "ИзнаÑÑне към платформа"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8154,10 +8277,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8246,7 +8403,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8254,7 +8411,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8266,7 +8423,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8283,7 +8440,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8352,11 +8509,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8372,7 +8529,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8383,7 +8540,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8392,7 +8549,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8400,11 +8557,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8445,11 +8602,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8459,7 +8620,7 @@ msgstr "Създаване на папка"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8477,15 +8638,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8537,7 +8698,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8552,6 +8713,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8565,19 +8730,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8586,7 +8751,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8595,14 +8760,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8647,47 +8812,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8862,6 +9034,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9018,6 +9194,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "ВнаÑÑне на ÑъщеÑтвуващ проект"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Създаване на нов проект"
@@ -9087,8 +9272,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9108,8 +9293,9 @@ msgid "Project Manager"
msgstr "ДиÑпечер на проектите"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "СпиÑък Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+#, fuzzy
+msgid "Projects"
+msgstr "Проект"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9133,10 +9319,6 @@ msgid "Templates"
msgstr "Шаблони"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Изход"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9481,6 +9663,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "ПриÑтавки"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9536,14 +9722,6 @@ msgstr "Изберете метод"
msgid "Select Method"
msgstr "Изберете метод"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9840,6 +10018,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9886,6 +10068,11 @@ msgstr "Ðова Ñцена"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Създай нови възли."
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Запазване на Ñцената"
@@ -9963,19 +10150,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10073,6 +10260,10 @@ msgid "Error loading script from %s"
msgstr "Грешка при зареждането на шрифта."
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10104,7 +10295,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10268,6 +10459,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "ÐаÑтройки на редактора"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10702,10 +10897,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Създай нови възли."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Създай нови възли."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Създай нов полигон от нулата."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10896,10 +11110,6 @@ msgid "Cut Nodes"
msgstr "ИзрÑзване на възелите"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "ПоÑтавÑне на възелите"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Файл:"
@@ -11681,22 +11891,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Ðепознат формат за шрифтове."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Грешка при зареждането на шрифта."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11709,6 +11903,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11725,6 +11923,43 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No faces!"
+#~ msgstr "ÐÑма лица!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Грешка, не можа да Ñе зареди файла."
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Режим на Селектиране (Q)"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Избиране на вÑичко"
+
+#~ msgid "Project List"
+#~ msgstr "СпиÑък Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+
+#~ msgid "Exit"
+#~ msgstr "Изход"
+
+#~ msgid "Unknown font format."
+#~ msgstr "Ðепознат формат за шрифтове."
+
+#~ msgid "Error loading font."
+#~ msgstr "Грешка при зареждането на шрифта."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Предишен подпрозорец"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Създаване на папка"
+
+#~ msgid "Reverse"
+#~ msgstr "В обратен ред"
+
#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "ÐеуÑпешно Ñъздаване на папка."
@@ -11896,9 +12131,6 @@ msgstr ""
#~ "Status: Needs Re-Import"
#~ msgstr "Запазване и повторно внаÑÑне"
-#~ msgid "Re-Import..."
-#~ msgstr "Повторно внаÑÑне..."
-
#~ msgid "Font Import"
#~ msgstr "ВнаÑÑне на шрифт"
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 00182447f2..44a7be497c 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -65,7 +65,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "মà§à¦•à§à¦¤ করে দিন"
@@ -144,6 +143,31 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) কল পরিবরà§à¦¤à¦¨ à¦
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) ভà§à¦¯à¦¾à¦²à§ পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦¨à¦œà¦¿à¦¶à¦¨ পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à¦¾à¦¨à§à¦¸à¦«à¦°à§à¦® পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) ভà§à¦¯à¦¾à¦²à§ পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) কল পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° লà§à¦ª পরিবরà§à¦¤à¦¨ করà§à¦¨"
@@ -666,17 +690,18 @@ msgid "Line Number:"
msgstr "লাইন নামà§à¦¬à¦¾à¦°:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "%d সংখà§à¦¯à¦• সংঘটন পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¿à¦¤ হয়েছে ।"
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "কোনো মিল নেই"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d সংখà§à¦¯à¦• সংঘটন পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¿à¦¤ হয়েছে ।"
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "অকà§à¦·à¦°à§‡à¦° মাতà§à¦°à¦¾ (বড়/ছোট-হাতের) মিল করà§à¦¨"
@@ -920,8 +945,7 @@ msgstr "ফেবরিট/পà§à¦°à¦¿à¦¯à¦¼-সমূহ:"
msgid "Recent:"
msgstr "সামà§à¦ªà§à¦°à¦¤à¦¿à¦•:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1025,7 +1049,7 @@ msgstr ""
"দরকারি।\n"
"তবà§à¦“ তাদের অপসারণ করবেন? (অফেরৎযোগà§à¦¯)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "অপসারণ সমà§à¦­à¦¬ নয় :\n"
@@ -1064,7 +1088,7 @@ msgstr "%d -টি বসà§à¦¤à§(সমূহ) সà§à¦¥à¦¾à¦¯à¦¼à§€à¦­à¦¾à¦¬à
msgid "Show Dependencies"
msgstr "নিরà§à¦­à¦°à¦¤à¦¾-সমূহ"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "মালিকবিহীন রিসোরà§à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à¦•à¦¾à¦°à§€"
@@ -1154,14 +1178,16 @@ msgid "License"
msgstr "লাইসেনà§à¦¸"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "থারà§à¦¡ পারà§à¦Ÿà¦¿ লাইসেনà§à¦¸"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot ইঞà§à¦œà¦¿à¦¨ বিভিনà§à¦¨ থারà§à¦¡ পারà§à¦Ÿà¦¿ ফà§à¦°à¦¿ à¦à¦¬à¦‚ ওপেন সোরà§à¦¸ লাইবà§à¦°à§‡à¦°à¦¿ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করে থাকে। "
@@ -1181,7 +1207,8 @@ msgid "Licenses"
msgstr "লাইসেনà§à¦¸"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "জিপ ফরমà§à¦¯à¦¾à¦Ÿ খà§à¦à¦œà§‡ পেতে বà§à¦¯à¦¾à¦°à§à¦¥, পà§à¦¯à¦¾à¦•à§‡à¦œ ফাইল ওপেন করা যায়নি।"
#: editor/editor_asset_installer.cpp
@@ -1199,7 +1226,6 @@ msgid "Success!"
msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "ইনà§à¦¸à¦Ÿà¦²"
@@ -1706,12 +1732,11 @@ msgid "New"
msgstr "নতà§à¦¨"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "ইমà§à¦ªà§‹à¦°à§à¦Ÿ"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ"
@@ -1784,7 +1809,7 @@ msgstr "ফাইল-মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦°à§‡ দেখà§à¦¨"
msgid "New Folder..."
msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "রিফà§à¦°à§‡à¦¸ করà§à¦¨"
@@ -1835,7 +1860,7 @@ msgstr "সামনের দিকে যান"
msgid "Go Up"
msgstr "উপরের দিকে যান"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "অদৃশà§à¦¯ ফাইলসমূহ অদলবদল/টগল করà§à¦¨"
@@ -1861,27 +1886,32 @@ msgstr "ফেবরিট/পà§à¦°à¦¿à¦¯à¦¼à¦•à§‡ নিচের দিকে
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬"
+msgid "Go to previous folder."
+msgstr "ফোলà§à¦¡à¦¾à¦° তৈরী করা সমà§à¦­à¦¬ হয়নি।"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨"
+msgid "Go to next folder."
+msgstr "ফোলà§à¦¡à¦¾à¦° তৈরী করা সমà§à¦­à¦¬ হয়নি।"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "ফোলà§à¦¡à¦¾à¦° তৈরী করা সমà§à¦­à¦¬ হয়নি।"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "ফোলà§à¦¡à¦¾à¦° তৈরী করা সমà§à¦­à¦¬ হয়নি।"
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "অদৃশà§à¦¯ ফাইলসমূহ অদলবদল/টগল করà§à¦¨"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2154,6 +2184,11 @@ msgstr "পরিসà§à¦•à¦¾à¦° করà§à¦¨/কà§à¦²à§€à§Ÿà¦¾à¦°"
msgid "Clear Output"
msgstr "আউটপà§à¦Ÿ/ফলাফল"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "উইনà§à¦¡à§‹"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2483,6 +2518,15 @@ msgid "Pick a Main Scene"
msgstr "à¦à¦•à¦Ÿà¦¿ মà§à¦–à§à¦¯ দৃশà§à¦¯ মনোনীত করà§à¦¨"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "দৃশà§à¦¯ বনà§à¦§ করà§à¦¨"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "দৃশà§à¦¯ বনà§à¦§ করà§à¦¨"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "অà§à¦¯à¦¾à¦¡-অন পà§à¦²à¦¾à¦—ইন à¦à¦¨à¦¾à¦¬à¦² করা সমà§à¦­à¦¬ হয় নি। কনফিগার পারà§à¦¸à¦¿à¦‚ ('%s') বà§à¦¯à¦°à§à¦¥ হয়েছে।"
@@ -2600,6 +2644,11 @@ msgstr "দৃশà§à¦¯ চালান"
msgid "Close Tab"
msgstr "অনà§à¦¯ টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "অনà§à¦¯ টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "অনà§à¦¯ টà§à¦¯à¦¾à¦¬à¦—à§à¦²à¦¿ বনà§à¦§ করà§à¦¨"
@@ -2659,6 +2708,11 @@ msgid "Go to previously opened scene."
msgstr "পূরà§à¦¬à§‡ খোলা দৃশà§à¦¯à§‡ যান।"
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "পথ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿/কপি করà§à¦¨"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "পরের টà§à¦¯à¦¾à¦¬"
@@ -2687,6 +2741,10 @@ msgstr "নতà§à¦¨ উতà§à¦¤à¦°à¦¾à¦§à¦¿à¦•à¦¾à¦°à§€ দৃশà§à¦¯..."
msgid "Open Scene..."
msgstr "দৃশà§à¦¯ খà§à¦²à§à¦¨..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "সামà§à¦ªà§à¦°à¦¤à¦¿à¦•à¦¸à¦®à§‚হ খà§à¦²à§à¦¨"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "দৃশà§à¦¯ সংরকà§à¦·à¦£ করà§à¦¨"
@@ -2697,14 +2755,6 @@ msgid "Save All Scenes"
msgstr "সকল দৃশà§à¦¯ সংরকà§à¦·à¦£ করà§à¦¨"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "দৃশà§à¦¯ বনà§à¦§ করà§à¦¨"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "সামà§à¦ªà§à¦°à¦¤à¦¿à¦•à¦¸à¦®à§‚হ খà§à¦²à§à¦¨"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "à¦à¦¤à§‡ রূপানà§à¦¤à¦° করà§à¦¨..."
@@ -2734,27 +2784,37 @@ msgstr "দৃশà§à¦¯ পà§à¦°à¦¤à§à¦¯à¦¾à¦¬à§ƒà¦¤à§à¦¤ করà§à¦¨"
msgid "Miscellaneous project or scene-wide tools."
msgstr "পà§à¦°à¦•à¦²à§à¦ª অথবা দৃশà§à¦¯à§‡-বà§à¦¯à¦¾à¦ªà§€ বিবিধ সরঞà§à¦œà¦¾à¦®-সমূহ।"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Project"
msgstr "নতà§à¦¨ পà§à¦°à¦•à¦²à§à¦ª"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° সেটিংস"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "সরঞà§à¦œà¦¾à¦®-সমূহ"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "পà§à¦°à¦•à¦²à§à¦ª মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦°"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "সরঞà§à¦œà¦¾à¦®-সমূহ"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "মালিকবিহীন রিসোরà§à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨à¦•à¦¾à¦°à§€"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2853,13 +2913,14 @@ msgstr ""
"রিমোট ডিভাইসে বà§à¦¯à¦¬à¦¹à¦¾à¦°à§‡à¦° সময়, নেটওয়ারà§à¦• ফাইল-সিসà§à¦Ÿà§‡à¦® (filesystem) à¦à¦Ÿà¦¿à¦•à§‡ আরো "
"কারà§à¦¯à¦•à¦° করবে।"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Editor"
msgstr "সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨ (Edit)"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস"
#: editor/editor_node.cpp
@@ -2877,15 +2938,6 @@ 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 "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦¨"
@@ -2910,15 +2962,15 @@ msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ টেমপà§à¦²à§‡à¦Ÿà¦¸à¦®à§‚হ লোড হচà§à¦›à§‡"
-#: editor/editor_node.cpp editor/project_export.cpp
+#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Export Templates"
+msgid "Manage Export Templates..."
msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ টেমপà§à¦²à§‡à¦Ÿà¦¸à¦®à§‚হ লোড হচà§à¦›à§‡"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "হেলà§à¦ª"
@@ -2926,12 +2978,13 @@ msgstr "হেলà§à¦ª"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦®à§‚হ বনà§à¦§ করà§à¦¨"
@@ -3225,6 +3278,11 @@ msgstr "সময়:"
msgid "Calls"
msgstr "ডাকà§à¦¨ (Call)"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "থিম à¦à¦¡à¦¿à¦Ÿ করà§à¦¨..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "চালà§"
@@ -3401,7 +3459,7 @@ msgstr "নোড হতে ইমà§à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨:"
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Re-Download"
+msgid "Redownload"
msgstr "রিলোড"
#: editor/export_template_manager.cpp
@@ -3421,6 +3479,10 @@ msgid "Download"
msgstr "নীচে"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(খà§à¦à¦œà§‡ পাওয়া যায়নি)"
@@ -3489,13 +3551,11 @@ msgid "No response."
msgstr "কোন পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à§Ÿà¦¾ নেই।"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "রিকà§à§Ÿà§‡à¦¸à§à¦Ÿ বà§à¦¯à¦°à§à¦¥ হয়েছে।"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "লà§à¦ª পà§à¦¨à¦ƒà¦¨à¦¿à¦°à§à¦¦à§‡à¦¶ করà§à¦¨à¥¤"
@@ -3510,14 +3570,19 @@ msgid "Download Complete."
msgstr "নীচে"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "থিমটি ফাইলে সংরকà§à¦·à¦£ করা সমà§à¦­à¦¬ হয়নি:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr "à¦à¦Ÿà¦²à¦¾à¦¸/মানচিতà§à¦°à¦¾à¦¬à¦²à§€ সংরকà§à¦·à¦£à§‡ সমসà§à¦¯à¦¾ হয়েছে:"
#: editor/export_template_manager.cpp
@@ -3621,22 +3686,12 @@ msgstr "বসà§à¦¤à§ অপসারণ করà§à¦¨"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "লিসà§à¦Ÿ থেকে মিরর নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"লেখার জনà§à¦¯ file_type_cache.cch খোলা সমà§à¦­à¦¬ হচà§à¦›à§‡ না, ফাইলের ধরণ কà§à¦¯à¦¾à¦¶ (cache) "
-"সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡ না!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "ফেবরিট/পà§à¦°à¦¿à¦¯à¦¼-সমূহ:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "'%s' তে নেভিগেট করা যাবে না কারণ à¦à¦Ÿà¦¿ ফাইল সিসà§à¦Ÿà§‡à¦®à§‡ পাওয়া যায়নি!"
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3681,13 +3736,13 @@ msgstr "বà§à¦¯à¦¬à¦¹à§ƒà¦¤ নামে অগà§à¦°à¦¹à¦£à¦¯à§‹à¦—à§à¦¯ অ
#: editor/filesystem_dock.cpp
#, fuzzy
-msgid "Name contains invalid characters."
-msgstr "গà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ অকà§à¦·à¦°à¦¸à¦®à§‚হ:"
+msgid "A file or folder with this name already exists."
+msgstr "গà§à¦°à§à¦ªà§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ আছে!"
#: editor/filesystem_dock.cpp
#, fuzzy
-msgid "A file or folder with this name already exists."
-msgstr "গà§à¦°à§à¦ªà§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ আছে!"
+msgid "Name contains invalid characters."
+msgstr "গà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ অকà§à¦·à¦°à¦¸à¦®à§‚হ:"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3755,6 +3810,11 @@ msgstr "ডà§à¦ªà§à¦²à¦¿à¦•à§‡à¦Ÿ"
msgid "Move To..."
msgstr "à¦à¦–ানে সরান..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "নতà§à¦¨ দৃশà§à¦¯"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3829,6 +3889,11 @@ msgstr "গà§à¦°à§à¦ªà§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ আছে!"
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "দৃশà§à¦¯ হতে তৈরি করবেন"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ তৈরি করà§à¦¨"
@@ -3898,6 +3963,14 @@ msgid "Search complete"
msgstr "টেকà§à¦¸à¦Ÿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "গà§à¦°à§à¦ª/দলে যোগ করà§à¦¨"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "গà§à¦°à§à¦ª/দল হতে অপসারণ করà§à¦¨"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "ভà§à¦²: অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨!"
@@ -3907,13 +3980,23 @@ msgstr "ভà§à¦²: অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° নাম ইতিমà¦
msgid "Invalid group name."
msgstr "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম।"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "ছবির গà§à¦°à§à¦ªà¦¸à¦®à§‚হ"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "ছবির গà§à¦°à§à¦ª অপসারণ করà§à¦¨"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "দলসমূহ"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "গà§à¦°à§à¦ª/দলে যোগ করà§à¦¨"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3928,12 +4011,13 @@ msgid "Nodes in Group"
msgstr "গà§à¦°à§à¦ªà¦¸à¦®à§‚হ সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "গà§à¦°à§à¦ª/দলে যোগ করà§à¦¨"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "গà§à¦°à§à¦ª/দল হতে অপসারণ করà§à¦¨"
+#, fuzzy
+msgid "Group Editor"
+msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡ খà§à¦²à§à¦¨"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4153,7 +4237,8 @@ msgid "MultiNode Set"
msgstr "মালà§à¦Ÿà¦¿-নোড সà§à¦¥à¦¾à¦ªà¦¨ করà§à¦¨"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "সিগনà§à¦¯à¦¾à¦²-সমূহ à¦à¦¬à¦‚ দলসমূহ সমà§à¦ªà¦¾à¦¦à¦¨ করতে à¦à¦•à¦Ÿà¦¿ নোড নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤"
#: editor/plugin_config_dialog.cpp
@@ -4969,10 +5054,6 @@ msgid "View Files"
msgstr "ফাইল"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "হোসà§à¦Ÿà¦¨à¦¾à¦® রিসলভ করা যায়নি:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "সংযোগ তà§à¦°à§à¦Ÿà¦¿, আবার চেষà§à¦Ÿà¦¾ করà§à¦¨à¥¤"
@@ -4986,15 +5067,48 @@ msgid "No response from host:"
msgstr "হোসà§à¦Ÿ থেকে কোন পà§à¦°à¦¤à¦¿à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾ নেই:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "হোসà§à¦Ÿà¦¨à¦¾à¦® রিসলভ করা যায়নি:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request failed, return code:"
msgstr "আবেদনকৃত ফাইল ফরমà§à¦¯à¦¾à¦Ÿ/ধরণ অজানা:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "রিকà§à§Ÿà§‡à¦¸à§à¦Ÿ বà§à¦¯à¦°à§à¦¥ হয়েছে।"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "থিমটি ফাইলে সংরকà§à¦·à¦£ করা সমà§à¦­à¦¬ হয়নি:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "অনà§à¦°à§‹à¦§ বà§à¦¯à¦°à§à¦¥ হয়েছে, অধিক সংখà§à¦¯à¦• রিডাইরেকà§à¦Ÿ à¦à¦° কারণে"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "লà§à¦ª পà§à¦¨à¦ƒà¦¨à¦¿à¦°à§à¦¦à§‡à¦¶ করà§à¦¨à¥¤"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "আবেদনকৃত ফাইল ফরমà§à¦¯à¦¾à¦Ÿ/ধরণ অজানা:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "সময়:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "ডাউনলোড হà§à¦¯à¦¾à¦¶ তà§à¦°à§à¦Ÿà¦¿à¦¯à§à¦•à§à¦¤, কাংখিত ফাইলটি কà§à¦·à¦¤à¦¿à¦—à§à¦°à¦¸à§à¦¤ হয়েছে।"
@@ -5039,6 +5153,11 @@ msgid "Idle"
msgstr "অনিয়োজিত"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "ইনà§à¦¸à¦Ÿà¦²"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "পà§à¦¨à¦°à¦¾à¦¯à¦¼ চেষà§à¦Ÿà¦¾ করà§à¦¨"
@@ -5070,13 +5189,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "সকল"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "পà§à¦²à¦¾à¦—ইন-সমূহ"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -5084,8 +5207,9 @@ msgid "Sort:"
msgstr "সাজান:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "উলà§à¦Ÿà¦¾à¦¨/বিপরীত দিকে ফিরান"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "পরীকà§à¦·à¦¾à¦®à§‚লক উৎস"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -5097,7 +5221,8 @@ msgid "Site:"
msgstr "ওয়েবসাইট:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "সমরà§à¦¥à¦¨..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5109,6 +5234,11 @@ msgid "Testing"
msgstr "পরীকà§à¦·à¦¾à¦®à§‚লক উৎস"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "লোড"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "পà§à¦°à¦¯à¦¼à§‡à¦¾à¦œà¦¨à§€à¦¯à¦¼ উপকরণসমূহের ZIP ফাইল"
@@ -5160,36 +5290,38 @@ msgid "Rotation Step:"
msgstr "ঘূরà§à¦£à¦¾à§Ÿà¦¨à§‡à¦° পদকà§à¦·à§‡à¦ª:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "ভারà§à¦Ÿà¦¿à¦•à§à¦¯à¦¾à¦² গাইড সরান"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "নতà§à¦¨ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ তৈরি করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "চলক/ভেরিয়েবল অপসারণ করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "বকà§à¦°à¦°à§‡à¦–ায় বিনà§à¦¦à§ সরান"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "নতà§à¦¨ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ তৈরি করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ চাবিসমূহ অপসারণ করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "নতà§à¦¨ হরাইজনà§à¦Ÿà¦¾à¦² à¦à¦¬à¦‚ ভারà§à¦Ÿà¦¿à¦•à§à¦¯à¦¾à¦² গাইড তৈরী করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5282,6 +5414,11 @@ msgstr "ভঙà§à¦—ি পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨ করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "ভঙà§à¦—ি পরিষà§à¦•à¦¾à¦° করà§à¦¨"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Mesh হতে Emitter তৈরি করà§à¦¨"
@@ -5312,6 +5449,7 @@ msgid "Zoom Reset"
msgstr "জà§à¦®à§ পà§à¦¨:সà§à¦¥à¦¾à¦ªà¦¨ করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "মোড (Mode) বাছাই করà§à¦¨"
@@ -5332,14 +5470,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "অলà§à¦Ÿà¦¾à¦° কী + মাউসের ডান বোতাম: গভীর তালিকায় নিরà§à¦¬à¦¾à¦šà¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "মোড (Mode) সরান"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "ঘূরà§à¦£à¦¾à§Ÿà¦¨ মোড"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "মাপের মোড করà§à¦¨ (R)"
@@ -5367,6 +5508,7 @@ msgid "Toggle snapping."
msgstr "ছেদবিনà§à¦¦à§ অদলবদল করà§à¦¨ (টগল বà§à¦°à§‡à¦•à¦ªà§Ÿà§‡à¦¨à§à¦Ÿ)"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
@@ -5385,12 +5527,6 @@ msgid "Use Rotation Snap"
msgstr "ঘূরà§à¦£à¦¨ সà§à¦¨à§à¦¯à¦¾à¦ª বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Configure Snap..."
-msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª কনফিগার করà§à¦¨..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "আপেকà§à¦·à¦¿à¦• সà§à¦¨à§à¦¯à¦¾à¦ª"
@@ -5404,6 +5540,12 @@ msgid "Smart Snapping"
msgstr "সà§à¦®à¦¾à¦°à§à¦Ÿ সà§à¦¨à§à¦¯à¦¾à¦ªà¦¿à¦‚ বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করà§à¦¨"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Configure Snap..."
+msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª কনফিগার করà§à¦¨..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "ধারক/বাহক পরà§à¦¯à¦¨à§à¦¤ বিসà§à¦¤à§ƒà¦¤ করà§à¦¨"
@@ -5632,16 +5774,6 @@ msgstr "হà§à¦¯à¦¾à¦¨à§à¦¡à§‡à¦² সà§à¦¥à¦¾à¦ªà¦¨ করà§à¦¨"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "ছবি লোডে সমসà§à¦¯à¦¾ হয়েছে:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "সà§à¦¬à¦šà§à¦›à¦¤à¦¾à¦¸à¦¹ কোনো পিকà§à¦¸à§‡à¦² নেই > ছবিতে ১২৮..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Emission Mask লোড করà§à¦¨"
@@ -5976,14 +6108,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "পৃষà§à¦ à¦¤à¦²à§‡à¦° উৎস অকারà§à¦¯à¦•à¦° (কোনো ফোকাস নেই)।"
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "পপà§à¦²à§‡à¦Ÿ করার জনà§à¦¯ ধারকের কোনো নিরেট পৃষà§à¦  নেই।"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "à¦à¦²à¦¾à¦•à¦¾à¦° নকশা করা সমà§à¦­à¦¬ হয়নি।"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Mesh-à¦à¦° à¦à¦•à¦Ÿà¦¿ উৎস নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨:"
@@ -6070,20 +6194,27 @@ msgid "Generation Time (sec):"
msgstr "গড় সময় (সেঃ)"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "পৃষà§à¦ à¦¸à¦®à§‚হ কোনো আকার নেই!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "নোডে কোনো জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦• আকার নেই (পৃষà§à¦ )।"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "কোনো পৃষà§à¦  নেই!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "নোডে কোনো জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦• আকার নেই।"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "নোডে কোনো জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦• আকার নেই (পৃষà§à¦ )।"
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "নোডে কোনো জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦• আকার নেই।"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6437,7 +6568,6 @@ msgid "Grid Settings"
msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª সেটিংস"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª"
@@ -6557,13 +6687,8 @@ msgstr "ছবি লোডে সমসà§à¦¯à¦¾ হয়েছে:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "ছবি লোড অসমà§à¦­à¦¬ হয়েছে"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
-msgstr "ছবি লোড অসমà§à¦­à¦¬ হয়েছে"
+msgid "Could not load file at:"
+msgstr "টাইলটি খà§à¦à¦œà§‡ পাওয়া যায়নি:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6592,7 +6717,7 @@ msgstr "ইমà§à¦ªà§‹à¦°à§à¦Ÿà§‡ সমসà§à¦¯à¦¾ হয়েছে"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨"
#: editor/plugins/script_editor_plugin.cpp
@@ -6680,6 +6805,11 @@ msgid "Open..."
msgstr "খà§à¦²à§à¦¨"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "পরবরà§à¦¤à§€ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "সকলà§à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করà§à¦¨"
@@ -6720,13 +6850,13 @@ msgid "Save Theme"
msgstr "থিম সংরকà§à¦·à¦£ করà§à¦¨"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦®à§‚হ বনà§à¦§ করà§à¦¨"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "সবগà§à¦²à¦¿ বনà§à¦§ করà§à¦¨"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦®à§‚হ বনà§à¦§ করà§à¦¨"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "চালান"
@@ -6819,6 +6949,11 @@ msgstr "ডিবাগার"
msgid "Search Results"
msgstr "সাহাযà§à¦¯ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "বোনà§â€Œ/হাড় পরিষà§à¦•à¦¾à¦° করà§à¦¨"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6893,6 +7028,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6930,26 +7066,6 @@ msgstr "কমেনà§à¦Ÿ টগল করà§à¦¨"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦¨"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "পরের বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "পূরà§à¦¬à§‡à¦° বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° আইটেম অপসারণ করà§à¦¨"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "লাইন আনফোলà§à¦¡ করà§à¦¨"
@@ -6970,6 +7086,11 @@ msgid "Complete Symbol"
msgstr "সিমà§à¦¬à¦² সমà§à¦ªà§‚রà§à¦£ করà§à¦¨"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহের আকার পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "শেষের হোয়াইটসà§à¦ªà§‡à¦¸ ছেà¦à¦Ÿà§‡ ফেলà§à¦¨"
@@ -6988,32 +7109,37 @@ msgid "Auto Indent"
msgstr "সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿà¦­à¦¾à¦¬à§‡ মাতà§à¦°à¦¾ দিন"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "ছেদবিনà§à¦¦à§ অদলবদল করà§à¦¨ (টগল বà§à¦°à§‡à¦•à¦ªà§Ÿà§‡à¦¨à§à¦Ÿ)"
+msgid "Find Previous"
+msgstr "পূরà§à¦¬à§‡ খà§à¦à¦œà§à¦¨"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "সকল বিরতি-বিনà§à¦¦à§-সমূহ অপসারণ করà§à¦¨"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "দà§à¦°à§à¦¤ ফাইলসমূহ ফিলà§à¦Ÿà¦¾à¦° করà§à¦¨..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "পà§à¦°à¦¾à¦¸à¦™à§à¦—িক সাহাযà§à¦¯"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "পরের বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
+msgid "Toggle Bookmark"
+msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦¨"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "পূরà§à¦¬à§‡à¦° বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
+msgid "Go to Next Bookmark"
+msgstr "পরের বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "পূরà§à¦¬à§‡ খà§à¦à¦œà§à¦¨"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "পূরà§à¦¬à§‡à¦° বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "দà§à¦°à§à¦¤ ফাইলসমূহ ফিলà§à¦Ÿà¦¾à¦° করà§à¦¨..."
+msgid "Remove All Bookmarks"
+msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° আইটেম অপসারণ করà§à¦¨"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7026,8 +7152,23 @@ msgid "Go to Line..."
msgstr "লাইনে যান..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "পà§à¦°à¦¾à¦¸à¦™à§à¦—িক সাহাযà§à¦¯"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "ছেদবিনà§à¦¦à§ অদলবদল করà§à¦¨ (টগল বà§à¦°à§‡à¦•à¦ªà§Ÿà§‡à¦¨à§à¦Ÿ)"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "সকল বিরতি-বিনà§à¦¦à§-সমূহ অপসারণ করà§à¦¨"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "পরের বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "পূরà§à¦¬à§‡à¦° বিরতিবিনà§à¦¦à§à¦¤à§‡ যান"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -7220,9 +7361,14 @@ msgstr "পশà§à¦šà¦¾à§Ž"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "দরà§à¦¶à¦¨à§‡à¦° সাথে সারিবদà§à¦§ করà§à¦¨"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "নিরà§à¦¬à¦¾à¦šà¦¨à¦•à§‡ দরà§à¦¶à¦¨à§‡à¦° সাথে সারিবদà§à¦§ করà§à¦¨"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "ইনসà§à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸ করার জনà§à¦¯ পà§à¦°à§Ÿà§‹à¦œà¦¨à§€à§Ÿ ধারক উপসà§à¦¥à¦¿à¦¤ নেই।"
@@ -7283,8 +7429,8 @@ msgstr "অডিও শà§à¦°à§‹à¦¤à¦¾"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Doppler Enable"
-msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
+msgid "Enable Doppler"
+msgstr "সমà§à¦ªà¦¾à¦¦à¦¨à¦¯à§‹à¦—à§à¦¯ অংশীদারীসমূহ"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7343,9 +7489,8 @@ msgid "Snap Nodes To Floor"
msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª মোড:"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "মোড (Mode) বাছাই করà§à¦¨"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7356,32 +7501,11 @@ msgid ""
msgstr "অলà§à¦Ÿà¦¾à¦° কী + মাউসের ডান বোতাম: গভীর তালিকায় নিরà§à¦¬à¦¾à¦šà¦¨"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "সরানোর মোড (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "ঘোরানোর মোড (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "মাপের মোড করà§à¦¨ (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ সà§à¦¥à¦¾à¦¨à¦¾à¦™à§à¦•à¦¸à¦®à§‚হ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr "মাপের মোড করà§à¦¨ (R)"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª মোড:"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "নিমà§à¦¨ দরà§à¦¶à¦¨"
@@ -7423,30 +7547,6 @@ msgid "Focus Selection"
msgstr "নিরà§à¦¬à¦¾à¦šà¦¨à§‡ ফোকাস করà§à¦¨"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "নিরà§à¦¬à¦¾à¦šà¦¨à¦•à§‡ দরà§à¦¶à¦¨à§‡à¦° সাথে সারিবদà§à¦§ করà§à¦¨"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Move"
-msgstr "সরান"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Rotate"
-msgstr "কনà§à¦Ÿà§à¦°à§‹à¦² বোতাম: ঘূরà§à¦£à¦¨"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Scale"
-msgstr "সà§à¦•à§‡à¦²/মাপ:"
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Toggle Freelook"
msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦¨"
@@ -7504,7 +7604,8 @@ msgstr "গà§à¦°à¦¿à¦¡ দেখà§à¦¨"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "সেটিংস"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7827,10 +7928,6 @@ msgid "TextureRegion"
msgstr "গঠনবিনà§à¦¯à¦¾à¦¸à§‡à¦° à¦à¦²à¦¾à¦•à¦¾"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "থিমটি ফাইলে সংরকà§à¦·à¦£ করা সমà§à¦­à¦¬ হয়নি:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "সকল বসà§à¦¤à§ যোগ করà§à¦¨"
@@ -7925,12 +8022,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "বসà§à¦¤à§/আইটেম"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "বসà§à¦¤à§/আইটেম"
#: editor/plugins/theme_editor_plugin.cpp
@@ -8044,14 +8141,6 @@ msgid "Transpose"
msgstr "পকà§à¦·à¦¾à¦¨à§à¦¤à¦°à¦¿à¦¤ করà§à¦¨"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "পà§à¦°à¦¤à¦¿à¦¬à¦¿à¦®à§à¦¬ X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "পà§à¦°à¦¤à¦¿à¦¬à¦¿à¦®à§à¦¬ Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿ টà§à¦•à¦°à§‹"
@@ -8068,8 +8157,8 @@ msgstr "TileMap আà¦à¦•à§à¦¨"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8392,6 +8481,10 @@ msgid "TileSet"
msgstr "TileSet (টাইল-সেট)..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "ইনপà§à¦Ÿ যোগ করà§à¦¨"
@@ -8484,6 +8577,11 @@ msgid "Duplicate Nodes"
msgstr "নোড(সমূহ) পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿ করà§à¦¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "নোড-সমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "নোড(সমূহ) অপসারণ করà§à¦¨"
@@ -8508,6 +8606,11 @@ msgstr "ডান"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "নোড তৈরি করà§à¦¨"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "নোড তৈরি করà§à¦¨"
@@ -8585,6 +8688,22 @@ msgid "Color uniform."
msgstr "রà§à¦ªà¦¾à¦¨à§à¦¤à¦°"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8592,10 +8711,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "ভেকà§à¦Ÿà¦° ধà§à¦°à§à¦¬à¦• পরিবরà§à¦¤à¦¨ করà§à¦¨"
@@ -8688,7 +8841,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8696,7 +8849,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8708,7 +8861,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8725,7 +8878,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8794,11 +8947,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8814,7 +8967,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8825,7 +8978,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8834,7 +8987,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8842,11 +8995,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8889,12 +9042,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "টেকà§à¦¸à¦¾à¦° ইউনিফরà§à¦® পরিবরà§à¦¤à¦¨ করà§à¦¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "টেকà§à¦¸à¦¾à¦° ইউনিফরà§à¦® পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "টেকà§à¦¸à¦¾à¦° ইউনিফরà§à¦® পরিবরà§à¦¤à¦¨ করà§à¦¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8904,7 +9062,7 @@ msgstr "রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à§‡à¦° à¦à¦° সংলাপ..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8922,15 +9080,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8983,7 +9141,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8998,6 +9156,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -9011,19 +9173,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -9032,7 +9194,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -9041,14 +9203,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9095,47 +9257,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9332,6 +9501,11 @@ msgstr "à¦à¦‡ পà§à¦²à§à¦¯à¦¾à¦Ÿà¦«à¦°à§à¦®à§‡à¦° জনà§à¦¯ দরকা
#: editor/project_export.cpp
#, fuzzy
+msgid "Manage Export Templates"
+msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ টেমপà§à¦²à§‡à¦Ÿà¦¸à¦®à§‚হ লোড হচà§à¦›à§‡"
+
+#: editor/project_export.cpp
+#, fuzzy
msgid "Export With Debug"
msgstr "Tile Set à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨"
@@ -9493,6 +9667,15 @@ msgstr "নামহীন পà§à¦°à¦•à¦²à§à¦ª"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "বিদà§à¦¯à¦®à¦¾à¦¨ পà§à¦°à¦•à¦²à§à¦ª ইমà§à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "সংযোগ..."
@@ -9572,8 +9755,8 @@ msgstr "তালিকা হতে পà§à¦°à¦•à¦²à§à¦ª অপসারণ à¦
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "তালিকা হতে পà§à¦°à¦•à¦²à§à¦ª অপসারণ করবেন? (ফোলà§à¦¡à¦¾à¦°à§‡à¦° বিষয়াদি পরিবরà§à¦¤à¦¨ হবে না)"
#: editor/project_manager.cpp
@@ -9599,8 +9782,9 @@ msgid "Project Manager"
msgstr "পà§à¦°à¦œà§‡à¦•à§à¦Ÿ মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦°"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° তালিকা"
+#, fuzzy
+msgid "Projects"
+msgstr "নতà§à¦¨ পà§à¦°à¦•à¦²à§à¦ª"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9625,10 +9809,6 @@ msgid "Templates"
msgstr "বসà§à¦¤à§ অপসারণ করà§à¦¨"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨"
-
-#: editor/project_manager.cpp
#, fuzzy
msgid "Restart Now"
msgstr "পà§à¦¨à¦°à¦¾à¦°à¦®à§à¦­ (সেঃ):"
@@ -9985,6 +10165,10 @@ msgstr "ঘটনাসà§à¦¥à¦²"
msgid "AutoLoad"
msgstr "সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿ-লোড"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "পà§à¦²à¦¾à¦—ইন-সমূহ"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "শূনà§à¦¯"
@@ -10040,14 +10224,6 @@ msgstr "মেথড/পদà§à¦§à¦¤à¦¿ বাছাই করà§à¦¨"
msgid "Select Method"
msgstr "মেথড/পদà§à¦§à¦¤à¦¿ বাছাই করà§à¦¨"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "PVRTC সরঞà§à¦œà¦¾à¦® à¦à¦•à§à¦¸à¦¿à¦•à¦¿à¦‰à¦Ÿ করা সমà§à¦­à¦¬ হচà§à¦›à§‡ না:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "PVRTC সরঞà§à¦œà¦¾à¦® দà§à¦¬à¦¾à¦°à¦¾ রূপানà§à¦¤à¦°à¦¿à¦¤ ছবি পà§à¦¨à¦°à¦¾à§Ÿ লোড করা সমà§à¦­à¦¬ নয়:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10354,6 +10530,11 @@ msgid "Remove Node(s)"
msgstr "নোড(সমূহ) অপসারণ করà§à¦¨"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "ইনপà§à¦Ÿ নাম পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10403,6 +10584,11 @@ msgstr "পরবরà§à¦¤à§€ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "নোডের নতà§à¦¨ অভিভাবক দান করà§à¦¨"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "অরà§à¦¥à¦ªà§‚রà§à¦¨!"
@@ -10485,23 +10671,25 @@ msgstr "নোড কনফিগারেশন সতরà§à¦•à¦¬à¦¾à¦°à§à¦¤à
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"à¦à¦‡ নোডের কানেকশন à¦à¦¬à¦‚ গà§à¦°à§à¦ª বিদà§à¦¯à¦®à¦¾à¦¨\n"
"সিগনà§à¦¯à¦¾à¦² ডক দেখানোর জনà§à¦¯ কà§à¦²à¦¿à¦• করà§à¦¨à¥¤"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"à¦à¦‡ নোডের কানেকশন বিদà§à¦¯à¦®à¦¾à¦¨\n"
"সিগনà§à¦¯à¦¾à¦² ডক দেখানোর জনà§à¦¯ কà§à¦²à¦¿à¦• করà§à¦¨à¥¤"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"à¦à¦‡ নোডটি à¦à¦•à¦Ÿà¦¿ গà§à¦°à§à¦ªà§‡à¦° অনà§à¦¤à¦°à§à¦­à§à¦•à§à¦¤à¥¤\n"
@@ -10611,6 +10799,11 @@ msgid "Error loading script from %s"
msgstr "%s হতে সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে সমসà§à¦¯à¦¾ হয়েছে"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "ওভাররাইড..."
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "না/আ"
@@ -10645,7 +10838,8 @@ msgid "Script is valid."
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "অনà§à¦®à§‹à¦¦à¦¿à¦¤: a-z, A-Z, 0-9 à¦à¦¬à¦‚ _"
#: editor/script_create_dialog.cpp
@@ -10818,6 +11012,10 @@ msgid "Change Shortcut"
msgstr "অà§à¦¯à¦¾à¦‚করসমূহ পরিবরà§à¦¤à¦¨ করà§à¦¨"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "শরà§à¦Ÿà¦•à¦¾à¦Ÿà¦¸à¦®à§‚হ"
@@ -11279,10 +11477,32 @@ msgid "Set Variable Type"
msgstr "চলক/ভেরিয়েবল সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ পূরà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ ধরণের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ "
+"হতে পারবে না।"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "নতà§à¦¨ তৈরি করà§à¦¨"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "ভেরিয়েবলস/চলকসমূহ:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "নতà§à¦¨ তৈরি করà§à¦¨"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "আরমà§à¦­ হতে নতà§à¦¨ polygon তৈরি করà§à¦¨à¥¤"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "নামটি কারà§à¦¯à¦•à¦° সনাকà§à¦¤à¦•à¦¾à¦°à§€ নয়:"
@@ -11491,10 +11711,6 @@ msgid "Cut Nodes"
msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "নোড-সমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "সদসà§à¦¯à¦—ণ (Members):"
@@ -12306,22 +12522,6 @@ msgstr ""
"আকার ধারণ করতে পারে। অনà§à¦¯à¦¥à¦¾à§Ÿ, à¦à¦Ÿà¦¿à¦•à§‡ à¦à¦•à¦Ÿà¦¿ RenderTarget করà§à¦¨ à¦à¦¬à¦‚ à¦à¦° অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ "
"দৃশà§à¦¯à¦¾à¦¬à¦²à¦¿à¦•à§‡ (texture) দৃশà§à¦¯à¦®à¦¾à¦¨ করতে কোনো নোডে হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨à¥¤"
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "FreeType আরমà§à¦­à§‡ সমসà§à¦¯à¦¾ হয়েছে।"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "অজানা ধরনের ফনà§à¦Ÿà¥¤"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "ফনà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে সমসà§à¦¯à¦¾ হয়েছে।"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "ফনà§à¦Ÿà§‡à¦° আকার অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯à¥¤"
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -12337,6 +12537,11 @@ msgstr "অকারà§à¦¯à¦•à¦° উৎস!"
msgid "Invalid source for shader."
msgstr "অকারà§à¦¯à¦•à¦° উৎস!"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "অকারà§à¦¯à¦•à¦° উৎস!"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -12353,6 +12558,132 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "লেখার জনà§à¦¯ file_type_cache.cch খোলা সমà§à¦­à¦¬ হচà§à¦›à§‡ না, ফাইলের ধরণ কà§à¦¯à¦¾à¦¶ (cache) "
+#~ "সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡ না!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "'%s' তে নেভিগেট করা যাবে না কারণ à¦à¦Ÿà¦¿ ফাইল সিসà§à¦Ÿà§‡à¦®à§‡ পাওয়া যায়নি!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "ছবি লোডে সমসà§à¦¯à¦¾ হয়েছে:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "সà§à¦¬à¦šà§à¦›à¦¤à¦¾à¦¸à¦¹ কোনো পিকà§à¦¸à§‡à¦² নেই > ছবিতে ১২৮..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "পপà§à¦²à§‡à¦Ÿ করার জনà§à¦¯ ধারকের কোনো নিরেট পৃষà§à¦  নেই।"
+
+#~ msgid "Couldn't map area."
+#~ msgstr "à¦à¦²à¦¾à¦•à¦¾à¦° নকশা করা সমà§à¦­à¦¬ হয়নি।"
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "পৃষà§à¦ à¦¸à¦®à§‚হ কোনো আকার নেই!"
+
+#~ msgid "No faces!"
+#~ msgstr "কোনো পৃষà§à¦  নেই!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "ছবি লোড অসমà§à¦­à¦¬ হয়েছে"
+
+#, fuzzy
+#~ msgid "Error could not load file."
+#~ msgstr "ছবি লোড অসমà§à¦­à¦¬ হয়েছে"
+
+#, fuzzy
+#~ msgid "Doppler Enable"
+#~ msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "মোড (Mode) বাছাই করà§à¦¨"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "সরানোর মোড (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "ঘোরানোর মোড (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "মাপের মোড করà§à¦¨ (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ সà§à¦¥à¦¾à¦¨à¦¾à¦™à§à¦•à¦¸à¦®à§‚হ"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª মোড:"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨"
+
+#, fuzzy
+#~ msgid "Tool Move"
+#~ msgstr "সরান"
+
+#, fuzzy
+#~ msgid "Tool Rotate"
+#~ msgstr "কনà§à¦Ÿà§à¦°à§‹à¦² বোতাম: ঘূরà§à¦£à¦¨"
+
+#, fuzzy
+#~ msgid "Tool Scale"
+#~ msgstr "সà§à¦•à§‡à¦²/মাপ:"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "তালিকা হতে পà§à¦°à¦•à¦²à§à¦ª অপসারণ করবেন? (ফোলà§à¦¡à¦¾à¦°à§‡à¦° বিষয়াদি পরিবরà§à¦¤à¦¨ হবে না)"
+
+#~ msgid "Project List"
+#~ msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° তালিকা"
+
+#~ msgid "Exit"
+#~ msgstr "পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "PVRTC সরঞà§à¦œà¦¾à¦® à¦à¦•à§à¦¸à¦¿à¦•à¦¿à¦‰à¦Ÿ করা সমà§à¦­à¦¬ হচà§à¦›à§‡ না:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "PVRTC সরঞà§à¦œà¦¾à¦® দà§à¦¬à¦¾à¦°à¦¾ রূপানà§à¦¤à¦°à¦¿à¦¤ ছবি পà§à¦¨à¦°à¦¾à§Ÿ লোড করা সমà§à¦­à¦¬ নয়:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "FreeType আরমà§à¦­à§‡ সমসà§à¦¯à¦¾ হয়েছে।"
+
+#~ msgid "Unknown font format."
+#~ msgstr "অজানা ধরনের ফনà§à¦Ÿà¥¤"
+
+#~ msgid "Error loading font."
+#~ msgstr "ফনà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে সমসà§à¦¯à¦¾ হয়েছে।"
+
+#~ msgid "Invalid font size."
+#~ msgstr "ফনà§à¦Ÿà§‡à¦° আকার অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯à¥¤"
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡ খà§à¦²à§à¦¨"
+
+#~ msgid "Reverse"
+#~ msgstr "উলà§à¦Ÿà¦¾à¦¨/বিপরীত দিকে ফিরান"
+
+#~ msgid "Mirror X"
+#~ msgstr "পà§à¦°à¦¤à¦¿à¦¬à¦¿à¦®à§à¦¬ X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "পà§à¦°à¦¤à¦¿à¦¬à¦¿à¦®à§à¦¬ Y"
+
#, fuzzy
#~ msgid "Generating solution..."
#~ msgstr "ওকটà§à¦°à§€ (octree) গঠনবিনà§à¦¯à¦¾à¦¸ তৈরি করা হচà§à¦›à§‡"
@@ -12943,9 +13274,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤à¦¸à¦®à§‚হ মà§à¦›à§‡ ফেলà§à¦¨"
-#~ msgid "Could not find tile:"
-#~ msgstr "টাইলটি খà§à¦à¦œà§‡ পাওয়া যায়নি:"
-
#~ msgid "Item name or ID:"
#~ msgstr "আইটেমের নাম বা আইডি:"
@@ -13200,9 +13528,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "তথà§à¦¯"
-#~ msgid "Re-Import..."
-#~ msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "ইমà§à¦ªà§‹à¦°à§à¦Ÿ করার জনà§à¦¯ কোনো বিট মাসà§à¦• নেই!"
@@ -13598,9 +13923,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "সà§à¦Ÿà§‡à¦°à¦¿à¦“"
-#~ msgid "Window"
-#~ msgstr "উইনà§à¦¡à§‹"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "%s%% -ঠমাপিত হচà§à¦›à§‡à¥¤"
@@ -13831,9 +14153,6 @@ msgstr ""
#~ msgid "Add Image Group"
#~ msgstr "ছবির গà§à¦°à§à¦ª যোগ করà§à¦¨"
-#~ msgid "Delete Image Group"
-#~ msgstr "ছবির গà§à¦°à§à¦ª অপসারণ করà§à¦¨"
-
#~ msgid "Project Export Settings"
#~ msgstr "পà§à¦°à¦•à¦²à§à¦ª à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ-à¦à¦° সেটিংস"
@@ -13918,9 +14237,6 @@ msgstr ""
#~ msgid "Export Project PCK"
#~ msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° PCK à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨"
-#~ msgid "Export..."
-#~ msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ..."
-
#~ msgid "Project Export"
#~ msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ পà§à¦°à¦•à¦²à§à¦ª"
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 4f12d5f02e..44afcb8066 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-07-09 10:46+0000\n"
+"PO-Revision-Date: 2019-08-04 14:23+0000\n"
"Last-Translator: roger <616steam@gmail.com>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/"
"godot/ca/>\n"
@@ -63,7 +63,6 @@ msgid "On call to '%s':"
msgstr "En la crida a '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Allibera"
@@ -132,6 +131,31 @@ msgid "Anim Change Call"
msgstr "Canviar crida d'animació"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Modifica el temps de la clau"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Modifica la Transició d'Animació"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Modifica la Transformació de l'Animació"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Modifica el valor de la clau"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Canviar crida d'animació"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Canviar la durada de l'Animació"
@@ -450,7 +474,7 @@ msgstr "Selecciona-ho Tot"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Select None"
-msgstr "Selecciona un Node"
+msgstr "No seleccionar-ne cap"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -627,16 +651,18 @@ msgid "Line Number:"
msgstr "Línia:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d ocurrència/es reemplaçades."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Cap Coincidència"
+#, fuzzy
+msgid "%d match."
+msgstr "S'han trobat %d coincidències."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d ocurrència/es reemplaçades."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "S'han trobat %d coincidències."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -786,9 +812,8 @@ msgid "Connect"
msgstr "Connecta"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Senyals:"
+msgstr "Senyal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -865,8 +890,7 @@ msgstr "Favorits:"
msgid "Recent:"
msgstr "Recents:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -954,10 +978,8 @@ msgid "Owners Of:"
msgstr "Propietaris de:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr ""
-"Voleu Eliminar els fitxers seleccionats del projecte? (No es pot desfer!)"
+msgstr "Eliminar els fitxers seleccionats del projecte? (No es pot restaurar)"
#: editor/dependency_editor.cpp
msgid ""
@@ -968,7 +990,7 @@ msgstr ""
"Els fitxers seleccionats són utilitzats per altres recursos.\n"
"Voleu Eliminar-los de totes maneres? (No es pot desfer!)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "No es pot eliminar:"
@@ -1004,7 +1026,7 @@ msgstr "Voleu Eliminar permanentment %d element(s)? (No es pot desfer!)"
msgid "Show Dependencies"
msgstr "Mostrar Dependències"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Navegador de Recursos Orfes"
@@ -1093,14 +1115,16 @@ msgid "License"
msgstr "Llicència"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Llicència externa"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"El motor Godot es recolza en una sèrie de biblioteques lliures i de codi "
@@ -1121,7 +1145,8 @@ msgid "Licenses"
msgstr "Llicències"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Error en obrir el paquet d'arxius. El fitxer no té el format zip."
#: editor/editor_asset_installer.cpp
@@ -1138,7 +1163,6 @@ msgid "Success!"
msgstr "Èxit!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instal·la"
@@ -1510,8 +1534,11 @@ msgid "Template file not found:"
msgstr "No s'ha trobat la Plantilla:"
#: editor/editor_export.cpp
+#, fuzzy
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"En les exportacions de 32 bits, el PCK incrustat no pot ser més gran que 4 "
+"GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1623,12 +1650,11 @@ msgid "New"
msgstr "Nou"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importa"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportar"
@@ -1689,7 +1715,7 @@ msgstr "Mostrar en el Gestor de Fitxers"
msgid "New Folder..."
msgstr "Nou Directori..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Refresca"
@@ -1740,7 +1766,7 @@ msgstr "Endavant"
msgid "Go Up"
msgstr "Puja"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Commuta Fitxers Ocults"
@@ -1765,23 +1791,28 @@ msgid "Move Favorite Down"
msgstr "Mou Favorit Avall"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Directori Anterior"
+msgid "Go to previous folder."
+msgstr "Anar al directori anterior."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Directori Següent"
+msgid "Go to next folder."
+msgstr "Anar al directori següent."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Anar al directori pare."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Actualitzar Fitxers"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Eliminar carpeta actual de preferits."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Commutar visibilitat dels fitxers ocults."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2023,6 +2054,10 @@ msgstr "Neteja"
msgid "Clear Output"
msgstr "Buida la Sortida"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "L'exportació del projecte ha fallat amb el codi d'error %d."
@@ -2195,8 +2230,9 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
-"En ser un object remot, els canvis no es desaran.\n"
-"Referiu-vos a la documentació rellevant sobre la Depuració de codi."
+"Aquest és un objecte remot, de manera que els canvis no es conservaran.\n"
+"Si us plau, llegiu la documentació rellevant a la depuració per entendre "
+"millor aquest flux de treball."
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
@@ -2344,6 +2380,15 @@ msgid "Pick a Main Scene"
msgstr "Tria una Escena Principal"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Tanca l'Escena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Tanca l'Escena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"No es pot habilitar el complement a: '%s' ha fallat l'anàlisi de la "
@@ -2461,6 +2506,11 @@ msgstr "Reprodueix aquesta Escena"
msgid "Close Tab"
msgstr "Tanca la Pestanya"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Tanca la Pestanya"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Tanca les altres pestanyes"
@@ -2514,6 +2564,10 @@ msgid "Go to previously opened scene."
msgstr "Vés a l'escena oberta anteriorment."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar text"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Pestanya Següent"
@@ -2541,6 +2595,10 @@ msgstr "Nova Escena heretada..."
msgid "Open Scene..."
msgstr "Obre Escena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Obre Recent"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Desa Escena"
@@ -2550,14 +2608,6 @@ msgid "Save All Scenes"
msgstr "Desar Totes les Escenes"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Tanca l'Escena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Obre Recent"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Converteix a..."
@@ -2587,25 +2637,37 @@ msgstr "Reverteix Escena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Eines vàries o d'escena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projecte"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Configuració del Projecte"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Eines"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportar"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Instal·lar plantilla de compilació d'Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Obre el directori de Dades del Projecte"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Eines"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Instal·lar plantilla de compilació d'Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Navegador de Recursos Orfes"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2704,12 +2766,13 @@ msgstr ""
"En usar-se remotament en un dispositiu, un sistema de fitxers en xarxa en "
"millora el rendiment."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Configuració de l'Editor"
#: editor/editor_node.cpp
@@ -2727,14 +2790,6 @@ msgstr ""
"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"
@@ -2755,14 +2810,16 @@ msgid "Open Editor Settings Folder"
msgstr "Obre el directori de Configuració de l'Editor"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Administrar Característiques de l'Editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gestor de Plantilles d'Exportació"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ajuda"
@@ -2770,12 +2827,13 @@ msgstr "Ajuda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Cerca"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentació en línia"
@@ -2902,7 +2960,6 @@ 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 "
@@ -2910,8 +2967,8 @@ msgid ""
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ó."
+"Elimineu el directori 'build' manualment abans de tornar a intentar aquesta "
+"operació."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
@@ -3055,6 +3112,10 @@ msgstr "Temps"
msgid "Calls"
msgstr "Crides"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Editar Text:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Activat"
@@ -3220,7 +3281,8 @@ msgid "Import From Node:"
msgstr "Importa des del Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Torna a Baixar"
#: editor/export_template_manager.cpp
@@ -3237,6 +3299,10 @@ msgid "Download"
msgstr "Baixa"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mancant)"
@@ -3300,12 +3366,10 @@ msgid "No response."
msgstr "Cap resposta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Ha fallat la sol·licitud."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Bucle de redirecció."
@@ -3319,15 +3383,22 @@ msgid "Download Complete."
msgstr "Baixada Completa."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "No es pot desar el Tema:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"No s'han pogut instal·lar les plantilles. Els fitxers problemàtics es troben "
"a '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Error en la sol·licitud de l'url: "
#: editor/export_template_manager.cpp
@@ -3412,21 +3483,11 @@ msgstr "Baixa plantilles"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Selecciona un mirror de la llista: (Maj+Clic: Obre en el Navegador)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"No s'ha pogut escriure el fitxer file_type_cache.cch. No es desara el cau de "
-"tipus de fitxers!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Preferits"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "No es pot accedir a '%s'. No es troba en el sistema de fitxers!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "Estat: No s'ha pogut importar. Corregiu el fitxer i torneu a importar."
@@ -3459,14 +3520,14 @@ msgid "Provided name contains invalid characters."
msgstr "El nom proporcionat conté caràcters invàlids."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "El Nom conté caràcters que no són vàlids."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Ja existeix un Fitxer o Directori amb aquest nom."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "El Nom conté caràcters que no són vàlids."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Reanomenant fitxer:"
@@ -3522,6 +3583,11 @@ msgstr "Duplica..."
msgid "Move To..."
msgstr "Mou cap a..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nova Escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Script Nou..."
@@ -3585,6 +3651,11 @@ msgstr "Ja hi existex un fitxer o directori amb aquest nom."
msgid "Overwrite"
msgstr "Sobreescriu"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Crea-ho a partir de l'Escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Crea un Script"
@@ -3647,6 +3718,14 @@ msgid "Search complete"
msgstr "Cerca completa"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Afegeix al Grup"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Treu del Grup"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Aquest grup ja existeix."
@@ -3654,12 +3733,23 @@ msgstr "Aquest grup ja existeix."
msgid "Invalid group name."
msgstr "Nom del grup no vàlid."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gestiona Grups"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Elimina Disseny"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grups"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Els nodes no es troben en el Grup"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3672,12 +3762,13 @@ msgid "Nodes in Group"
msgstr "Nodes del Grup"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Afegeix al Grup"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Treu del Grup"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Editor de scripts"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3885,7 +3976,8 @@ msgid "MultiNode Set"
msgstr "Establir MultiNode"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Seleccioneu un Node per editar Senyals i Grups."
#: editor/plugin_config_dialog.cpp
@@ -4651,10 +4743,6 @@ msgid "View Files"
msgstr "Visualitza Fitxers"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "No es pot resoldre l'amfitrió:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "S'ha produït un error en la connexió. Torneu-ho a provar."
@@ -4667,14 +4755,47 @@ msgid "No response from host:"
msgstr "Cap resposta de l'amfitrió:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "No es pot resoldre l'amfitrió:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Ha fallat la sol·licitud, codi de devolució:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Ha fallat la sol·licitud."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "No es pot desar el Tema:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Ha fallat la sol·licitud. Massa redireccionaments"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Bucle de redirecció."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Ha fallat la sol·licitud, codi de devolució:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Temps"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Error en la baixada (hash incorrecte). El fitxer fou manipulat."
@@ -4715,6 +4836,10 @@ msgid "Idle"
msgstr "Inactiu"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instal·lar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Torneu a provar"
@@ -4743,13 +4868,17 @@ msgid "Last"
msgstr "Últim"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Tot"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "ReImporta..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Connectors"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4757,8 +4886,9 @@ msgid "Sort:"
msgstr "Ordena:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Inverteix"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Ordenació inversa."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4770,7 +4900,8 @@ msgid "Site:"
msgstr "Lloc:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Suport..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4782,6 +4913,11 @@ msgid "Testing"
msgstr "Provant"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Carregar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Arxiu ZIP d'Actius"
@@ -4840,32 +4976,32 @@ msgid "Rotation Step:"
msgstr "Pas de la Rotació:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Mou la guia vertical"
+msgid "Move Vertical Guide"
+msgstr "Moure guia vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Crea una nova guia vertical"
+msgid "Create Vertical Guide"
+msgstr "Crear guia vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Elimina la guia vertical"
+msgid "Remove Vertical Guide"
+msgstr "Eliminar guia vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Mou la guia horitzontal"
+msgid "Move Horizontal Guide"
+msgstr "Moure guia horitzontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Crea una nova guia horitzontal"
+msgid "Create Horizontal Guide"
+msgstr "Crear guia horitzontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Elimina la guia horitzontal"
+msgid "Remove Horizontal Guide"
+msgstr "Eliminar guia horitzontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Crea una guia horitzontal i vertical noves"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Crea guies horitzontal i vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4954,6 +5090,11 @@ msgid "Paste Pose"
msgstr "Enganxa Positura"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Reestableix la Postura"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Crea Os(sos) Personalitzat(s) a partir de Node(s)"
@@ -4985,6 +5126,7 @@ msgid "Zoom Reset"
msgstr "Restablir zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Mode de selecció"
@@ -5007,14 +5149,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Clic Dret: Selecció detallada per llista"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Mode de moviment"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Mode de Rotació"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Mode d'Escalat"
@@ -5040,6 +5185,7 @@ msgid "Toggle snapping."
msgstr "Commutar Ajustament."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Utilitzar Ajustament"
@@ -5057,11 +5203,6 @@ msgid "Use Rotation Snap"
msgstr "Utilitzar Ajustament de Rotació"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurar Ajustament..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Ajustament Relatiu"
@@ -5075,6 +5216,11 @@ msgid "Smart Snapping"
msgstr "Ajustament Intel·ligent"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Ajustament..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Ajustar al Pare"
@@ -5297,16 +5443,6 @@ msgstr "Estableix la Nansa"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Error en carregar la imatge:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Cap píxel amb transparència > 128 en la imatge..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Carrega una Màscara d'Emissió"
@@ -5626,14 +5762,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "La Superfície d'origen no és vàlida (li manquen cares)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "el node Pare no disposa de cares sòlides per omplir."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "No es pot mapar la zona."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selecciona una Malla d'Origen:"
@@ -5718,20 +5846,27 @@ msgid "Generation Time (sec):"
msgstr "Temps de generació (s):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Les Cares no tenen àrea!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "El Node no conté cap geometria (cares)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Cap Cara!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "El Node no conté cap geometria."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "El Node no conté cap geometria (cares)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "El Node no conté cap geometria."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6066,7 +6201,6 @@ msgid "Grid Settings"
msgstr "Configuració de la Quadrícula"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Ajustar"
@@ -6173,12 +6307,9 @@ msgid "Error writing TextFile:"
msgstr "Error en escriure el Fitxer de Text:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Error: No s'ha pogut carregar el fitxer."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Error no s'ha pogut carregar el fitxer."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "No s'ha trobat la tessel·la:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6201,7 +6332,8 @@ msgid "Error Importing"
msgstr "Error en Importar"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nou Fitxer de Text..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6284,6 +6416,11 @@ msgid "Open..."
msgstr "Obrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Obrir Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Desa-ho Tot"
@@ -6321,13 +6458,13 @@ msgid "Save Theme"
msgstr "Desa el Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Tanca la Documentació"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Tanca-ho Tot"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Tanca la Documentació"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Executar"
@@ -6416,6 +6553,11 @@ msgstr "Depurador"
msgid "Search Results"
msgstr "Resultats de cerca"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Buida les Escenes Recents"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Connexions al mètode:"
@@ -6485,6 +6627,7 @@ msgid "Syntax Highlighter"
msgstr "Ressaltador de sintaxi"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6520,24 +6663,6 @@ msgid "Toggle Comment"
msgstr "Comentaris"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Commutar Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Anar al marcador següent"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Anar al marcador anterior"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Suprimir tots els marcadors"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "(Des)Plega la línia"
@@ -6558,6 +6683,11 @@ msgid "Complete Symbol"
msgstr "Completa el Símbol"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Escala la Selecció"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Retalla els espais en blanc al final"
@@ -6574,29 +6704,34 @@ msgid "Auto Indent"
msgstr "Sagnat Automàtic"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Commuta el punt d'Interrupció"
+msgid "Find Previous"
+msgstr "Cerca l'Anterior"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Elimina tots els punts d'interrupció"
+msgid "Find in Files..."
+msgstr "Cercar en Fitxers..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Anar al Punt d'Interrupció següent"
+msgid "Contextual Help"
+msgstr "Ajuda Contextual"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Anar al Punt d'Interrupció anterior"
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "Commutar Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Cerca l'Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Anar al marcador següent"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Cercar en Fitxers..."
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Anar al marcador anterior"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Suprimir tots els marcadors"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6607,8 +6742,21 @@ msgid "Go to Line..."
msgstr "Anar a la Línia..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Ajuda Contextual"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Commuta el punt d'Interrupció"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Elimina tots els punts d'interrupció"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Anar al Punt d'Interrupció següent"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Anar al Punt d'Interrupció anterior"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6794,9 +6942,15 @@ msgid "Rear"
msgstr "Darrere"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+#, fuzzy
+msgid "Align Transform with View"
msgstr "Alinear amb la Vista"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Alinea la Selecció amb la Vista"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "No hi ha cap node Pare per instanciar-li un fill."
@@ -6850,8 +7004,9 @@ msgid "Audio Listener"
msgstr "Receptor d'Àudio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Activa Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Habilitar Filtració"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6907,8 +7062,8 @@ msgid "Snap Nodes To Floor"
msgstr "Ajustar Nodes al Terra"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Mode Selecció (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6921,30 +7076,11 @@ msgstr ""
"Alt+Clic Dret: Selecció de llista de profunditat"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Mode Moviment (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Mode Rotació (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Mode Escala (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordenades Locals"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Mode Espai Local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Mode d'Ajustament (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vista Inferior"
@@ -6985,26 +7121,6 @@ msgid "Focus Selection"
msgstr "Focalitza't en la Selecció"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Alinea la Selecció amb la Vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Selecciona una Eina"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Eina de Translació"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Eina de Rotació"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Eina d'Escala"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Vista Lliure"
@@ -7060,7 +7176,8 @@ msgstr "Mostra la Graella"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Configuració"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7373,10 +7490,6 @@ msgid "TextureRegion"
msgstr "Regió de Textura"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "No es pot desar el Tema:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Afegeix tots els Elements"
@@ -7463,12 +7576,12 @@ msgstr "Submenú"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Element"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Element"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7576,14 +7689,6 @@ msgid "Transpose"
msgstr "Transposa"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Replica en l'eix X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Replica en l'Eix Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "AutoTiles"
@@ -7599,8 +7704,8 @@ msgstr "Pinta Rajola"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Maj + RMB: dibuixar una línia\n"
"Maj + Ctrl + RMB: pintar rectangle"
@@ -7918,6 +8023,10 @@ msgid "TileSet"
msgstr "Conjunt de rajoles"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Afegeix una Entrada"
@@ -8009,6 +8118,11 @@ msgid "Duplicate Nodes"
msgstr "Duplicar Nodes"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Enganxa els Nodes"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Eliminar Nodes"
@@ -8030,6 +8144,11 @@ msgid "Light"
msgstr "Llum"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Crear node Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Crear node Shader"
@@ -8107,6 +8226,23 @@ msgid "Color uniform."
msgstr "Transforma"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Retorna l'invers de l'arrel quadrada del paràmetre."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8116,12 +8252,47 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
"Retorna un vector associat si el valor booleà proporcionat és cert o fals."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Retorna la tangent del paràmetre."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Boolean constant."
msgstr "Modificar una constant vectorial"
@@ -8220,7 +8391,8 @@ msgid "Returns the arc-cosine of the parameter."
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."
+#, fuzzy
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr "(Només GLES3) Retorna el cosinus hiperbòlic invers del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8228,7 +8400,8 @@ msgid "Returns the arc-sine of the parameter."
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."
+#, fuzzy
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr "(Només GLES3) Retorna el sinus hiperbòlic invers del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8240,7 +8413,8 @@ msgid "Returns the arc-tangent of the parameters."
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."
+#, fuzzy
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr "(Només GLES3) Retorna la tangent hiperbòlica inversa del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8257,7 +8431,8 @@ msgid "Returns the cosine of the parameter."
msgstr "Retorna el cosinus del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr "(Només GLES3) Retorna el cosinus hiperbòlic del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8326,11 +8501,13 @@ msgid "1.0 / scalar"
msgstr "1.0 / escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+#, fuzzy
+msgid "Finds the nearest integer to the parameter."
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."
+#, fuzzy
+msgid "Finds the nearest even integer to the parameter."
msgstr "(Només GLES3) Troba l'enter parell més proper al paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8346,7 +8523,8 @@ msgid "Returns the sine of the parameter."
msgstr "Retorna el sinus del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic sine of the parameter."
msgstr "(Només GLES3) Retorna el sinus hiperbòlic del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8357,7 +8535,7 @@ msgstr "Retorna l'arrel quadrada del paràmetre."
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8366,7 +8544,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8374,11 +8552,13 @@ msgid "Returns the tangent of the parameter."
msgstr "Retorna la tangent del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic tangent of the parameter."
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."
+#, fuzzy
+msgid "Finds the truncated value of the parameter."
msgstr "(Només GLES3) Troba el valor truncat del paràmetre."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8423,12 +8603,17 @@ msgstr "Realitza la cerca de textures."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "Modifica un Uniforme Textura"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "Modifica un Uniforme Textura"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "Modifica un Uniforme Textura"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8438,7 +8623,7 @@ msgstr "Funció de transformació."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8456,15 +8641,18 @@ msgid "Decomposes transform to four vectors."
msgstr "Descompon una transformació en quatre vectors."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+#, fuzzy
+msgid "Calculates the determinant of a transform."
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."
+#, fuzzy
+msgid "Calculates the inverse of a transform."
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."
+#, fuzzy
+msgid "Calculates the transpose of a transform."
msgstr "(Només GLES3) Calcula la transposició d'una transformació."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8515,12 +8703,18 @@ msgid "Calculates the dot product of two vectors."
msgstr "Calcula el producte escalar de dos vectors."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Retorna un vector que apunta en la mateixa direcció que un vector de "
+"referència. La funció té tres paràmetres vectorials: N, el vector a "
+"orientar, I, el vector incident, i Nref, el vector de referència. Si el "
+"producte de punt d'I i Nref és més petit que zero, el valor retornat és N. "
+"en cas contrari es retorna -N."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
@@ -8531,6 +8725,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Interpolació lineal entre dos vectors."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolació lineal entre dos vectors."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Calcula el producte normalitzar del vector."
@@ -8543,20 +8742,24 @@ msgid "1.0 / vector"
msgstr "1.0 / vector"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Retorna un vector que apunta en la direcció de la reflexió (a: vector "
+"d'incident, b: vector normal)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+#, fuzzy
+msgid "Returns the vector that points in the direction of refraction."
msgstr "Retorna un vector que apunta en la direcció de la refracció."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8565,7 +8768,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8574,14 +8777,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8633,47 +8836,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8821,8 +9031,9 @@ msgid "Compiled"
msgstr "Compilat"
#: editor/project_export.cpp
+#, fuzzy
msgid "Encrypted (Provide Key Below)"
-msgstr ""
+msgstr "Encriptat (Proporcioneu la clau a sota)"
#: editor/project_export.cpp
msgid "Invalid Encryption Key (must be 64 characters long)"
@@ -8849,6 +9060,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Manquen les plantilles d'exportació per aquesta plataforma:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gestor de Plantilles d'Exportació"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exporta en mode Depuració"
@@ -9007,6 +9222,15 @@ msgid "Unnamed Project"
msgstr "Projecte sense nom"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importa un Projecte existent"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "No es pot obrir el projecte a '%s'."
@@ -9015,6 +9239,7 @@ msgid "Are you sure to open more than one project?"
msgstr "Esteu segur que voleu obrir més d'un projecte de cop?"
#: editor/project_manager.cpp
+#, fuzzy
msgid ""
"The following project settings file does not specify the version of Godot "
"through which it was created.\n"
@@ -9026,8 +9251,17 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
+"El següent fitxer de configuració del projecte següent no especifica la "
+"versió de Godot amb la que s'ha creat.\n"
+"\n"
+"% s\n"
+"\n"
+"Si continueu amb l'obertura, es convertirà al format de fitxer de "
+"configuració actual de Godot.\n"
+"Advertiment: Ja no podreu obrir el projecte amb versions anteriors del 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"
@@ -9038,6 +9272,13 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
+"El següent fitxer de configuració del projecte va ser generat per una versió "
+"anterior del motor, i necessita ser convertit per a aquesta versió:\n"
+"\n"
+"% s\n"
+"\n"
+"Voleu convertir-lo?\n"
+"Advertiment: ja no podreu obrir el projecte amb versions anteriors del motor."
#: editor/project_manager.cpp
msgid ""
@@ -9087,12 +9328,13 @@ msgstr ""
"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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Eliminar tots els projectes que falten de la llista? (El contingut dels "
-"directoris no es modificarà)"
+"Eliminar %d projectes de la llista?\n"
+"El contingut del directori del projecte no es modificarà."
#: editor/project_manager.cpp
msgid ""
@@ -9117,8 +9359,9 @@ msgid "Project Manager"
msgstr "Gestor del Projecte"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Llista de Projectes"
+#, fuzzy
+msgid "Projects"
+msgstr "Projecte"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9142,10 +9385,6 @@ msgid "Templates"
msgstr "Plantilles"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Surt"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Reinicia"
@@ -9489,6 +9728,10 @@ msgstr "Localitzacions:"
msgid "AutoLoad"
msgstr "Càrrega Automàtica"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Connectors"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9541,14 +9784,6 @@ msgstr "Selecciona un Mètode Virtual"
msgid "Select Method"
msgstr "Selecciona un Mètode"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "No s'ha pogut executar l'eina PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "No es pot recarregar la imatge convertida amb PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9638,8 +9873,9 @@ msgid "Post-Process"
msgstr "Post-Processat"
#: editor/rename_dialog.cpp
+#, fuzzy
msgid "Keep"
-msgstr ""
+msgstr "Mantenir"
#: editor/rename_dialog.cpp
msgid "CamelCase to under_scored"
@@ -9844,6 +10080,11 @@ msgid "Remove Node(s)"
msgstr "Elimina els Nodes"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Modifica el Nom de l'Entrada"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9890,6 +10131,11 @@ msgstr "Estendre el script"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Torna a Parentar el Node"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Entesos!"
@@ -9967,23 +10213,25 @@ msgstr "Avís de Configuració del Node:"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"El Node té connexions i grups\n"
"Feu Clic per mostrar el Tauler de Senyals."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"El Node té connexions.\n"
"Feu Clic per mostrar el Tauler de Senyals."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"El Node està agrupat.\n"
@@ -10081,6 +10329,11 @@ msgid "Error loading script from %s"
msgstr "Error en carregar l'Script des de '%s'"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sobreescriu"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "No Disponible"
@@ -10109,7 +10362,8 @@ msgid "Script is valid."
msgstr "El script és vàlid."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Permesos: a-z, a-Z, 0-9 i _"
#: editor/script_create_dialog.cpp
@@ -10254,8 +10508,9 @@ msgid "Set From Tree"
msgstr "Estableix des de l'Arbre"
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Exporta les mesures com a CSV"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10270,6 +10525,10 @@ msgid "Change Shortcut"
msgstr "Canviar Drecera"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Configuració de l'Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Dreceres"
@@ -10702,10 +10961,32 @@ msgid "Set Variable Type"
msgstr "Estableix el Tipus de Variable"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"El Nom no és vàlid. No pot coincidir amb noms de tipus integrats ja "
+"existents."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Crear un nou rectangle."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variables:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Crear un nou rectangle."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Crear un nou polígon."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "El nom no és un identificador vàlid:"
@@ -10897,10 +11178,6 @@ msgid "Cut Nodes"
msgstr "Talla els Nodes"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Enganxa els Nodes"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Editar Membre"
@@ -10979,8 +11256,9 @@ msgid "Package name is missing."
msgstr "El nom del paquet falta."
#: platform/android/export/export.cpp
+#, fuzzy
msgid "Package segments must be of non-zero length."
-msgstr ""
+msgstr "Els segments de paquets han de ser de longitud no zero."
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
@@ -11008,25 +11286,35 @@ msgid "ADB executable not configured in the Editor Settings."
msgstr "L'executable ADB no està configurat a la configuració de l'editor."
#: platform/android/export/export.cpp
+#, fuzzy
msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr ""
+msgstr "OpenJDK Jarsigner no està configurat en la configuració de l'editor."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
msgstr ""
#: platform/android/export/export.cpp
+#, fuzzy
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"La compilació personalitzada requereix un camí d'Android SDK vàlid en la "
+"configuració de l'editor."
#: platform/android/export/export.cpp
+#, fuzzy
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"El camí de l'SDK d'Android no és vàlid per a la compilació personalitzada en "
+"la configuració de l'editor."
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"Android project is not installed for compiling. Install from Editor menu."
msgstr ""
+"El projecte Android no està instal·lat per a la compilació. Instal·leu-lo "
+"des del menú Editor."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -11037,32 +11325,47 @@ msgid "Invalid package name:"
msgstr "El nom del paquet no és vàlid:"
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Intentant construir des d'una plantilla personalitzada, però no existeix "
+"informació de versió per a això. Torneu a instal·lar des del menú 'projecte'."
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"Android build version mismatch:\n"
" Template installed: %s\n"
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"La versió de compilació d'Android no coincideix:\n"
+" Plantilla instal·lada:% s\n"
+" Versió de Godot:% s\n"
+"Torneu a instal·lar la plantilla de compilació d'Android des del menú "
+"'Projecte'."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
msgstr ""
#: platform/android/export/export.cpp
+#, fuzzy
msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
+"La construcció del projecte Android ha fallat, comproveu la sortida per "
+"l'error.\n"
+"Alternativament visiteu docs.godotengine.org per a la documentació de "
+"compilació d'Android."
#: platform/android/export/export.cpp
+#, fuzzy
msgid "No build apk generated at: "
-msgstr ""
+msgstr "No s'ha generat cap compilació apk a: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -11342,9 +11645,12 @@ msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
msgstr ""
#: scene/2d/skeleton_2d.cpp
+#, fuzzy
msgid ""
"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
msgstr ""
+"Aquest OS no té una postura de descans adequada. Aneu al node Skeleton2D i "
+"definiu-ne una."
#: scene/2d/tile_map.cpp
#, fuzzy
@@ -11495,14 +11801,19 @@ msgid "Plotting Meshes"
msgstr "S'estàn traçant les Malles"
#: scene/3d/gi_probe.cpp
+#, fuzzy
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
msgstr ""
+"Les GIProbes no estan suportades pel controlador de vídeo GLES2.\n"
+"Utilitzeu un BakedLightmap en el seu lloc."
#: scene/3d/light.cpp
+#, fuzzy
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Un SpotLight amb un angle més ample que 90 graus no pot projectar ombres."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11672,7 +11983,7 @@ msgstr "Trieu un color de la pantalla."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
@@ -11722,6 +12033,7 @@ msgstr ""
#: scene/gui/range.cpp
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
msgstr ""
+"Si l'opció \"Exp Edit\" està habilitada, \"Min Value\" ha de ser major que 0."
#: scene/gui/scroll_container.cpp
#, fuzzy
@@ -11758,22 +12070,6 @@ msgstr ""
"forma per tal d'obtenir-ne la mida. Altrament, establiu-la com a Destinació "
"de Renderització i assigneu-ne la textura interna a algun node."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Error inicialitzant FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Format de lletra desconegut."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error carregant lletra."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "La mida de la lletra no és vàlida."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrada"
@@ -11787,6 +12083,11 @@ msgstr "Font no vàlida pel Shader."
msgid "Invalid source for shader."
msgstr "Font no vàlida pel Shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Font no vàlida pel Shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Assignació a funció."
@@ -11801,7 +12102,128 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Les constants no es poden modificar."
+
+#~ msgid "No Matches"
+#~ msgstr "Cap Coincidència"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "No s'ha pogut escriure el fitxer file_type_cache.cch. No es desara el cau "
+#~ "de tipus de fitxers!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "No es pot accedir a '%s'. No es troba en el sistema de fitxers!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Error en carregar la imatge:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Cap píxel amb transparència > 128 en la imatge..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "el node Pare no disposa de cares sòlides per omplir."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "No es pot mapar la zona."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Les Cares no tenen àrea!"
+
+#~ msgid "No faces!"
+#~ msgstr "Cap Cara!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Error: No s'ha pogut carregar el fitxer."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Error no s'ha pogut carregar el fitxer."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Activa Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Mode Selecció (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Mode Moviment (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Mode Rotació (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Mode Escala (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordenades Locals"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Mode d'Ajustament (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Selecciona una Eina"
+
+#~ msgid "Tool Move"
+#~ msgstr "Eina de Translació"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Eina de Rotació"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Eina d'Escala"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Eliminar tots els projectes que falten de la llista? (El contingut dels "
+#~ "directoris no es modificarà)"
+
+#~ msgid "Project List"
+#~ msgstr "Llista de Projectes"
+
+#~ msgid "Exit"
+#~ msgstr "Surt"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "No s'ha pogut executar l'eina PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "No es pot recarregar la imatge convertida amb PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Error inicialitzant FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Format de lletra desconegut."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error carregant lletra."
+
+#~ msgid "Invalid font size."
+#~ msgstr "La mida de la lletra no és vàlida."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Directori Anterior"
+
+#~ msgid "Next Folder"
+#~ msgstr "Directori Següent"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Obrir automàticament captures de pantalla"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Obrir en un editor d'imatges extern."
+
+#~ msgid "Reverse"
+#~ msgstr "Inverteix"
+
+#~ msgid "Mirror X"
+#~ msgstr "Replica en l'eix X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Replica en l'Eix Y"
#~ msgid "Generating solution..."
#~ msgstr "S'està generant la solució..."
@@ -12415,9 +12837,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Elimina la Selecció"
-#~ msgid "Could not find tile:"
-#~ msgstr "No s'ha trobat la tessel·la:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nom o ID de l'Element:"
@@ -12659,9 +13078,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "Informació"
-#~ msgid "Re-Import..."
-#~ msgstr "ReImporta..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Cap màscara de bits per importar!"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index c9fbafaf13..a9cae4a444 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -11,12 +11,14 @@
# zxey <r.hozak@seznam.cz>, 2018.
# Vojtěch Šamla <auzkok@seznam.cz>, 2018, 2019.
# Peeter Angelo <contact@peeterangelo.com>, 2019.
+# VojtechBrezina <vojta.brezina@gmail.com>, 2019.
+# Garrom Orc Shaman <garromorcshaman@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:46+0000\n"
-"Last-Translator: Martin Novák <maidx@seznam.cz>\n"
+"PO-Revision-Date: 2019-08-21 15:57+0000\n"
+"Last-Translator: VojtechBrezina <vojta.brezina@gmail.com>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/"
"cs/>\n"
"Language: cs\n"
@@ -24,7 +26,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -67,7 +69,6 @@ msgid "On call to '%s':"
msgstr "Při volání '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Volný"
@@ -136,6 +137,26 @@ msgid "Anim Change Call"
msgstr "Animace: změna volání"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animace: ZmÄ›nit Äas klíÄových snímků"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Animace: změna přechodů"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Animace: změna transformací"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animace: ZmÄ›nit hodnotu klíÄových snímků"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Animace: změna volání"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Změnit délku animace"
@@ -207,7 +228,7 @@ msgstr "Aktivovat/Deaktivovat tuto stopu."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "Režim aktualizece (jak je tato vlastnost nastavena)"
+msgstr "Režim aktualizace (jak je tato vlastnost nastavena)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -266,7 +287,6 @@ msgid "Clamp Loop Interp"
msgstr "Režim svorkové smyÄky"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Wrap Loop Interp"
msgstr "Interpolace ovinutou smyÄkou"
@@ -292,9 +312,8 @@ msgid "Change Animation Interpolation Mode"
msgstr "Změnit režim interpolace animace"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Loop Mode"
-msgstr "ZmÄ›nit smyÄku animace"
+msgstr "ZmÄ›nit režim smyÄky animace"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -325,7 +344,7 @@ msgstr "Animace: vložit"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr "AnimationPlayer nemůže animovat sám sebe, pouze ostatní."
+msgstr "AnimationPlayer nemůže animovat sám sebe, pouze ostatní pÅ™ehrávaÄe."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
@@ -388,23 +407,20 @@ msgid "Track is not of type Spatial, can't insert key"
msgstr "Stopa není typu Spatial, nelze vložit klíÄ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Transform Track Key"
-msgstr "Stopa 3D transformace"
+msgstr "PÅ™idat klÃ­Ä stopy transformace"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "Přidat stopu"
+msgstr "PÅ™idat klÃ­Ä stopy"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
msgstr "Cesta stopy není validní, nelze vložit klÃ­Ä metody."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "Stopa volání metody"
+msgstr "PÅ™idat klÃ­Ä volání metody"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
@@ -427,12 +443,11 @@ 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."
+"Tato možnost nefunguje pro úpravy Beziérovy křivky , protože se jedná pouze "
+"o jednu stopu."
#: editor/animation_track_editor.cpp
msgid ""
@@ -446,6 +461,15 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Tato animace patří k importované scéně, takže změny na importovaných stopách "
+"nebudou uloženy\n"
+"\n"
+"Aby jste povolily možnost přidávat vlastní stopy, běžte do nastavení importu "
+"této scény a nastavte\n"
+"\"Animace > Úložiště\" na \"Soubory\", Povolte \"Animace > Ponechat vlastní "
+"stopy\", poté re-importujte.\n"
+"Alternativně použijte přednastavení importu které importuje animace do "
+"separovaných souborů."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
@@ -457,9 +481,8 @@ msgid "Select All"
msgstr "Vybrat vše"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Vybrat uzel"
+msgstr "Nevybrat nic"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -604,17 +627,16 @@ msgid "Copy"
msgstr "Kopírovat"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Audio klipy:"
+msgstr "Přidat klip audio stopy"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "ZmÄ›nit poÄáteÄní pozici audio klipu"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "Změnit koncovou pozici audio klipu"
#: editor/array_property_edit.cpp
msgid "Resize Array"
@@ -637,16 +659,18 @@ msgid "Line Number:"
msgstr "Číslo řádku:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Nahrazeno %d výskytů."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Žádné shody"
+#, fuzzy
+msgid "%d match."
+msgstr "Nalezeno %d shod(a)."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Nahrazeno %d výskytů."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Nalezeno %d shod(a)."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -698,33 +722,28 @@ msgid "Line and column numbers."
msgstr "Čísla řádků a sloupců."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "Je nutné zadat metodu v cílovém uzlu!"
+msgstr "Je nutné zadat metodu v cílovém uzlu."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"Cílová metoda nenalezena! Specifikujte existující metodu, nebo k cílovému "
+"Cílová metoda nenalezena. Specifikujte existující metodu, nebo k cílovému "
"uzlu připojte skript."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Node:"
msgstr "Připojit k uzlu:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "Nelze se připojit k hostiteli:"
+msgstr "Připojit ke skriptu:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "Signály:"
+msgstr "Z signálu:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
@@ -756,9 +775,8 @@ msgid "Extra Call Arguments:"
msgstr "Další argumenty volání:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "PokroÄilé možnosti"
+msgstr "PokroÄilé"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -833,7 +851,7 @@ msgstr "Připojit Signál: "
#: editor/connections_dialog.cpp
#, fuzzy
msgid "Edit Connection:"
-msgstr "Upravit připojení: "
+msgstr "Upravit připojení:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
@@ -881,8 +899,7 @@ msgstr "Oblíbené:"
msgid "Recent:"
msgstr "Nedávné:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -985,7 +1002,7 @@ msgstr ""
"Soubory ke smazání potÅ™ebují jiné zdroje ke své Äinnosti.\n"
"Přesto je chcete smazat? (nelze vrátit zpět)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nelze odstranit:"
@@ -1023,7 +1040,7 @@ msgstr "Permanentně smazat %d položek? (nelze vrátit zpět!)"
msgid "Show Dependencies"
msgstr "Závislosti"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Průzkumník osiřelých zdrojů"
@@ -1112,14 +1129,16 @@ msgid "License"
msgstr "Licence"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licence třetích stran"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine závisí na volně dostupných a open source knihovnách od třetích "
@@ -1140,7 +1159,8 @@ msgid "Licenses"
msgstr "Licence"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "NepodaÅ™ilo se otevřít balíÄek, není ve formátu zip."
#: editor/editor_asset_installer.cpp
@@ -1158,7 +1178,6 @@ msgid "Success!"
msgstr "Úspěch!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalovat"
@@ -1534,9 +1553,8 @@ 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
@@ -1656,12 +1674,11 @@ msgid "New"
msgstr "Nový"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importovat"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportovat"
@@ -1729,7 +1746,7 @@ msgstr "Zobrazit ve správci souborů"
msgid "New Folder..."
msgstr "Nová složka..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Obnovit"
@@ -1780,7 +1797,7 @@ msgstr "Jit dopředu"
msgid "Go Up"
msgstr "Jít o úroveň výš"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Zobrazit skryté soubory"
@@ -1805,26 +1822,33 @@ msgid "Move Favorite Down"
msgstr "Přesunout oblíbenou položku dolů"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Předchozí složka"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Jít na nadřazenou složku"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Další složka"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Jít na nadřazenou složku"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Jít na nadřazenou složku"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Hledat soubory"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Nelze vytvořit složku."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Zobrazit skryté soubory"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2067,6 +2091,10 @@ msgstr "VyÄistit"
msgid "Clear Output"
msgstr "Vymazat výstup"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Export projektu selhal s chybovým kódem %d."
@@ -2388,6 +2416,15 @@ msgid "Pick a Main Scene"
msgstr "Vybrat hlavní scénu"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Zavřít scénu"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Zavřít scénu"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Nelze povolit rozšiřující plugin: '%s' parsování konfigurace se nezdařilo."
@@ -2495,6 +2532,11 @@ msgstr "Spustit tuto scénu"
msgid "Close Tab"
msgstr "Zavřít záložku"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Zavřít záložku"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Zavřít ostatní záložky"
@@ -2549,6 +2591,11 @@ msgid "Go to previously opened scene."
msgstr "Přejít na předchozí scénu."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopírovat cestu"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Další záložka"
@@ -2576,6 +2623,10 @@ msgstr "Nová odvozená scéna..."
msgid "Open Scene..."
msgstr "Otevřít scénu..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Otevřít nedávné"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Uložit scénu"
@@ -2585,14 +2636,6 @@ msgid "Save All Scenes"
msgstr "Uložit všechny scény"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Zavřít scénu"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Otevřít nedávné"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konvertovat na..."
@@ -2622,25 +2665,36 @@ msgstr "Vrátit scénu"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Různé nástroje pro projekt nebo scény."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Nastavení projektu"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Nástroje"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportovat"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Otevřít složku s daty projektu"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Nástroje"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Průzkumník osiřelých zdrojů"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2737,12 +2791,13 @@ msgstr ""
"Při použití se vzdáleným spuštěním je toto více efektivní při použití "
"síťového souborového systému."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Nastavení editoru"
#: editor/editor_node.cpp
@@ -2760,15 +2815,6 @@ 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"
@@ -2791,14 +2837,15 @@ msgstr "Otevřít složku s nastavením editoru"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Spravovat exportní šablony"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Spravovat exportní šablony"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Nápověda"
@@ -2806,12 +2853,13 @@ msgstr "Nápověda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Hledat"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online dokumentace"
@@ -3087,6 +3135,11 @@ msgstr "ÄŒas"
msgid "Calls"
msgstr "Volání"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Editovat téma..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3254,7 +3307,8 @@ msgid "Import From Node:"
msgstr "Import z uzlu:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Stáhnout znovu"
#: editor/export_template_manager.cpp
@@ -3271,6 +3325,10 @@ msgid "Download"
msgstr "Stáhnout"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Nenalezeno)"
@@ -3334,12 +3392,10 @@ msgid "No response."
msgstr "Žádná odpovÄ›Ä."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Požadavek se nezdařil."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Zacyklené přesměrování."
@@ -3353,14 +3409,21 @@ msgid "Download Complete."
msgstr "Stahování dokonÄeno."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nelze uložit motiv do souboru:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Instalace šablon selhala. Problémové archivy šablon lze nalézt na '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Chyba požadavku o url: "
#: editor/export_template_manager.cpp
@@ -3447,21 +3510,11 @@ msgstr "Stáhnout šablony"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Zvolte zrcadlo ze seznamu: (Shift + Klik: OtevÅ™it v prohlížeÄi)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Nelze otevřít file_type_cache.cch pro zápis, cache typů souborů není "
-"ukládána!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Oblíbené"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Nelze přejít k '%s', protože nebylo nalezeno v souborovém systému!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Status: import souboru selhal. Opravte, prosím, soubor a naimportujte ho "
@@ -3497,14 +3550,14 @@ msgid "Provided name contains invalid characters."
msgstr "Poskytnuté jméno obsahuje neplatné znaky"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Jméno obsahuje neplatné znaky."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Soubor nebo složka s tímto názvem již existuje."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Jméno obsahuje neplatné znaky."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Přejmenovávání souboru:"
@@ -3564,6 +3617,11 @@ msgstr "Duplikovat..."
msgid "Move To..."
msgstr "Přesunout do..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nová scéna"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nový skript..."
@@ -3632,6 +3690,11 @@ msgstr "Soubor nebo složka se stejným názvem již na tomto místě existuje."
msgid "Overwrite"
msgstr "Přepsat"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Vytvořit ze scény"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Vytvořit skript"
@@ -3692,6 +3755,14 @@ msgid "Search complete"
msgstr "Vyhledávání dokonÄeno"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Přidat do skupiny"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Odebrat ze skupiny"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Název skupiny již existuje."
@@ -3699,12 +3770,23 @@ msgstr "Název skupiny již existuje."
msgid "Invalid group name."
msgstr "Neplatný název skupiny."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Spravovat skupiny"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Odstranit rozložení"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Skupiny"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Uzly nejsou ve skupinÄ›"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3717,12 +3799,13 @@ msgid "Nodes in Group"
msgstr "Uzly jsou ve skupinÄ›"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Přidat do skupiny"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Odebrat ze skupiny"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Otevřít editor skriptů"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3930,7 +4013,8 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Zvolit uzel pro editaci signálů a skupin."
#: editor/plugin_config_dialog.cpp
@@ -4689,10 +4773,6 @@ msgid "View Files"
msgstr "Zobrazit soubory"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Nelze přeložit název hostitele:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Chyba připojení, zkuste to prosím znovu."
@@ -4705,14 +4785,47 @@ msgid "No response from host:"
msgstr "Žádná odpovÄ›Ä od hostitele:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Nelze přeložit název hostitele:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Požadavek se nezdařil, návratový kód:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Požadavek se nezdařil."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nelze uložit motiv do souboru:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Požadavek se nezdařil, příliš mnoho přesměrování"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Zacyklené přesměrování."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Požadavek se nezdařil, návratový kód:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ÄŒas"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Špatný hash staženého souboru, soubor byl nejspíše zfalšován."
@@ -4753,6 +4866,11 @@ msgid "Idle"
msgstr "NeÄinný"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Instalovat"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Opakovat"
@@ -4781,13 +4899,17 @@ msgid "Last"
msgstr "Poslední"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "VÅ¡echny"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importovat"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Pluginy"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4795,8 +4917,9 @@ msgid "Sort:"
msgstr "Řadit:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Naopak"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Posílá se žádost..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4808,7 +4931,8 @@ msgid "Site:"
msgstr "Web:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Podpora..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4820,6 +4944,11 @@ msgid "Testing"
msgstr "Testované"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "NaÄíst..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP soubor asetů"
@@ -4871,31 +5000,38 @@ msgid "Rotation Step:"
msgstr "Krok rotace:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Přesunout svislé vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Vytvořit nové svislé vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Odstranit svislé vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Přesunout vodorovné vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Vytvořit nové vodorovné vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Odstranit vodorovné vodítko"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Vytvořit nové vodorovné a svislé vodítka"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4980,6 +5116,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Vymazat pózu"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Vytvořit ze scény"
@@ -5009,6 +5150,7 @@ msgid "Zoom Reset"
msgstr "Resetovat zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Režim výběru"
@@ -5030,14 +5172,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Pravé tlaÄíko myÅ¡i:"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Režim přesouvání"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Režim otáÄení"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Režim škálování"
@@ -5061,6 +5206,7 @@ msgid "Toggle snapping."
msgstr "Přepnout přichycování."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Použít přichycování"
@@ -5078,11 +5224,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Nastavení přichytávání..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5096,6 +5237,11 @@ msgid "Smart Snapping"
msgstr "Chytré přichytávání"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Nastavení přichytávání..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "PÅ™ichytit k rodiÄovi"
@@ -5314,16 +5460,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Chyba při nahrávání obrázku:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Žádný pixel s průhledností > 128 v obrázku..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "NaÄíst emisní masku"
@@ -5647,14 +5783,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5739,19 +5867,24 @@ msgid "Generation Time (sec):"
msgstr "Čas generování (sec):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Scéna neobsahuje žádný skript."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6085,7 +6218,6 @@ msgid "Grid Settings"
msgstr "Nastavení mřížky"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Přichytit"
@@ -6192,11 +6324,8 @@ msgid "Error writing TextFile:"
msgstr "Chyba při zápisu textového souboru:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Chyba: nelze naÄíst soubor."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+#, fuzzy
+msgid "Could not load file at:"
msgstr "Chyba: nelze naÄíst soubor."
#: editor/plugins/script_editor_plugin.cpp
@@ -6220,7 +6349,8 @@ msgid "Error Importing"
msgstr "Chyba importu"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nový textový soubor..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6304,6 +6434,11 @@ msgid "Open..."
msgstr "Otevřít..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Otevřít skript"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Uložit vše"
@@ -6342,13 +6477,13 @@ msgid "Save Theme"
msgstr "Uložit motiv"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Zavřít dokumentaci"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Zavřít vše"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Zavřít dokumentaci"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Spustit"
@@ -6438,6 +6573,11 @@ msgstr "Ladicí program"
msgid "Search Results"
msgstr "Výsledky hledání"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Vymazat nedávné scény"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6508,6 +6648,7 @@ msgid "Syntax Highlighter"
msgstr "ZvýrazňovaÄ syntaxe"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6543,26 +6684,6 @@ msgid "Toggle Comment"
msgstr "Přepnout komentář"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Přepnout volný pohled"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Přejít na další breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Přejít na předchozí breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Odstranit všechny položky"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Složit/Rozložit řádek"
@@ -6583,6 +6704,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Změnit měřítko výběru"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Osekat koncové mezery"
@@ -6599,29 +6725,36 @@ msgid "Auto Indent"
msgstr "Automatické odsazení"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Přepnout breakpoint"
+msgid "Find Previous"
+msgstr "Najít předchozí"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Odstranit všechny breakpointy"
+msgid "Find in Files..."
+msgstr "Najít v souborech..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Přejít na další breakpoint"
+msgid "Contextual Help"
+msgstr "Kontextová nápověda"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Přejít na předchozí breakpoint"
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "Přepnout volný pohled"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Najít předchozí"
+#, fuzzy
+msgid "Go to Next Bookmark"
+msgstr "Přejít na další breakpoint"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Najít v souborech..."
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Přejít na předchozí breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr "Odstranit všechny položky"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6632,8 +6765,21 @@ msgid "Go to Line..."
msgstr "Přejít na řádek..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Kontextová nápověda"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Přepnout breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Odstranit všechny breakpointy"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Přejít na další breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Přejít na předchozí breakpoint"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6815,9 +6961,14 @@ msgstr "Zadní"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "Zarovnat s výhledem"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Zarovnat výběr s pohledem"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr ""
@@ -6873,8 +7024,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Doppler Enable"
-msgstr "Povolit"
+msgid "Enable Doppler"
+msgstr "Povolit filtrování"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6929,8 +7080,8 @@ msgid "Snap Nodes To Floor"
msgstr "Přichytit k mřížce"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Režim výběru (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6943,30 +7094,10 @@ msgstr ""
"Alt+Pravé tlaÄíko myÅ¡i: VýbÄ›r seznamu hloubky"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Režim posunu (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Režim otáÄení (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Režim zvětšování (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Místní souřadnice"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Režim přichycení (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Pohled zdola"
@@ -7008,26 +7139,6 @@ msgid "Focus Selection"
msgstr "Zaměřit výběr"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Zarovnat výběr s pohledem"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Nástroj Výběr"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Nástroj Přesunout"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Nástroj OtoÄit"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Nástroj Zvětšení"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Přepnout volný pohled"
@@ -7083,7 +7194,8 @@ msgstr "Zobrazit mřížku"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Nastavení"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7395,10 +7507,6 @@ msgid "TextureRegion"
msgstr "Oblast textury"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Nelze uložit motiv do souboru:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Přidat všechny položky"
@@ -7489,12 +7597,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Položka"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Položka"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7602,14 +7710,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Zrcadlit X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Zrcadlit Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7624,8 +7724,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7939,6 +8039,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Přidat vstup"
@@ -8030,6 +8134,11 @@ msgid "Duplicate Nodes"
msgstr "Duplikovat uzel/uzly"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Vložit uzly"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Smazat uzel"
@@ -8052,6 +8161,11 @@ msgstr "Světlo"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Vytvořit uzel"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Vytvořit uzel"
@@ -8130,6 +8244,23 @@ msgid "Color uniform."
msgstr "Animace: změna transformace"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Vrátí inverzní odmocninu z parametru."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8137,10 +8268,45 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Vrátí tangens parametru."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8232,7 +8398,8 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "Vrátí arkus kosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+#, fuzzy
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr "(Pouze GLES3) Vrátí inverzní hyperbolický kosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8240,7 +8407,8 @@ msgid "Returns the arc-sine of the parameter."
msgstr "Vrátí arkus sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+#, fuzzy
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr "(Pouze GLES3) Vrátí inverzní hyperbolický sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8252,7 +8420,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "Vrátí arkus tangent parametrů."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+#, fuzzy
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr "(Pouze GLES3) Vrátí inverzní hyperbolický tangent parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8270,7 +8439,8 @@ msgid "Returns the cosine of the parameter."
msgstr "Vrátí kosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr "(Pouze GLES3) Vrátí hyperbolický kosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8339,11 +8509,13 @@ msgid "1.0 / scalar"
msgstr "1.0 / skalár"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+#, fuzzy
+msgid "Finds the nearest integer to the parameter."
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."
+#, fuzzy
+msgid "Finds the nearest even integer to the parameter."
msgstr "(Pouze GLES3) Nalezne nejbližší sudé celé Äíslo k parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8359,7 +8531,8 @@ msgid "Returns the sine of the parameter."
msgstr "Vrátí sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic sine of the parameter."
msgstr "(Pouze GLES3) Vrátí hyperbolický sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8370,7 +8543,7 @@ msgstr "Vrátí odmocninu parametru."
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8379,7 +8552,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8387,12 +8560,14 @@ msgid "Returns the tangent of the parameter."
msgstr "Vrátí tangens parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+#, fuzzy
+msgid "Returns the hyperbolic tangent of the parameter."
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."
-msgstr ""
+#, fuzzy
+msgid "Finds the truncated value of the parameter."
+msgstr "Vrátí absolutní hodnotu parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8433,11 +8608,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8447,7 +8626,7 @@ msgstr "Transformovat polygon"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8465,15 +8644,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8525,7 +8704,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8540,6 +8719,11 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Lineární interpolace mezi dvěma skaláry."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8553,19 +8737,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8574,7 +8758,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8583,14 +8767,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8635,47 +8819,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8847,6 +9038,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Exportní šablony pro tuto platformu chybí:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Spravovat exportní šablony"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8994,6 +9189,15 @@ msgid "Unnamed Project"
msgstr "Nepojmenovaný projekt"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Sestavit projekt"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Nelze otevřít projekt v '%s'."
@@ -9067,8 +9271,8 @@ msgstr "Odstranit projekt ze seznamu? (Obsah složky zůstane nedotÄen)"
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "Odstranit projekt ze seznamu? (Obsah složky zůstane nedotÄen)"
#: editor/project_manager.cpp
@@ -9088,8 +9292,9 @@ msgid "Project Manager"
msgstr "Správce projektů"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Seznam projektů"
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9113,10 +9318,6 @@ msgid "Templates"
msgstr "Å ablony"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "UkonÄit"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Restartovat nyní"
@@ -9467,6 +9668,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Pluginy"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Nula"
@@ -9519,14 +9724,6 @@ msgstr "Vybrat virtuální metodu"
msgid "Select Method"
msgstr "Vybrat metodu"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Dávkové přejmenování"
@@ -9818,6 +10015,11 @@ msgid "Remove Node(s)"
msgstr "Odstranit uzel/uzly"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Změnit název vstupu"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9864,6 +10066,11 @@ msgstr "Otevřít skript"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Přidat/Vytvořit nový uzel"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Dává smysl!"
@@ -9940,19 +10147,19 @@ msgstr "Varování konfigurace uzlu:"
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10051,6 +10258,11 @@ msgid "Error loading script from %s"
msgstr "Chyba nahrávání skriptu z %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Přepsat"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
@@ -10084,7 +10296,8 @@ msgid "Script is valid."
msgstr "Skript je validní"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Povoleno: a-z, A-Z, 0-9 a _"
#: editor/script_create_dialog.cpp
@@ -10250,6 +10463,10 @@ msgid "Change Shortcut"
msgstr "Upravit kotvy"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Nastavení editoru"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Zkratky"
@@ -10682,10 +10899,31 @@ msgid "Set Variable Type"
msgstr "Nastavit typ proměnné"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Neplatný název. Nesmí kolidovat s existujícím jménem zabudovaného typu."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Vytvořit nové uzly."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Proměnné:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Vytvořit nové uzly."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Vytvořit nový polygon."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Jméno není platný identifikátor:"
@@ -10880,10 +11118,6 @@ msgid "Cut Nodes"
msgstr "Vyjmout uzly"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Vložit uzly"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Členové"
@@ -11704,22 +11938,6 @@ msgstr ""
"mohl získat velikost. Jinak ho nastavte jako render target a pÅ™iÅ™aÄte jeho "
"vnitřní texturu nějakému uzlu k zobrazení."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Chyba při inicializaci FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Neznámý formát fontu."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Chyba nahrávání fontu."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Neplatná velikost fontu."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Vstup"
@@ -11733,6 +11951,11 @@ msgstr "Neplatný zdroj pro shader."
msgid "Invalid source for shader."
msgstr "Neplatný zdroj pro shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Neplatný zdroj pro shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11749,6 +11972,104 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanty není možné upravovat."
+#~ msgid "No Matches"
+#~ msgstr "Žádné shody"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Nelze otevřít file_type_cache.cch pro zápis, cache typů souborů není "
+#~ "ukládána!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Nelze přejít k '%s', protože nebylo nalezeno v souborovém systému!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Chyba při nahrávání obrázku:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Žádný pixel s průhledností > 128 v obrázku..."
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Chyba: nelze naÄíst soubor."
+
+#, fuzzy
+#~ msgid "Doppler Enable"
+#~ msgstr "Povolit"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Režim výběru (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Režim posunu (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Režim otáÄení (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Režim zvětšování (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Místní souřadnice"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Režim přichycení (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Nástroj Výběr"
+
+#~ msgid "Tool Move"
+#~ msgstr "Nástroj Přesunout"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Nástroj OtoÄit"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Nástroj Zvětšení"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "Odstranit projekt ze seznamu? (Obsah složky zůstane nedotÄen)"
+
+#~ msgid "Project List"
+#~ msgstr "Seznam projektů"
+
+#~ msgid "Exit"
+#~ msgstr "UkonÄit"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Chyba při inicializaci FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Neznámý formát fontu."
+
+#~ msgid "Error loading font."
+#~ msgstr "Chyba nahrávání fontu."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Neplatná velikost fontu."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Předchozí složka"
+
+#~ msgid "Next Folder"
+#~ msgstr "Další složka"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Otevřít další editor"
+
+#~ msgid "Reverse"
+#~ msgstr "Naopak"
+
+#~ msgid "Mirror X"
+#~ msgstr "Zrcadlit X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Zrcadlit Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Generování řešení..."
@@ -11779,9 +12100,6 @@ msgstr "Konstanty není možné upravovat."
#~ msgid "Builds"
#~ msgstr "Sestavení"
-#~ msgid "Build Project"
-#~ msgstr "Sestavit projekt"
-
#~ msgid "View log"
#~ msgstr "Zobrazit logy"
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 103fc7ef35..bacbf07ff6 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -67,7 +67,6 @@ msgid "On call to '%s':"
msgstr "Ved kald til '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Gratis"
@@ -139,6 +138,31 @@ msgstr "Anim Skift Call"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Skift Keyframetid"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Skift Overgang"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Skift Transformering"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Skift Keyframeværdi"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Skift Call"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Ændre Animation Navn:"
@@ -645,17 +669,18 @@ msgid "Line Number:"
msgstr "Linjenummer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Erstattede %d forekomst(er)."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Ingen Match"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Erstattede %d forekomst(er)."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Match stor/lille"
@@ -890,8 +915,7 @@ msgstr "Favoritter:"
msgid "Recent:"
msgstr "Seneste:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -994,7 +1018,7 @@ msgstr ""
"De filer der fjernes er nødvendige for, at andre ressourcer kan fungere.\n"
"Fjern dem alligevel? (ej fortrydes)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Kan ikke fjerne:"
@@ -1031,7 +1055,7 @@ msgstr "Slette %d styk(s) permanent? (ej fortryd)"
msgid "Show Dependencies"
msgstr "Afhængigheder"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Forældreløs ressource udforsker"
@@ -1120,14 +1144,16 @@ msgid "License"
msgstr "Licens"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Tredjeparts Licens"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine er afhængig af en række tredjeparts biblioteker som er gratis "
@@ -1148,7 +1174,8 @@ msgid "Licenses"
msgstr "Licenser"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Fejl ved åbning af pakke fil, ikke i zip format."
#: editor/editor_asset_installer.cpp
@@ -1165,7 +1192,6 @@ msgid "Success!"
msgstr "Succes!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installér"
@@ -1662,12 +1688,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importer"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Eksport"
@@ -1735,7 +1760,7 @@ msgstr "Vis i Filhåndtering"
msgid "New Folder..."
msgstr "Opret mappe..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Opdater"
@@ -1786,7 +1811,7 @@ msgstr "GÃ¥ Fremad"
msgid "Go Up"
msgstr "GÃ¥ Op"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Skifter Skjulte Filer"
@@ -1812,27 +1837,32 @@ msgstr "Flyt Favorit Ned"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Forrige fane"
+msgid "Go to previous folder."
+msgstr "GÃ¥ til overliggende mappe"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Opret Mappe"
+msgid "Go to next folder."
+msgstr "GÃ¥ til overliggende mappe"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "GÃ¥ til overliggende mappe"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Søg Classes"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Kunne ikke oprette mappe."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Skifter Skjulte Filer"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2076,6 +2106,10 @@ msgstr "Clear"
msgid "Clear Output"
msgstr "Ryd Output"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Projekt eksport fejlede med fejlkode %d."
@@ -2396,6 +2430,15 @@ msgid "Pick a Main Scene"
msgstr "Vælg en Main Scene"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Luk Scene"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Luk Scene"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Kan ikke aktivere addon plugin ved: '%s' parsing af konfiguration "
@@ -2509,6 +2552,11 @@ msgstr "Spil denne Scene"
msgid "Close Tab"
msgstr "Luk faneblad"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Luk faneblad"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2563,6 +2611,11 @@ msgid "Go to previously opened scene."
msgstr "Gå til den forrige åbnede scene."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopier Sti"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Næste fane"
@@ -2590,6 +2643,10 @@ msgstr "Ny Nedarvet Scene..."
msgid "Open Scene..."
msgstr "Ã…bn Scene..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Ã…ben Seneste"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Gem Scene"
@@ -2599,14 +2656,6 @@ msgid "Save All Scenes"
msgstr "Gem alle Scener"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Luk Scene"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Ã…ben Seneste"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konverter Til..."
@@ -2636,25 +2685,36 @@ msgstr "Gendan scene"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Diverse projekt eller scene redskaber."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projekt Indstillinger"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Værktøjer"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Eksport"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Ã…bn Projekt datamappe"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Værktøjer"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Forældreløs ressource udforsker"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2752,12 +2812,13 @@ msgstr ""
"Når det bruges eksternt på en enhed, er dette mere effektivt med "
"netværksfilsystem."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Redaktør"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Editor Indstillinger"
#: editor/editor_node.cpp
@@ -2775,15 +2836,6 @@ 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"
@@ -2806,14 +2858,15 @@ msgstr "Åbn redaktør Indstillinger mappe"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Organiser Eksport Skabeloner"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Organiser Eksport Skabeloner"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Hjælp"
@@ -2821,12 +2874,13 @@ msgstr "Hjælp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Søg"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentation"
@@ -3103,6 +3157,11 @@ msgstr "Tid"
msgid "Calls"
msgstr "Kald"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Medlemmer"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3267,7 +3326,8 @@ msgid "Import From Node:"
msgstr "Importer Fra Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Gen-Download"
#: editor/export_template_manager.cpp
@@ -3284,6 +3344,10 @@ msgid "Download"
msgstr "Download"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mangler)"
@@ -3347,12 +3411,10 @@ msgid "No response."
msgstr "Ingen reaktion."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Forespørgsel mislykkedes."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Omdiriger Løkke."
@@ -3366,13 +3428,19 @@ msgid "Download Complete."
msgstr "Download fuldført."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kan ikke fjerne:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Fejl ved anmodning af url: "
#: editor/export_template_manager.cpp
@@ -3459,19 +3527,11 @@ msgstr "Download Skabeloner"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Vælg spejl fra liste: (Shift+Click: Åbn i Browser)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr "Kan ikke skrive til file_type_cache.cch. Gemmer ikke fil type cache!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoritter"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Kan ikke navigere til '%s' da det ikke blev fundet i filsystemet!"
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3513,14 +3573,14 @@ msgid "Provided name contains invalid characters."
msgstr "Det angivne navn indeholder ugyldige karakterer"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Navnet indeholder ugyldige karakterer."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "En fil eller mappe med dette navn findes allerede."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Navnet indeholder ugyldige karakterer."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Omdøb fil:"
@@ -3583,6 +3643,11 @@ msgstr "Duplikere"
msgid "Move To..."
msgstr "Flyt Til..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ny Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3657,6 +3722,11 @@ msgstr "En fil eller mappe med dette navn findes allerede."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Gem Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3726,6 +3796,14 @@ msgid "Search complete"
msgstr "Søg Tekst"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Føj til Gruppe"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Fjern fra Gruppe"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "FEJL: Animationsnavn eksisterer allerede!"
@@ -3735,13 +3813,23 @@ msgstr "FEJL: Animationsnavn eksisterer allerede!"
msgid "Invalid group name."
msgstr "Ugyldigt navn."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Grupper"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Slet Layout"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupper"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Føj til Gruppe"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3755,12 +3843,13 @@ msgid "Nodes in Group"
msgstr "Føj til Gruppe"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Føj til Gruppe"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Fjern fra Gruppe"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Ã…bn Script Editor"
#: editor/groups_editor.cpp
#, fuzzy
@@ -3971,7 +4060,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Sæt"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Vælg en Node at redigere Signaler og Grupper for."
#: editor/plugin_config_dialog.cpp
@@ -4770,10 +4860,6 @@ msgid "View Files"
msgstr "Vis filer"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4786,14 +4872,47 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Forespørgsel mislykkedes."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kan ikke fjerne:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Omdiriger Løkke."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Forespørgsel mislykkedes."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tid"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4836,6 +4955,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Installér"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4865,13 +4989,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Alle"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4879,8 +5006,9 @@ msgid "Sort:"
msgstr "Sorter:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Omvendt"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Anmoder..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4892,7 +5020,8 @@ msgid "Site:"
msgstr "Websted:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Støtte..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4904,6 +5033,11 @@ msgid "Testing"
msgstr "Tester"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Indlæs"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Assets zipfil"
@@ -4954,32 +5088,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "Fjern vertikal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Opret ny vertikal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Fjern vertikal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "Fjern horisontal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Opret ny horisontal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Fjern horisontal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Opret ny vertikal guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5064,6 +5205,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Spil Brugerdefineret Scene"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Spil Brugerdefineret Scene"
@@ -5094,6 +5240,7 @@ msgid "Zoom Reset"
msgstr "Zoom Ud"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5114,14 +5261,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Skifter Modus"
@@ -5147,6 +5297,7 @@ msgid "Toggle snapping."
msgstr "Skift snapping mode"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5163,11 +5314,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5180,6 +5326,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5396,16 +5547,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5726,14 +5867,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5818,19 +5951,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6174,7 +6311,6 @@ msgid "Grid Settings"
msgstr "Editor Indstillinger"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6283,12 +6419,7 @@ msgstr "Error loading skrifttype."
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Fejl - kunne ikke oprette script i filsystem."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Fejl - kunne ikke oprette script i filsystem."
#: editor/plugins/script_editor_plugin.cpp
@@ -6318,7 +6449,7 @@ msgstr "Fejl i flytning:\n"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Opret mappe..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6404,6 +6535,11 @@ msgid "Open..."
msgstr "Ã…ben"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Ã…ben script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6444,13 +6580,13 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Luk alt"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr ""
@@ -6539,6 +6675,11 @@ msgstr ""
msgid "Search Results"
msgstr "Søg i Hjælp"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Ryd Seneste Scener"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6611,6 +6752,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6647,26 +6789,6 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Skift/Toggle Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Gå Til Næste Trin"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Skift/Toggle Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Fjern Alt"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "Fold Line"
@@ -6687,6 +6809,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skalér Valgte"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6705,32 +6832,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Skift/Toggle Breakpoint"
+msgid "Find Previous"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtrer filer..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Gå Til Næste Trin"
+msgid "Toggle Bookmark"
+msgstr "Skift/Toggle Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Skift/Toggle Breakpoint"
+msgid "Go to Next Bookmark"
+msgstr "Gå Til Næste Trin"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Skift/Toggle Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtrer filer..."
+msgid "Remove All Bookmarks"
+msgstr "Fjern Alt"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6743,9 +6875,24 @@ msgid "Go to Line..."
msgstr "GÃ¥ til linje"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Skift/Toggle Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Gå Til Næste Trin"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Skift/Toggle Breakpoint"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6926,7 +7073,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6982,8 +7133,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Ændret Lokalfilter"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7037,9 +7189,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Vælg Mode (Q)\n"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7049,31 +7200,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Vælg Mode (Q)\n"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7114,26 +7244,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Vælg værktøj"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7188,8 +7298,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Tester"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7497,10 +7608,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7589,11 +7696,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7703,14 +7810,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7725,8 +7824,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8042,6 +8141,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Tilføj punkt"
@@ -8131,6 +8234,11 @@ msgid "Duplicate Nodes"
msgstr "Dublikér nøgle(r)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Indsæt Node"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Vælg Node"
@@ -8154,6 +8262,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Opret Mappe"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Opret Mappe"
@@ -8231,6 +8344,22 @@ msgid "Color uniform."
msgstr "Anim Skift Transformering"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8238,10 +8367,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8331,7 +8494,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8339,7 +8502,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8351,7 +8514,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8368,7 +8531,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8437,11 +8600,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8457,7 +8620,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8468,7 +8631,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8477,7 +8640,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8485,11 +8648,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8530,11 +8693,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8544,7 +8711,7 @@ msgstr "Opret Poly"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8562,15 +8729,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8622,7 +8789,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8637,6 +8804,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8650,19 +8821,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8671,7 +8842,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8680,14 +8851,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8732,47 +8903,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8947,6 +9125,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Organiser Eksport Skabeloner"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9099,6 +9281,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Projekt"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Kan ikke åbne projekt"
@@ -9172,8 +9363,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9193,8 +9384,9 @@ msgid "Project Manager"
msgstr "Projektleder"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9218,10 +9410,6 @@ msgid "Templates"
msgstr "Skabeloner"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9565,6 +9753,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9617,14 +9809,6 @@ msgstr "Vælg Virtual Method"
msgid "Select Method"
msgstr "Vælg Method"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9925,6 +10109,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Ændre Argument navn"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9972,6 +10161,11 @@ msgstr "Ã…ben script"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Opret Ny %s"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Gem Scene"
@@ -10049,19 +10243,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10159,6 +10353,10 @@ msgid "Error loading script from %s"
msgstr "Fejl ved load af script fra %s"
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10192,7 +10390,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10358,6 +10556,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Editor Indstillinger"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10783,10 +10985,32 @@ msgid "Set Variable Type"
msgstr "Sæt Variabel Type"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ugyldigt navn. Det må ikke være i konflikt med eksisterende built-in type "
+"navn."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Opret Ny %s"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variable:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Opret Ny %s"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Opret Poly"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Navnet er ikke et gyldigt id:"
@@ -10976,10 +11200,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Indsæt Node"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Medlemmer"
@@ -11793,22 +12013,6 @@ msgstr ""
"den kan opnå en størrelse. Ellers gør den til en RenderTarget og tildel dens "
"indre textur til en node så den kan vises."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Fejl under initialisering af FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Ukendt skrifttypeformat."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error loading skrifttype."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ugyldig skriftstørrelse."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11823,6 +12027,11 @@ msgstr "Ugyldig skriftstørrelse."
msgid "Invalid source for shader."
msgstr "Ugyldig skriftstørrelse."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ugyldig skriftstørrelse."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11839,6 +12048,56 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Kan ikke skrive til file_type_cache.cch. Gemmer ikke fil type cache!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Kan ikke navigere til '%s' da det ikke blev fundet i filsystemet!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Fejl - kunne ikke oprette script i filsystem."
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Vælg Mode (Q)\n"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Vælg Mode (Q)\n"
+
+#~ msgid "Tool Select"
+#~ msgstr "Vælg værktøj"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Fejl under initialisering af FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Ukendt skrifttypeformat."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error loading skrifttype."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ugyldig skriftstørrelse."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Forrige fane"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Opret Mappe"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Åbn næste Editor"
+
+#~ msgid "Reverse"
+#~ msgstr "Omvendt"
+
#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "Fejler med at indlæse ressource."
@@ -11856,10 +12115,6 @@ msgstr ""
#~ msgstr "Opret Abonnement"
#, fuzzy
-#~ msgid "Build Project"
-#~ msgstr "Projekt"
-
-#, fuzzy
#~ msgid "View log"
#~ msgstr "Vis filer"
diff --git a/editor/translations/de.po b/editor/translations/de.po
index eac561c855..bc00839d04 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -2,7 +2,7 @@
# Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-# Alexander Mahr <alex.mahr@gmail.com>, 2016.
+# Alexander Mahr <alex.mahr@gmail.com>, 2016, 2019.
# Andreas Esau <andreasesau@gmail.com>, 2016.
# Andreas Haas <liu.gam3@gmail.com>, 2016.
# Andreas Hirschauer <andreas@hirschauer-it.de>, 2016.
@@ -13,12 +13,12 @@
# Eurocloud KnowHow <tobias.kloy@werde-volunteer.info>, 2017.
# HugeGameArt <hugegameartgd@gmail.com>, 2018.
# hyperglow <greensoma@web.de>, 2016.
-# Jan Groß <jan@grossit.de>, 2016.
+# Jan Groß <jan@grossit.de>, 2016, 2019.
# Kim <github@aggsol.de>, 2017.
# Metin Celik <metincelik88@gmail.com>, 2018.
# Neicul <neicul@gmx.de>, 2018.
# nimradium <nimra242001@gmail.com>, 2018.
-# Oliver Ruehl <oliver@ruehldesign.co>, 2016-2017.
+# Oliver Ruehl <oliver@ruehldesign.co>, 2016-2017, 2019.
# Paul-Vincent Roll <paviro@me.com>, 2016.
# Peter Friedland <peter_friedland@gmx.de>, 2016.
# No need for a name <endoplasmatik@gmx.net>, 2016.
@@ -43,12 +43,15 @@
# Marcus Naschke <marcus.naschke@gmail.com>, 2019.
# datenbauer <d-vaupel@web.de>, 2019.
# Alexander Hausmann <alexander-hausmann+weblate@posteo.de>, 2019.
+# Nicolas Mohr <81moni1bif@hft-stuttgart.de>, 2019.
+# Linux User <no-ads@mail.de>, 2019.
+# David May <wasser@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:46+0000\n"
-"Last-Translator: So Wieso <sowieso@dukun.de>\n"
+"PO-Revision-Date: 2019-08-18 10:23+0000\n"
+"Last-Translator: Linux User <no-ads@mail.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -56,7 +59,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.8-dev\n"
+"X-Generator: Weblate 3.8\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -100,7 +103,6 @@ msgid "On call to '%s':"
msgstr "Im Aufruf von ‚%s‘:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Kostenlos"
@@ -169,6 +171,26 @@ msgid "Anim Change Call"
msgstr "Aufruf ändern"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim-Multi-Change Schlüsselbildzeit"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Anim-Multi-Change Ãœbergang"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Anim-Multi-Change Transform"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim-Multi-Change Schlüsselbildwert"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Anim-Multi-Change Methodenaufruf"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Animationslänge ändern"
@@ -551,7 +573,7 @@ msgstr "Auswahl duplizieren"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "Transponierte duplizieren"
+msgstr "Umgesetztes duplizieren"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -671,16 +693,18 @@ msgid "Line Number:"
msgstr "Zeilennummer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Suchbegriff wurde %d mal ersetzt."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Keine Ãœbereinstimmungen"
+#, fuzzy
+msgid "%d match."
+msgstr "%d Ãœbereinstimmung(en) gefunden."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Suchbegriff wurde %d mal ersetzt."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "%d Ãœbereinstimmung(en) gefunden."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -830,7 +854,6 @@ msgid "Connect"
msgstr "Verbinden"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "Signale:"
@@ -840,11 +863,11 @@ msgstr "Verbinde ‚%s‘ mit ‚%s‘"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr "'%s' von '%s' trennen"
+msgstr "Trenne '%s' von '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect all from signal: '%s'"
-msgstr "Alle Verbindungen des Signal trennen: ‚%s‘"
+msgstr "Alle Verbindungen des Signals trennen: ‚%s‘"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -908,8 +931,7 @@ msgstr "Favoriten:"
msgid "Recent:"
msgstr "Kürzlich:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -997,11 +1019,10 @@ msgid "Owners Of:"
msgstr "Besitzer von:"
#: editor/dependency_editor.cpp
-#, 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)"
+"Ausgewählte Dateien aus dem Projekt entfernen? (Kann nicht rückgängig "
+"gemacht werden)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1013,7 +1034,7 @@ msgstr ""
"funktionieren.\n"
"Trotzdem entfernen? (Kann nicht rückgängig gemacht werden)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Kann nicht entfernt werden:"
@@ -1050,7 +1071,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr "Abhängigkeiten aufzeigen"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Unbenutzte Dateien ansehen"
@@ -1139,14 +1160,16 @@ msgid "License"
msgstr "Lizenz"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Drittpartei-Lizenz"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Die Godot-Engine baut auf vielen freien und quelloffenen Bibliotheken von "
@@ -1168,7 +1191,8 @@ msgid "Licenses"
msgstr "Lizenzen"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Fehler beim Öffnen der Paketdatei, kein ZIP-Format."
#: editor/editor_asset_installer.cpp
@@ -1185,7 +1209,6 @@ msgid "Success!"
msgstr "Geschafft!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installieren"
@@ -1554,6 +1577,7 @@ msgstr "Vorlagendatei nicht gefunden:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"In 32-bit-Exporten kann das eingebettete PCK nicht größer als 4 GiB sein."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1662,12 +1686,11 @@ msgid "New"
msgstr "Neu"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Import"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportieren"
@@ -1728,7 +1751,7 @@ msgstr "Im Dateimanager anzeigen"
msgid "New Folder..."
msgstr "Neuer Ordner..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Aktualisieren"
@@ -1779,7 +1802,7 @@ msgstr "Vor"
msgid "Go Up"
msgstr "Hoch"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Versteckte Dateien ein- und ausblenden"
@@ -1804,23 +1827,27 @@ msgid "Move Favorite Down"
msgstr "Favorit nach unten schieben"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Vorheriger Ordner"
+msgid "Go to previous folder."
+msgstr "Gehe zum vorherigen Ordner."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Nächster Ordner"
+msgid "Go to next folder."
+msgstr "Gehe zum nächsten Ordner."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Gehe zu übergeordnetem Ordner."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Dateien neu lesen."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Gegenwärtigen Ordner (de)favorisieren."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Versteckte Dateien ein- oder ausblenden."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2062,6 +2089,11 @@ msgstr "Löschen"
msgid "Clear Output"
msgstr "Ausgabe löschen"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Fenster"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Projekt-Export ist fehlgeschlagen mit Fehlercode %d."
@@ -2389,6 +2421,15 @@ msgid "Pick a Main Scene"
msgstr "Wähle eine Hauptszene"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Szene schließen"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Szene schließen"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Erweiterung lässt sich nicht aktivieren: ‚%‘ Parsen der Konfiguration "
@@ -2508,6 +2549,11 @@ msgstr "Diese Szene abspielen"
msgid "Close Tab"
msgstr "Tab schließen"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Tab schließen"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Andere Tabs schließen"
@@ -2561,6 +2607,10 @@ msgid "Go to previously opened scene."
msgstr "Gehe zu vorher geöffneter Szene."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Text kopieren"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Nächster Tab"
@@ -2588,6 +2638,10 @@ msgstr "Neue geerbte Szene..."
msgid "Open Scene..."
msgstr "Szene öffnen..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Zuletzt benutzte Szenen"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Szene speichern"
@@ -2597,14 +2651,6 @@ msgid "Save All Scenes"
msgstr "Alle Szenen speichern"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Szene schließen"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Zuletzt benutzte Szenen"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Umwandeln zu..."
@@ -2634,25 +2680,36 @@ msgstr "Szene zurücksetzen"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Sonstiges Projekt oder szenenübergreifende Werkzeuge."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projekteinstellungen"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Werkzeuge"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Exportieren..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Android-Build-Vorlage installieren"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Projektdatenordner öffnen"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Werkzeuge"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Android-Build-Vorlage installieren"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Unbenutzte Dateien ansehen"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2751,12 +2808,13 @@ msgstr ""
"Sollte dies beim Abspielen auf externen Geräten genutzt werden, ist es am "
"effizientesten das Netzwerk-Dateisystem zu nutzen."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Editoreinstellungen"
#: editor/editor_node.cpp
@@ -2773,14 +2831,6 @@ 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"
@@ -2801,14 +2851,16 @@ msgid "Open Editor Settings Folder"
msgstr "Editoreinstellungenordner öffnen"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Editorfunktionen verwalten"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Verwalte Exportvorlagen"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Hilfe"
@@ -2816,12 +2868,13 @@ msgstr "Hilfe"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Suchen"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Internetdokumentation"
@@ -2835,7 +2888,7 @@ msgstr "Problem-Melder"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "Gemeinschaft"
+msgstr "Community (Gemeinschaft)"
#: editor/editor_node.cpp
msgid "About"
@@ -3101,6 +3154,10 @@ msgstr "Zeit"
msgid "Calls"
msgstr "Aufrufe"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Text bearbeiten:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "An"
@@ -3273,7 +3330,8 @@ msgid "Import From Node:"
msgstr "Aus Node importieren:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Erneut herunterladen"
#: editor/export_template_manager.cpp
@@ -3290,6 +3348,10 @@ msgid "Download"
msgstr "Herunterladen"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Fehlend)"
@@ -3353,12 +3415,10 @@ msgid "No response."
msgstr "Keine Antwort."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Anfrage fehlgeschlagen."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Weiterleitungsschleife."
@@ -3372,15 +3432,22 @@ msgid "Download Complete."
msgstr "Download abgeschlossen."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kann Motiv nicht speichern in Datei:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Template-Installation fehlgeschlagen. Des problematische Template-Archiv "
"befindet sich hier: ‚%s‘."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Fehler beim Abrufen der URL: "
#: editor/export_template_manager.cpp
@@ -3465,23 +3532,11 @@ msgstr "Lade Template herunter"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Mirror aus Liste auswählen: (Umsch-Klick: In Browser öffnen)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Die Datei 'file_type_cache.cch' konnte nicht zum schreiben geöffnet werden. "
-"Der Dateityp-Cache wird nicht gespeichert!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoriten"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Kann nicht zu '%s' navigierien, da es sich nicht im Dateisystem gefunden "
-"wurde!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Status: Dateiimport fehlgeschlagen. Manuelle Reparatur und Neuimport nötig."
@@ -3515,14 +3570,14 @@ msgid "Provided name contains invalid characters."
msgstr "Angegebener Name enthält ungültige Zeichen."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Name enthält ungültige Zeichen."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Es existiert bereits eine Datei oder ein Ordner mit diesem Namen."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Name enthält ungültige Zeichen."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Benenne Datei um:"
@@ -3578,6 +3633,11 @@ msgstr "Duplizieren..."
msgid "Move To..."
msgstr "Verschiebe zu..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Neue Szene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Neues Skript..."
@@ -3645,6 +3705,11 @@ msgstr ""
msgid "Overwrite"
msgstr "Ãœberschreiben"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Von Szene erstellen"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Erstelle Skript"
@@ -3707,6 +3772,14 @@ msgid "Search complete"
msgstr "Suche abgeschlossen"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Zu Gruppe hinzufügen"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Aus Gruppe entfernen"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Gruppenname existiert bereits."
@@ -3714,12 +3787,23 @@ msgstr "Gruppenname existiert bereits."
msgid "Invalid group name."
msgstr "Ungültiger Gruppenname."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gruppen verwalten"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Lösche Bildergruppe"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Gruppen"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nodes nicht in der Gruppe"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3732,12 +3816,13 @@ msgid "Nodes in Group"
msgstr "Nodes in der Gruppe"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Zu Gruppe hinzufügen"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Aus Gruppe entfernen"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Skripteditor"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3947,7 +4032,8 @@ msgid "MultiNode Set"
msgstr "MultiNode setzen"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Node auswählen um Signale und Gruppen zu bearbeiten."
#: editor/plugin_config_dialog.cpp
@@ -4303,7 +4389,7 @@ msgstr "Animation umbenennen"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
-msgstr "Überblende nächste Änderung"
+msgstr "Blende über in nächste Geänderte"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
@@ -4501,7 +4587,7 @@ msgstr "Am Ende"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr "Fortlaufend"
+msgstr "Reisen"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Start and end nodes are needed for a sub-transition."
@@ -4632,11 +4718,11 @@ msgstr "Eingang hinzufügen"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Clear Auto-Advance"
-msgstr "Lösche Auto-Fortschritt"
+msgstr "Stoppe automatischen Vorsprung"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Set Auto-Advance"
-msgstr "Setze Auto-Fortschritt"
+msgstr "Starte automatisches Weitergehen"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Delete Input"
@@ -4707,10 +4793,6 @@ msgid "View Files"
msgstr "Dateien anzeigen"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Kann Hostnamen nicht auflösen:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Verbindungsfehler, bitte erneut versuchen."
@@ -4723,14 +4805,47 @@ msgid "No response from host:"
msgstr "Keine Antwort von Host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Kann Hostnamen nicht auflösen:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Anfrage fehlgeschlagen: Rückgabewert:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Anfrage fehlgeschlagen."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kann Motiv nicht speichern in Datei:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Anfrage fehlgeschlagen, zu viele Weiterleitungen"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Weiterleitungsschleife."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Anfrage fehlgeschlagen: Rückgabewert:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Zeit"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Falsche Download-Prüfsumme, Datei könnte manipuliert worden sein."
@@ -4771,6 +4886,10 @@ msgid "Idle"
msgstr "Leerlauf"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Installieren..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Erneut versuchen"
@@ -4799,13 +4918,17 @@ msgid "Last"
msgstr "Letzte"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Alle"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Neuimport..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Erweiterungen"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4813,8 +4936,8 @@ msgid "Sort:"
msgstr "Sortiere:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Umkehren"
+msgid "Reverse sorting."
+msgstr "Sortierung umkehren."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4826,7 +4949,8 @@ msgid "Site:"
msgstr "Seite:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Stabilität..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4838,6 +4962,11 @@ msgid "Testing"
msgstr "Testphase"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Lade..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Nutzerinhalte als ZIP-Datei"
@@ -4896,31 +5025,31 @@ msgid "Rotation Step:"
msgstr "Rotationsabstand:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr "Vertikale Hilfslinie verschieben"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Neue vertikale Hilfslinie erstellen"
+msgid "Create Vertical Guide"
+msgstr "Vertikale Hilfslinie erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Vertikale Hilfslinie löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "Horizontale Hilfslinie verschieben"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Neue horizontale Hilfslinie erstellen"
+msgid "Create Horizontal Guide"
+msgstr "Horizontale Hilfslinie erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Horizontale Hilfslinie löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr "Neue horizontale und vertikale Hilfslinien erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5004,6 +5133,11 @@ msgid "Paste Pose"
msgstr "Pose einfügen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Knochen löschen"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Erstelle eigenständige(n) Knochen aus Node(s)"
@@ -5034,6 +5168,7 @@ msgid "Zoom Reset"
msgstr "Zoom Zurücksetzen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Auswahlmodus"
@@ -5056,14 +5191,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Rechtsklick: Listenauswahl nach Tiefe"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Bewegungsmodus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Rotationsmodus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Skalierungsmodus"
@@ -5090,6 +5228,7 @@ msgid "Toggle snapping."
msgstr "Einrasten umschalten."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Einrasten aktivieren"
@@ -5106,11 +5245,6 @@ msgid "Use Rotation Snap"
msgstr "Rotationsraster benutzen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Einrasten konfigurieren..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Relatives Einrasten benutzen"
@@ -5123,6 +5257,11 @@ msgid "Smart Snapping"
msgstr "Intelligentes Einrasten"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Einrasten konfigurieren..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "An Elternobjekt einrasten"
@@ -5165,7 +5304,7 @@ msgstr "Verhindert das Auswählen von Unterobjekten dieses Nodes."
#: 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 "Macht Unterobjekte dieses Objekts wieder auswählbar."
+msgstr "Stellt die Auswählbarkeit aller Unterobjekte wieder her."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -5338,16 +5477,6 @@ msgstr "Wähle Griff"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Fehler beim Laden des Bilds:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Keine Pixel mit einer Transparenz > 128 im Bild..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Emissionsmaske laden"
@@ -5660,14 +5789,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Quelle für Oberfläche ist ungültig (keine Faces)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Elternelement hat keine soliden Faces zu besetzen."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Bereich konnte nicht abgebildet werden."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Quell-Mesh auswählen:"
@@ -5753,20 +5874,27 @@ msgid "Generation Time (sec):"
msgstr "Erzeugungszeit (s):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Flächen enthalten keinen Bereich!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Knoten enthält keine Geometrie (Flächen)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Keine Flächen!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Knoten enthält keine Geometrie."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Knoten enthält keine Geometrie (Flächen)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Knoten enthält keine Geometrie."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6099,7 +6227,6 @@ msgid "Grid Settings"
msgstr "Gittereinstellungen"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Einrasten"
@@ -6206,12 +6333,9 @@ msgid "Error writing TextFile:"
msgstr "Fehler beim Schreiben von Textdatei:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Fehler: Datei konnte nicht geladen werden."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Fehler: Datei konnte nicht geladen werden."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Konnte Kachel nicht finden:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6234,7 +6358,8 @@ msgid "Error Importing"
msgstr "Fehler beim Importieren"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Neue Textdatei..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6315,6 +6440,11 @@ msgid "Open..."
msgstr "Öffnen..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Skript öffnen"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Alle speichern"
@@ -6352,13 +6482,13 @@ msgid "Save Theme"
msgstr "Motiv speichern"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Dokumentation schließen"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Alle schließen"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Dokumentation schließen"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Ausführen"
@@ -6447,6 +6577,11 @@ msgstr "Debugger"
msgid "Search Results"
msgstr "Suchergebnisse"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Verlauf leeren"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Verbindungen mit Methode:"
@@ -6514,8 +6649,9 @@ msgid "Syntax Highlighter"
msgstr "Syntaxhervorhebung"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Springe zu"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6523,9 +6659,8 @@ msgid "Bookmarks"
msgstr "Lesezeichen"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Punkte erstellen."
+msgstr "Haltepunkte"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6549,22 +6684,6 @@ msgid "Toggle Comment"
msgstr "Kommentar umschalten"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Lesezeichen umschalten"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Springe zum nächsten Lesezeichen"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Springe zum vorigen Lesezeichen"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Alle Lesezeichen entfernen"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Zeile ein/aufklappen"
@@ -6585,6 +6704,11 @@ msgid "Complete Symbol"
msgstr "Symbol vervollständigen"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Auswahl skalieren"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Kürze Leerraum am Zeilenende"
@@ -6601,29 +6725,32 @@ msgid "Auto Indent"
msgstr "Automatische Einrückung"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Haltepunkt umschalten"
+msgid "Find Previous"
+msgstr "Finde Vorheriges"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Lösche alle Haltepunkte"
+msgid "Find in Files..."
+msgstr "In Dateien suchen..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Springe zum nächsten Haltepunkt"
+msgid "Contextual Help"
+msgstr "Kontexthilfe"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Springe zum vorigen Haltepunkt"
+msgid "Toggle Bookmark"
+msgstr "Lesezeichen umschalten"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Finde Vorheriges"
+msgid "Go to Next Bookmark"
+msgstr "Springe zum nächsten Lesezeichen"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "In Dateien suchen..."
+msgid "Go to Previous Bookmark"
+msgstr "Springe zum vorigen Lesezeichen"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Alle Lesezeichen entfernen"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6634,8 +6761,21 @@ msgid "Go to Line..."
msgstr "Springe zu Zeile..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Kontexthilfe"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Haltepunkt umschalten"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Lösche alle Haltepunkte"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Springe zum nächsten Haltepunkt"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Springe zum vorigen Haltepunkt"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6816,8 +6956,12 @@ msgid "Rear"
msgstr "Hinten"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Mit Sicht ausrichten"
+msgid "Align Transform with View"
+msgstr "Transform auf Sicht ausrichten"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Rotation auf Sicht ausrichten"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6873,8 +7017,9 @@ msgid "Audio Listener"
msgstr "Audiosenke"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Dopplereffekt aktivieren"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Filtern aktivieren"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6929,8 +7074,8 @@ msgid "Snap Nodes To Floor"
msgstr "Nodes am Boden einrasten"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Auswahlmodus (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6943,30 +7088,11 @@ msgstr ""
"Alt+RMT: Tiefenauswahl"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Bewegungsmodus (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Rotationsmodus (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Skalierungsmodus (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Lokale Koordinaten"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Lokalkoordinatenmodus (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Einrastmodus (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Sicht von unten"
@@ -7007,26 +7133,6 @@ msgid "Focus Selection"
msgstr "Auswahl fokussieren"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Auswahl auf Ansicht ausrichten"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Werkzeugauswahl"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Werkzeug Verschieben"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Werkzeug Drehen"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Werkzeug Skalieren"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Freie Kamera umschalten"
@@ -7081,7 +7187,8 @@ msgstr "Zeige Gitter"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Einstellungen"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7376,10 +7483,6 @@ msgid "TextureRegion"
msgstr "Texturbereich"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Kann Motiv nicht speichern in Datei:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Alle Elemente hinzufügen"
@@ -7457,18 +7560,20 @@ msgstr "Markiertes Element der Auswahl"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Named Sep."
-msgstr "Ben. Trenner"
+msgstr "Ben. Trenner."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
msgstr "Untermenü"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Element 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Element 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7573,14 +7678,6 @@ msgid "Transpose"
msgstr "Transponieren"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "X-Koordinaten spiegeln"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Y-Koordinaten spiegeln"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Autokacheln deaktivieren"
@@ -7593,9 +7690,10 @@ msgid "Paint Tile"
msgstr "Kachel zeichnen"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Umsch+RMT: Linie zeichnen\n"
"Umsch+Strg+RMT: Rechteck einfärben"
@@ -7876,7 +7974,7 @@ msgstr "Kachelpriorität bearbeiten"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
-msgstr "Kachel-Z-Index bearbeiten"
+msgstr "bearbeite Kachel Z Index"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Collision Polygon"
@@ -7895,6 +7993,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Nur GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Eingang hinzufügen +"
@@ -7971,6 +8073,11 @@ msgid "Duplicate Nodes"
msgstr "Nodes duplizieren"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Nodes einfügen"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Nodes löschen"
@@ -7991,6 +8098,11 @@ msgid "Light"
msgstr "Licht"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Shader-Node erzeugen"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Shader-Node erzeugen"
@@ -8063,6 +8175,22 @@ msgid "Color uniform."
msgstr "Farb-Uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Gibt den Wahrheitswert des %s-Vergleiches der beiden Parameter zurück."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Gleichheit (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Größer als (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Größergleich (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8072,12 +8200,52 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Gibt den Wahrheitswert zwischen dem Vergleich von Unendlich und einem "
+"skalaren Parameter zurück."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Gibt den Wahrheitswert zwischen dem Vergleich von NaN und einem skalaren "
+"Parameter zurück."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Kleiner als (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Kleiner gleich (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Ungleich (!=)"
+
+#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Gibt den Wahrheitswert des Vergleiches zweier Parameter zurück."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Gibt den Wahrheitswert zwischen dem Vergleich von Unendlich (oder NaN) und "
+"einem skalaren Parameter zurück."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Boolean-Konstante."
@@ -8166,18 +8334,16 @@ msgid "Returns the arc-cosine of the parameter."
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."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "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 "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."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Gibt den inversen hyperbolischen Sinus des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8188,9 +8354,8 @@ msgid "Returns the arc-tangent of the parameters."
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."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Gibt den inversen hyperbolischen Tangens des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8206,8 +8371,8 @@ msgid "Returns the cosine of the parameter."
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 "(Nur GLES3) Gibt den hyperbolischen Kosinus des Parameters zurück."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Gibt den hyperbolischen Kosinus des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8275,12 +8440,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / Skalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(nur GLES3) Gibt die nächste Ganzzahl vom Parameter zurück."
+msgid "Finds the nearest integer to the parameter."
+msgstr "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 "(nur GLES3) Gibt die nächste gerade Ganzzahl vom Parameter zurück."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "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."
@@ -8295,18 +8460,19 @@ msgid "Returns the sine of the parameter."
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 "(nur GLES3) Gibt den hyperbolischen Sinus des Parameters zurück."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Gibt den hyperbolischen Sinus des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Gibt die Quadratwurzel des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8317,10 +8483,11 @@ msgstr ""
"Wert zwischen 0.0 und 1.0 zurück gegeben."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Schrittfunktion ( Skalar(Kante), Skalar(x) ).\n"
"\n"
@@ -8331,12 +8498,12 @@ msgid "Returns the tangent of the parameter."
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 "(nur GLES3) Gibt den hyperbolischen Tangens des Parameters zurück."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "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 "(Nur GLES3) Gibt den abgeschnittenen Wert des Parameters zurück."
+msgid "Finds the truncated value of the parameter."
+msgstr "Gibt den abgeschnittenen Wert des Parameters zurück."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8375,12 +8542,16 @@ msgid "Perform the texture lookup."
msgstr "Texturfinden ausführen."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Kubisches Textur-Uniform."
+msgid "Cubic texture uniform lookup."
+msgstr "Kubisches Textur-Uniform-Lookup."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr "2D-Textur-Uniform-Lookup."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "2D-Textur-Uniform."
+msgid "2D texture uniform lookup with triplanar."
+msgstr "2D-Textur-Uniform-Lookup mit triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8388,7 +8559,7 @@ msgstr "Transformierungsfunktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8396,7 +8567,7 @@ 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"
+"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 "
@@ -8413,16 +8584,16 @@ msgid "Decomposes transform to four vectors."
msgstr "Extrahiert vier Vektoren aus Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr "(nur GLES3) Berechnet die Determinante eines Transforms."
+msgid "Calculates the determinant of a transform."
+msgstr "Berechnet die Determinante eines Transforms."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(nur GLES3) Invertiert ein Transform."
+msgid "Calculates the inverse of a transform."
+msgstr "Invertiert ein Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(nur GLES3) Transponiert ein Transform."
+msgid "Calculates the transpose of a transform."
+msgstr "Transponiert ein Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8470,16 +8641,15 @@ msgstr "Berechnet das Skalarprodukt aus zwei Vektoren."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
-"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."
+"Gibt einen Vektor mit möglicherweise geändertem Vorzeichen zurück. 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."
@@ -8490,6 +8660,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Lineare Interpolation zwischen zwei Vektoren."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Lineare Interpolation zwischen zwei Vektoren."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Berechnet den normierten Vektor."
@@ -8503,21 +8678,22 @@ msgstr "1.0 / Vektor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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: "
+"Gibt den Vektor zurück der in Richtung der 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 "Berechnet den Vektor der in Richtung einer Brechung zeigt."
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Gibt den Vektor zurück der in Richtung der Brechung zeigt."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8528,10 +8704,11 @@ msgstr ""
"interpolierter Wert zwischen 0.0 und 1.0 zurückgegeben."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8542,20 +8719,22 @@ msgstr ""
"interpolierter Wert zwischen 0.0 und 1.0 zurückgegeben."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Stufenfunktion ( Skalar(Kante), Vektor(x) ).\n"
"\n"
@@ -8610,62 +8789,67 @@ msgstr ""
"Eingänge müssen übergeben werden)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
-"(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."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(nur für Fragment-/Light-Modus) Skalare Ableitungsfunktion."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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'."
+"(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."
+"(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'."
+"(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."
+"(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"
@@ -8817,7 +9001,7 @@ msgstr "Verschlüsselt (Schlüssel unten angeben)"
#: editor/project_export.cpp
msgid "Invalid Encryption Key (must be 64 characters long)"
-msgstr "Ungültiger Schlüssel (muss 64 Zeichen lang sein)"
+msgstr "Ungültiger Schlüssel für Verschlüsselung (muss 64 Zeichen lang sein)"
#: editor/project_export.cpp
msgid "Script Encryption Key (256-bits as hex):"
@@ -8840,6 +9024,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Export-Templates für diese Systeme fehlen:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Verwalte Exportvorlagen"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exportiere mit Debuginformationen"
@@ -8999,6 +9187,15 @@ msgid "Unnamed Project"
msgstr "Unbenanntes Projekt"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Existierendes Projekt importieren"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Projekt in ‚%s‘ kann nicht geöffnet werden."
@@ -9097,12 +9294,13 @@ msgstr ""
"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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Alle fehlenden Projekte aus der Liste entfernen? (Dateisysteminhalte werden "
-"nicht geändert)"
+"%d Projekte aus der Liste entfernen?\n"
+"Inhalte der Projektordner werden nicht geändert."
#: editor/project_manager.cpp
msgid ""
@@ -9126,8 +9324,9 @@ msgid "Project Manager"
msgstr "Projektverwaltung"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Projektliste"
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9150,10 +9349,6 @@ msgid "Templates"
msgstr "Vorlagen"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Verlassen"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Jetzt Neustarten"
@@ -9300,7 +9495,7 @@ msgstr "Ereignis hinzufügen"
#: editor/project_settings_editor.cpp
msgid "Button"
-msgstr "Taste"
+msgstr "Taste, Knopf (Button)"
#: editor/project_settings_editor.cpp
msgid "Left Button."
@@ -9376,23 +9571,23 @@ msgstr "Ãœbersetzung entfernen"
#: editor/project_settings_editor.cpp
msgid "Add Remapped Path"
-msgstr "Remap-Pfad hinzufügen"
+msgstr "Umgeleiteten Pfad hinzufügen"
#: editor/project_settings_editor.cpp
msgid "Resource Remap Add Remap"
-msgstr "Ressourcen-Remap hinzufügen"
+msgstr "Ressourcen-Umleitung hinzufügen"
#: editor/project_settings_editor.cpp
msgid "Change Resource Remap Language"
-msgstr "Ändere Zielsprache des Ressourcen-Remaps"
+msgstr "Ändere Zielsprache der Ressourcen-Umleitung"
#: editor/project_settings_editor.cpp
msgid "Remove Resource Remap"
-msgstr "Ressourcen-Remap entfernen"
+msgstr "Ressourcen-Umleitung entfernen"
#: editor/project_settings_editor.cpp
msgid "Remove Resource Remap Option"
-msgstr "Ressourcen-Remap-Option entfernen"
+msgstr "Ressourcen-Umleitungsoption entfernen"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter"
@@ -9465,7 +9660,7 @@ msgstr "Ressourcen:"
#: editor/project_settings_editor.cpp
msgid "Remaps by Locale:"
-msgstr "Remaps nach Lokalisierung:"
+msgstr "Umleitungen nach Lokalisierung:"
#: editor/project_settings_editor.cpp
msgid "Locale"
@@ -9495,6 +9690,10 @@ msgstr "Sprachen:"
msgid "AutoLoad"
msgstr "Autoload"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Erweiterungen"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Null"
@@ -9547,15 +9746,6 @@ msgstr "Virtuelle Methode auswählen"
msgid "Select Method"
msgstr "Methode auswählen"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Konnte PVRTC-Werkzeug nicht ausführen:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"Umgewandeltes Bild kann mittels PVRTC-Werkzeug nicht zurück geladen werden:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Stapelweise Umbenennung"
@@ -9853,6 +10043,11 @@ msgid "Remove Node(s)"
msgstr "Entferne Node(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Ausgangsschnittstellenname ändern"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9897,6 +10092,10 @@ msgid "Extend Script"
msgstr "Skript erweitern"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Node unter neues Node hängen"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Szenen-Wurzel erstellen"
@@ -9969,24 +10168,27 @@ msgid "Node configuration warning:"
msgstr "Node-Konfigurationswarnung:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Node hat Verbindungen und Gruppen.\n"
"Klicken um Signalverwaltung aufzurufen."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Node hat Verbindungen.\n"
"Hier klicken zur Signalverwaltung."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Node ist in Gruppe(n).\n"
@@ -10086,6 +10288,11 @@ msgid "Error loading script from %s"
msgstr "Fehler beim Laden des Skripts von %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Ãœberschreiben"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Nicht verfügbar"
@@ -10114,8 +10321,8 @@ msgid "Script is valid."
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 _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Erlaubt: a-z, A-Z, 0-9, _ und ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10274,6 +10481,10 @@ msgid "Change Shortcut"
msgstr "Tastenkürzel ändern"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Editoreinstellungen"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Tastenkürzel"
@@ -10694,10 +10905,30 @@ msgid "Set Variable Type"
msgstr "Variablentyp festlegen"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Darf nicht mit existierenden eingebauten Typnamen übereinstimmen."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Neues Rechteck erstellen."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variablen:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Neues Rechteck erstellen."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Neues Polygon erstellen."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Name ist kein gültiger Bezeichner:"
@@ -10887,10 +11118,6 @@ msgid "Cut Nodes"
msgstr "Nodes trennen"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Nodes einfügen"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Mitglied bearbeiten"
@@ -11185,7 +11412,6 @@ 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 "
"order for AnimatedSprite to display frames."
@@ -11256,12 +11482,11 @@ 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\" "
"property."
msgstr ""
-"Eine Textur mit der Form des Lichtkegels muss in der ‚Texture‘-Eigenschaft "
+"Eine Textur mit der Form des Lichtkegels muss in der „Texture“-Eigenschaft "
"angegeben werden."
#: scene/2d/light_occluder_2d.cpp
@@ -11272,10 +11497,10 @@ msgstr ""
"Occluder funktioniert."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+"Das Occluder-Polygon für diesen Occluder ist leer. Zum Fortfahren Polygon "
+"zeichnen."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11380,18 +11605,16 @@ msgstr ""
"verwendet werden um ihnen eine Form zu geben."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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."
+"VisibilityEnable2D funktioniert am besten, wenn die Wurzel der bearbeiteten "
+"Szene das Elternobjekt ist."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera braucht ein ARVROrigin-Node als Ãœberobjekt"
+msgstr "ARVRCamera braucht ein ARVROrigin-Node als Ãœberobjekt."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11481,13 +11704,12 @@ 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."
msgstr ""
-"Damit CollisionShape funktionieren kann, muss eine Form vorhanden sein. "
-"Bitte erzeuge eine shape Ressource dafür!"
+"Zum Funktionieren eines CollisionShape benötigt es eine zugeordnete Form. "
+"Zum Fortfahren ist eine Shape-Ressource dafür zu erzeugen."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11524,6 +11746,8 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Ein SpotLight mit einem Winkel von mehr als 90 Grad kann keine Schatten "
+"werfen."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11570,13 +11794,12 @@ msgstr ""
"gesetzt wird."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"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."
+"PathFollow mit aktiviertem ROTATION_ORIENTED erfordert die Aktivierung von "
+"„Up Vector“ in der Curve-Ressource des übergeordneten Pfades."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11590,11 +11813,12 @@ msgstr ""
"geändert werden."
#: scene/3d/remote_transform.cpp
-#, 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."
+msgstr ""
+"Die „Remote Path“-Eigenschaft muss auf ein gültiges Spatial-Node oder ein "
+"von Spatial-Node abgeleitetes Node verweisen."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11612,13 +11836,12 @@ msgstr ""
"geändert werden."
#: scene/3d/sprite_3d.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Eine SpriteFrames-Ressource muss in der ‚Frames‘-Eigenschaft erzeugt oder "
-"definiert werden, damit AnimatedSprite3D Einzelbilder anzeigen kann."
+"Eine SpriteFrames-Ressource muss in der „Frames“-Eigenschaft erzeugt oder "
+"gesetzt werden, damit AnimatedSprite3D Einzelbilder anzeigen kann."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11634,6 +11857,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment benötigt dass die Eigenschaft „Environment“ auf ein "
+"Environment mit einem sichtbaren Effekt verweist."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11672,9 +11897,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
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "Für diesen Graphen wurde kein Wurzel-Animation-Node festgelegt."
+msgstr "Für diesen Graphen wurde kein Wurzel-AnimationNode festgelegt."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11689,9 +11913,8 @@ msgstr ""
"AnimationPlayer-Node."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "Die Wurzel des Animationsspieler ist kein gültiges Node."
+msgstr "Die Wurzel des Animationsspielers ist kein gültiges Node."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11720,14 +11943,13 @@ msgid "Add current color as a preset."
msgstr "Aktuelle Farbe als Vorlage hinzufügen."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
-"Einfache Container sind unnötig solange kein Skript die Platzierung der "
-"Inhalte vornimmt.\n"
+"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."
@@ -11749,24 +11971,21 @@ 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, 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 "
-"machen ist in Ordnung, aber sie werden zur Laufzeit automatisch wieder "
-"versteckt."
+"Popups werden standardmäßig nicht angezeigt, es sei denn sie werden durch "
+"popup() oder andere popup*()-Funktionen aufgerufen. Sie als sichtbar zu "
+"markieren kann für die Bearbeitung nützlich sein, zur Laufzeit werden sie "
+"allerdings nicht automatisch angezeigt."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Wenn „Exp Edit“ aktiviert 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 "
@@ -11803,35 +12022,22 @@ msgstr ""
"Eigenschaft ‚Render Target‘ des Viewports aktiviert und seine Textur "
"irgendeinem Node zum Anzeigen zugewiesen werden."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Fehler beim initialisieren von FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Unbekanntes Schriftformat."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Fehler beim Laden der Schriftart."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ungültige Schriftgröße."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Eingang"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Ungültige Quelle für Shader."
+msgstr "Ungültige Quelle für Vorschau."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Ungültige Quelle für Shader."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Ungültige Vergleichsfunktion für diesen Typ."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Zuweisung an Funktion."
@@ -11848,6 +12054,131 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden."
msgid "Constants cannot be modified."
msgstr "Konstanten können nicht verändert werden."
+#~ msgid "No Matches"
+#~ msgstr "Keine Ãœbereinstimmungen"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Die Datei 'file_type_cache.cch' konnte nicht zum schreiben geöffnet "
+#~ "werden. Der Dateityp-Cache wird nicht gespeichert!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Kann nicht zu '%s' navigierien, da es sich nicht im Dateisystem gefunden "
+#~ "wurde!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Fehler beim Laden des Bilds:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Keine Pixel mit einer Transparenz > 128 im Bild..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Elternelement hat keine soliden Faces zu besetzen."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Bereich konnte nicht abgebildet werden."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Flächen enthalten keinen Bereich!"
+
+#~ msgid "No faces!"
+#~ msgstr "Keine Flächen!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Fehler: Datei konnte nicht geladen werden."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Fehler: Datei konnte nicht geladen werden."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Dopplereffekt aktivieren"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Auswahlmodus (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Bewegungsmodus (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Rotationsmodus (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Skalierungsmodus (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Lokale Koordinaten"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Einrastmodus (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Werkzeugauswahl"
+
+#~ msgid "Tool Move"
+#~ msgstr "Werkzeug Verschieben"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Werkzeug Drehen"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Werkzeug Skalieren"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Alle fehlenden Projekte aus der Liste entfernen? (Dateisysteminhalte "
+#~ "werden nicht geändert)"
+
+#~ msgid "Project List"
+#~ msgstr "Projektliste"
+
+#~ msgid "Exit"
+#~ msgstr "Verlassen"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Konnte PVRTC-Werkzeug nicht ausführen:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "Umgewandeltes Bild kann mittels PVRTC-Werkzeug nicht zurück geladen "
+#~ "werden:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Fehler beim initialisieren von FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Unbekanntes Schriftformat."
+
+#~ msgid "Error loading font."
+#~ msgstr "Fehler beim Laden der Schriftart."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ungültige Schriftgröße."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Vorheriger Ordner"
+
+#~ msgid "Next Folder"
+#~ msgstr "Nächster Ordner"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Bildschirmfotos automatisch öffnen"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "In externem Bildbearbeitungsprogramm öffnen."
+
+#~ msgid "Reverse"
+#~ msgstr "Umkehren"
+
+#~ msgid "Mirror X"
+#~ msgstr "X-Koordinaten spiegeln"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Y-Koordinaten spiegeln"
+
#~ msgid "Generating solution..."
#~ msgstr "Lösungen erzeugen..."
@@ -12599,9 +12930,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Erase selection"
#~ msgstr "Lösche Auswahl"
-#~ msgid "Could not find tile:"
-#~ msgstr "Konnte Kachel nicht finden:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Elementname oder ID:"
@@ -12869,9 +13197,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Info"
#~ msgstr "Info"
-#~ msgid "Re-Import..."
-#~ msgstr "Neuimport..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Keine Bitmasken zu importieren!"
@@ -13264,9 +13589,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Stereo"
#~ msgstr "Stereo"
-#~ msgid "Window"
-#~ msgstr "Fenster"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Skaliere auf %s%%."
@@ -13496,9 +13818,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Add Image Group"
#~ msgstr "Füge Bildergruppe hinzu"
-#~ msgid "Delete Image Group"
-#~ msgstr "Lösche Bildergruppe"
-
#~ msgid "Project Export Settings"
#~ msgstr "Projektexporteinstellungen"
@@ -13584,9 +13903,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Export Project PCK"
#~ msgstr "Exportiere Projekt-PCK"
-#~ msgid "Export..."
-#~ msgstr "Exportieren..."
-
#~ msgid "Project Export"
#~ msgstr "Projekt exportieren"
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index d1d0c1ade8..ad007f96c5 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -60,7 +60,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -134,6 +133,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Length"
msgstr "Typ ändern"
@@ -642,15 +661,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -886,8 +905,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -981,7 +999,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -1018,7 +1036,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1110,14 +1128,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1134,7 +1152,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1151,7 +1169,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1633,12 +1650,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1709,7 +1725,7 @@ msgstr "Datei öffnen"
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1760,7 +1776,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1786,12 +1802,12 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Node(s) löschen"
+msgid "Go to previous folder."
+msgstr "Node erstellen"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr "Node erstellen"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
@@ -1799,12 +1815,16 @@ msgstr "Node erstellen"
msgid "Go to parent folder."
msgstr "Node erstellen"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2047,6 +2067,10 @@ msgstr ""
msgid "Clear Output"
msgstr "Script hinzufügen"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2353,6 +2377,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Datei(en) öffnen"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2449,6 +2482,10 @@ msgstr "Szene starten"
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2503,6 +2540,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Script hinzufügen"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2530,6 +2572,10 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr ""
@@ -2540,14 +2586,6 @@ msgid "Save All Scenes"
msgstr "Neue Szene speichern als..."
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2577,17 +2615,23 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr "Verschiedene Projekte oder Szenenweite Werkzeuge."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Project"
msgstr "Projektname:"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projekteinstellungen"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Projekt exportieren"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2595,8 +2639,12 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "Projekt exportieren"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2679,13 +2727,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Connections editieren"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2700,14 +2749,6 @@ 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 ""
@@ -2728,14 +2769,15 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr "Ungültige Bilder löschen"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2743,12 +2785,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3028,6 +3071,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Node Filter editieren"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3193,7 +3241,7 @@ msgid "Import From Node:"
msgstr "Importiere von folgendem Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3210,6 +3258,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3272,12 +3324,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3291,14 +3341,18 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr "Szene kann nicht gespeichert werden."
#: editor/export_template_manager.cpp
@@ -3391,19 +3445,11 @@ msgstr "Ungültige Bilder löschen"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3439,11 +3485,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3510,6 +3556,11 @@ msgstr "Node(s) duplizieren"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Neue Szene speichern als..."
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3576,6 +3627,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Node erstellen"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3639,6 +3695,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3647,12 +3711,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "Projektname:"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Neues Projekt erstellen"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Node(s) löschen"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3666,12 +3740,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Verzeichnis öffnen"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3882,7 +3957,7 @@ msgstr "MultiNode Set"
#: editor/node_dock.cpp
#, fuzzy
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr "Selektiere ein Node um deren Signale und Gruppen zu ändern."
#: editor/plugin_config_dialog.cpp
@@ -4675,10 +4750,6 @@ msgid "View Files"
msgstr "Datei(en) öffnen"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4692,14 +4763,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4741,6 +4840,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4769,13 +4872,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importierte Projekte"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4783,7 +4889,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4796,7 +4902,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4808,6 +4914,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Connections editieren"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4858,36 +4969,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "Ungültige Bilder löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "Neues Projekt erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Ungültige Bilder löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "Ungültige Bilder löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "Neues Projekt erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Ungültige Bilder löschen"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Neues Projekt erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -4971,6 +5085,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Spiele angepasste Szene"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Spiele angepasste Szene"
@@ -5000,6 +5119,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5020,16 +5140,19 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Move Mode"
msgstr "Bild bewegen/einfügen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Rotate Mode"
msgstr "Node erstellen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "TimeScale-Node"
@@ -5054,6 +5177,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5070,11 +5194,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5087,6 +5206,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5303,16 +5427,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Emissions-Maske laden"
@@ -5636,14 +5750,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Oberflächen Quelle is invalid (kein Face)"
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5728,19 +5834,26 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Flächen enthalten keinen Bereich!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Keine Flächen!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Node enthält keine Geometrie (Flächen)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
+msgstr "Node enthält keine Geometrie (Flächen)."
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
msgstr "Node enthält keine Geometrie (Flächen)."
#: editor/plugins/particles_editor_plugin.cpp
@@ -6084,7 +6197,6 @@ msgid "Grid Settings"
msgstr "Projekteinstellungen"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6191,12 +6303,9 @@ msgid "Error writing TextFile:"
msgstr "Szene kann nicht gespeichert werden."
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr ""
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Neues Projekt erstellen"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6224,8 +6333,9 @@ msgid "Error Importing"
msgstr "Szene kann nicht gespeichert werden."
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
-msgstr ""
+#, fuzzy
+msgid "New Text File..."
+msgstr "Datei(en) öffnen"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6310,6 +6420,11 @@ msgid "Open..."
msgstr "Öffnen"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Script hinzufügen"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6347,11 +6462,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6440,6 +6555,11 @@ msgstr ""
msgid "Search Results"
msgstr "Ungültige Bilder löschen"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Script hinzufügen"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6508,6 +6628,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6545,24 +6666,6 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Autoplay Umschalten"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Ungültige Bilder löschen"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "Bild einfügen"
@@ -6583,6 +6686,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Script hinzufügen"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6601,31 +6709,36 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr ""
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "Autoplay Umschalten"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr "Ungültige Bilder löschen"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
msgstr ""
@@ -6634,7 +6747,20 @@ msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6817,7 +6943,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6874,8 +7004,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Typ ändern"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6928,9 +7059,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Selektiere Node(s) zum Importieren aus"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6940,31 +7070,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Selektiere Node(s) zum Importieren aus"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7006,26 +7115,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7080,8 +7169,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Projekteinstellungen"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7389,10 +7479,6 @@ msgid "TextureRegion"
msgstr "2D-Textur"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7482,11 +7568,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7593,14 +7679,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7615,8 +7693,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7933,6 +8011,10 @@ msgid "TileSet"
msgstr "Datei(en) öffnen"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Script hinzufügen"
@@ -8020,6 +8102,12 @@ msgid "Duplicate Nodes"
msgstr "Node(s) duplizieren"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Paste Nodes"
+msgstr "Node erstellen"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Node(s) löschen"
@@ -8042,6 +8130,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Node erstellen"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Node erstellen"
@@ -8115,6 +8208,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8122,10 +8231,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8214,7 +8357,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8222,7 +8365,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8234,7 +8377,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8251,7 +8394,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8320,11 +8463,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8340,7 +8483,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8351,7 +8494,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8360,7 +8503,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8368,11 +8511,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8412,11 +8555,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8426,7 +8573,7 @@ msgstr "Transformationstyp"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8444,15 +8591,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8503,7 +8650,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8518,6 +8665,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8531,19 +8682,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8552,7 +8703,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8561,14 +8712,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8613,47 +8764,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8829,6 +8987,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8986,6 +9148,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Existierendes Projekt importieren"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Neues Projekt erstellen"
@@ -9055,8 +9226,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9076,8 +9247,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projektname:"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9102,10 +9274,6 @@ msgid "Templates"
msgstr "Ungültige Bilder löschen"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9446,6 +9614,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9500,14 +9672,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9804,6 +9968,11 @@ msgid "Remove Node(s)"
msgstr "Node(s) entfernen"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Typ ändern"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9847,6 +10016,11 @@ msgid "Extend Script"
msgstr "Script hinzufügen"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Node erstellen"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9923,19 +10097,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10031,6 +10205,10 @@ msgid "Error loading script from %s"
msgstr "Fehler beim Instanzieren der %s Szene"
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10062,7 +10240,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10227,6 +10405,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10646,10 +10828,29 @@ msgid "Set Variable Type"
msgstr "Ungültige Bilder löschen"
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Node erstellen"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Node erstellen"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Node erstellen"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10854,11 +11055,6 @@ msgstr "Node erstellen"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "Node erstellen"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "Node Filter editieren"
@@ -11625,23 +11821,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-#, fuzzy
-msgid "Error initializing FreeType."
-msgstr "Fehler bei der FreeType Inizialisierung."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11654,6 +11833,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11670,6 +11853,32 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Faces contain no area!"
+#~ msgstr "Flächen enthalten keinen Bereich!"
+
+#~ msgid "No faces!"
+#~ msgstr "Keine Flächen!"
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Selektiere Node(s) zum Importieren aus"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Selektiere Node(s) zum Importieren aus"
+
+#, fuzzy
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Fehler bei der FreeType Inizialisierung."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Node(s) löschen"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Node erstellen"
+
#, fuzzy
#~ msgid "Build Project"
#~ msgstr "Projektname:"
@@ -11724,10 +11933,6 @@ msgstr ""
#~ msgstr "Node"
#, fuzzy
-#~ msgid "New TextFile"
-#~ msgstr "Datei(en) öffnen"
-
-#, fuzzy
#~ msgid "Show current scene file."
#~ msgstr "Node(s) löschen"
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 5f4f2ae64b..e27bfdfe87 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -52,7 +52,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -121,6 +120,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -605,15 +624,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -837,8 +856,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -932,7 +950,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -968,7 +986,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1057,14 +1075,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1081,7 +1099,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1098,7 +1116,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1565,12 +1582,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1631,7 +1647,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1682,7 +1698,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1707,23 +1723,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1956,6 +1976,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2252,6 +2276,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2345,6 +2377,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2398,6 +2434,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2425,20 +2465,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2471,24 +2507,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2568,12 +2612,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2589,14 +2633,6 @@ 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 ""
@@ -2617,14 +2653,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2632,12 +2668,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2909,6 +2946,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3070,7 +3111,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3087,6 +3128,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3148,12 +3193,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3167,13 +3210,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3258,19 +3305,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3303,11 +3342,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3366,6 +3405,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3429,6 +3472,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3489,6 +3536,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3496,12 +3551,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3514,11 +3577,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3725,7 +3788,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4467,10 +4530,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4483,14 +4542,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4531,6 +4618,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4559,13 +4650,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4573,7 +4666,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4586,7 +4679,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4598,6 +4691,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4648,31 +4745,31 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4752,6 +4849,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4780,6 +4881,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4800,14 +4902,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4831,6 +4936,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4847,11 +4953,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4864,6 +4965,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5071,16 +5177,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5391,14 +5487,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5482,19 +5570,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5821,7 +5913,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5927,11 +6018,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5955,7 +6042,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6036,6 +6123,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6073,11 +6164,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6165,6 +6256,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6231,6 +6326,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6265,92 +6361,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6528,7 +6628,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6584,7 +6688,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6638,7 +6742,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6649,27 +6753,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6713,26 +6797,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6787,7 +6851,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7080,10 +7144,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7168,11 +7228,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7277,14 +7337,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7298,8 +7350,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7578,6 +7630,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7654,6 +7710,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7674,6 +7735,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7746,6 +7811,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7753,10 +7834,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7845,7 +7960,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7853,7 +7968,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7865,7 +7980,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7882,7 +7997,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7951,11 +8066,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7971,7 +8086,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7982,7 +8097,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -7991,7 +8106,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7999,11 +8114,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8043,11 +8158,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8056,7 +8175,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8074,15 +8193,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8131,7 +8250,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8146,6 +8265,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8159,19 +8282,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8180,7 +8303,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8189,14 +8312,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8241,47 +8364,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8448,6 +8578,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8594,6 +8728,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8663,8 +8805,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8684,7 +8826,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8708,10 +8850,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9045,6 +9183,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9097,14 +9239,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9390,6 +9524,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9432,6 +9570,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9503,19 +9645,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9606,6 +9748,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9634,7 +9780,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9794,6 +9940,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10204,10 +10354,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10392,10 +10558,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11125,22 +11287,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11153,6 +11299,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index ed1e0493b4..8b5b93ec94 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-07-02 10:48+0000\n"
+"PO-Revision-Date: 2019-08-21 15:57+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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -62,7 +62,6 @@ msgid "On call to '%s':"
msgstr "Στην κλήση στο '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "ΕλεÏθεÏο"
@@ -104,31 +103,51 @@ msgstr "Μετακίνηση σημείου Bezier"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
-msgstr "Anim ΑναπαÏαγωγή Κλειδιών"
+msgstr "ΑναπαÏαγωγή Κλειδιών Κίνησης"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr "Anim ΔιαγÏαφή κλειδιών"
+msgstr "ΔιαγÏαφή Κλειδιών Κίνησης"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Anim Αλλαγή χÏόνου στιγμιοτÏπου"
+msgstr "Αλλαγή ΧÏόνου ÎšÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transition"
-msgstr "Anim Αλλαγή μετάβασης"
+msgstr "Αλλαγή Μετάβασης Κίνησης"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
-msgstr "Anim Αλλαγή μετασχηματισμοÏ"
+msgstr "Αλλαγή ÎœÎµÏ„Î±ÏƒÏ‡Î·Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Anim Αλλαγή τιμής στιγμιοτÏπου"
+msgstr "Αλλαγή Τιμής ÎšÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Anim Change Call"
-msgstr "Anim Αλλαγή κλήσης"
+msgstr "Αλλαγή Κλήσης Κίνησης"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Αλλαγή ΧÏόνων Κλειδιών Κίνησης"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Αλλαγή Μεταβάσεων Κίνησης"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Αλλαγή Μετασχηματισμών Κίνησης"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Αλλαγή Τιμών Κλειδιών Κίνησης"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Αλλαγή Κλήσεων Κίνησης"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
@@ -190,7 +209,7 @@ msgstr "Αποσπάσματα ήχου:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr "Αποσπάσματα κίνησης:"
+msgstr "Αποσπάσματα Κίνησης:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
@@ -288,7 +307,7 @@ msgstr "Αλλαγή λειτουÏγίας επανάληψης κίνησης"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
-msgstr "Anim ΑφαίÏεση κομματιοÏ"
+msgstr "ΑφαίÏεση ÎšÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
@@ -311,7 +330,7 @@ msgstr "ΔημιουÏγία"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
-msgstr "Anim Εισαγωγή"
+msgstr "Εισαγωγή Κίνησης"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
@@ -319,15 +338,15 @@ msgstr "Ένα AnimationPlayer δεν μποÏεί να κινήσει τον ε
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
-msgstr "Anim ΔημιουÏγία & Εισαγωγή"
+msgstr "ΔημιουÏγία & Εισαγωγή Κίνησης"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr "Anim Εισαγωγή ÎºÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï & κλειδιοÏ"
+msgstr "Εισαγωγή ÎšÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï & ÎšÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
-msgstr "Anim εισαγωγή κλειδιοÏ"
+msgstr "Εισαγωγή ÎšÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
#: editor/animation_track_editor.cpp
msgid "Change Animation Step"
@@ -402,7 +421,7 @@ msgstr "Δεν βÏέθηκε η μέθοδος στο αντικείμενο: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
-msgstr "Anim Μετακίνηση κελιδιών"
+msgstr "Μετακίνηση Κλειδιών Κίνησης"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
@@ -414,7 +433,7 @@ msgstr "Επικόλληση κομματιών"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
-msgstr "Anim Μεγέθυνση κλειδιών"
+msgstr "Κλιμάκωση Κλειδιών Κίνησης"
#: editor/animation_track_editor.cpp
msgid ""
@@ -455,9 +474,8 @@ msgid "Select All"
msgstr "Επιλογή όλων"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Επιλογή κόμβου"
+msgstr "Αποεπιλογή Όλων"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -634,16 +652,18 @@ msgid "Line Number:"
msgstr "ΑÏ. γÏαμμής:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Αντικαταστάθηκαν %d εμφανίσεις."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Δεν υπάÏχουν αντιστοιχίες"
+#, fuzzy
+msgid "%d match."
+msgstr "Î’Ïέθηκαν %d αποτελέσματα."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Αντικαταστάθηκαν %d εμφανίσεις."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Î’Ïέθηκαν %d αποτελέσματα."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -704,7 +724,7 @@ msgid ""
"target node."
msgstr ""
"Η στοχευμένη συνάÏτηση δεν βÏέθηκε. ΟÏίστε μία έγκυÏη μέθοδο ή συνδέστε μία "
-"δεσμή ενεÏγειών στον στοχευμένο κόμβο."
+"δέσμη ενεÏγειών στον στοχευμένο κόμβο."
#: editor/connections_dialog.cpp
msgid "Connect to Node:"
@@ -712,7 +732,7 @@ msgstr "ΣÏνδεση σε Κόμβο:"
#: editor/connections_dialog.cpp
msgid "Connect to Script:"
-msgstr "ΣÏνδεση σε Δεσμή ΕνεÏγειών:"
+msgstr "ΣÏνδεση σε Δέσμη ΕνεÏγειών:"
#: editor/connections_dialog.cpp
msgid "From Signal:"
@@ -720,7 +740,7 @@ msgstr "Από Σήμα:"
#: editor/connections_dialog.cpp
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
@@ -793,9 +813,8 @@ msgid "Connect"
msgstr "ΣÏνδεση"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Σήματα:"
+msgstr "Σήμα:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -873,8 +892,7 @@ msgstr "Αγαπημένα:"
msgid "Recent:"
msgstr "ΠÏόσφατα:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -962,9 +980,8 @@ msgid "Owners Of:"
msgstr "Ιδιοκτήτες του:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Îα αφαιÏεθοÏν τα επιλεγμένα αÏχεία από το έÏγο; (ΑδÏνατη η αναίÏεση)"
+msgstr "ΑφαίÏεση επιλεγμένων αÏχείων από το έÏγο; (Αδυναμία αναίÏεσης)"
#: editor/dependency_editor.cpp
msgid ""
@@ -975,7 +992,7 @@ msgstr ""
"Τα αÏχεία που αφαιÏοÏνται απαιτοÏνται από άλλους πόÏους για να δουλέψουν.\n"
"Îα αφαιÏεθοÏν; (ΑδÏνατη η αναίÏεση)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "ΑδÏνατη η αφαίÏεση:"
@@ -1011,7 +1028,7 @@ msgstr "Μόνιμη διαγÏαφή %d αντικειμένων; (ΑδÏνατ
msgid "Show Dependencies"
msgstr "Εμφάνιση ΕξαÏτήσεων"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "ΕξεÏευνητής αχÏησιμοποίητων πόÏων"
@@ -1100,14 +1117,16 @@ msgid "License"
msgstr "Άδεια"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Άδεια Ï„Ïίτων ομάδων"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Η μηχανή Godot βασίζεται σε μια σειÏά από δωÏεάν και Î±Î½Î¿Î¹Ï‡Ï„Î¿Ï ÎºÏŽÎ´Î¹ÎºÎ± "
@@ -1129,7 +1148,8 @@ msgid "Licenses"
msgstr "Άδειες"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Σφάλμα κατά το άνοιγμα του πακέτου, δεν είναι αÏχείο zip."
#: editor/editor_asset_installer.cpp
@@ -1146,7 +1166,6 @@ msgid "Success!"
msgstr "Επιτυχία!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Εγκατάσταση"
@@ -1334,7 +1353,6 @@ msgid "Must not collide with an existing engine class name."
msgstr "Δεν μποÏεί να συγχέεται με υπαÏκτό όνομα κλάσης της μηχανής."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
msgstr "Δεν μποÏεί να συγχέεται με υπαÏκτό ενσωματωμένο όνομα Ï„Ïπου."
@@ -1518,6 +1536,7 @@ msgstr "Δεν βÏέθηκε αÏχείο Ï€ÏοτÏπου:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"Σε εξαγωγές 32-bit, το ενσωματωμένο PCK δεν μποÏεί να υπεÏβαίνει τα 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1544,9 +1563,8 @@ msgid "Node Dock"
msgstr "ΠλατφόÏμα Κόμβου"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "ΠλατφόÏμα Συστήματος ΑÏχείων"
+msgstr "ΠλατφόÏμες Συστήματος ΑÏχείων και Εισαγωγής"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1597,12 +1615,11 @@ msgid "File '%s' format is invalid, import aborted."
msgstr "ΆκυÏη μοÏφή αÏχείου «%s», ακÏÏωση εισαγωγής."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
-"ΥπαÏκτό Ï€Ïοφίλ «%s». ΑφαιÏέστε το Ï€Ïιν την εισαγωγή, ακÏÏωση εισαγωγής."
+"ΥπαÏκτό Ï€Ïοφίλ «%s». ΑφαιÏέστε το Ï€Ïιν την εισαγωγή. Ματαίωση εισαγωγής."
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
@@ -1613,9 +1630,8 @@ msgid "Unset"
msgstr "ΚατάÏγηση"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "ΤÏέχων ΠÏοφίλ"
+msgstr "ΤÏέχων ΠÏοφίλ:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1627,19 +1643,17 @@ msgid "New"
msgstr "Îέο"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Εισαγωγή"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Εξαγωγή"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Διαθέσιμα ΠÏοφίλ"
+msgstr "Διαθέσιμα ΠÏοφίλ:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1694,7 +1708,7 @@ msgstr "Εμφάνιση στη διαχείÏιση αÏχείων"
msgid "New Folder..."
msgstr "Îέος φάκελος..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Αναναίωση"
@@ -1745,7 +1759,7 @@ msgstr "Πήγαινε μπÏοστά"
msgid "Go Up"
msgstr "Πήγαινε πάνω"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Εναλλαγή κÏυμμένων αÏχείων"
@@ -1770,24 +1784,28 @@ msgid "Move Favorite Down"
msgstr "Μετακίνηση αγαπημένου κάτω"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "ΠÏοηγοÏμενος φάκελος"
+msgid "Go to previous folder."
+msgstr "Πήγαινε στον Ï€ÏοηγοÏμενο φάκελο."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Επόμενος φάκελος"
+msgid "Go to next folder."
+msgstr "Πήγαινε στον επόμενο φάκελο."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Πήγαινε στον γονικό φάκελο."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Ανανέωση αÏχείων."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Εναλλαγή αγαπημένου Ï„Ïέχοντος φακέλου."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
-msgstr "Εναλλαγή οÏατότητας κÏυμένων αÏχείων."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "Εναλλαγή οÏατότητας κÏυφών αÏχείων."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -2028,6 +2046,11 @@ msgstr "ΕκκαθάÏιση"
msgid "Clear Output"
msgstr "ΕκκαθάÏιση εξόδου"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "ΠαÏάθυÏο"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Η εξαγωγή του έÏγου απέτυχε με κωδικό %d."
@@ -2241,7 +2264,7 @@ msgstr "ΓÏήγοÏο άνοιγμα σκηνής..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr "ΓÏήγοÏη άνοιγμα δεσμής ενεÏγειών..."
+msgstr "ΓÏήγοÏη άνοιγμα δέσμης ενεÏγειών..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2357,6 +2380,15 @@ msgid "Pick a Main Scene"
msgstr "Επιλογή κÏÏιας σκηνής"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Κλείσιμο σκηνής"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Κλείσιμο σκηνής"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"ΑδÏνατη η ενεÏγοποίηση Ï€Ïόσθετης επέκτασης στο: '%s'. Απέτυχε η ανάλυση του "
@@ -2370,7 +2402,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr "ΑδÏνατη η φόÏτωση δεσμής ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'."
+msgstr "ΑδÏνατη η φόÏτωση δέσμης ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'."
#: editor/editor_node.cpp
msgid ""
@@ -2384,13 +2416,13 @@ msgstr ""
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
-"ΑδÏνατη η φόÏτωση δεσμής ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'. Ο "
+"ΑδÏνατη η φόÏτωση δέσμης ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'. Ο "
"βασικός Ï„Ïπος δεν είναι το EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
-"ΑδÏνατη η φόÏτωση δεσμής ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'. Δεν "
+"ΑδÏνατη η φόÏτωση δέσμης ενεÏγειών Ï€Ïοσθέτου από τη διαδÏομή: '%s'. Δεν "
"είναι σε λειτουÏγία tool."
#: editor/editor_node.cpp
@@ -2476,6 +2508,11 @@ msgstr "ΑναπαÏαγωγή σκηνής"
msgid "Close Tab"
msgstr "Κλείσιμο καÏτέλας"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Κλείσιμο καÏτέλας"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Κλείσιμο άλλον καÏτελών"
@@ -2529,6 +2566,10 @@ msgid "Go to previously opened scene."
msgstr "ΕπιστÏοφή στην Ï€Ïοηγουμένως ανοιγμένη σκηνή."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "ΑντιγÏαφή Κειμένου"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Επόμενη καÏτέλα"
@@ -2556,6 +2597,10 @@ msgstr "Îέα κληÏονομημένη σκηνή..."
msgid "Open Scene..."
msgstr "Άνοιγμα σκηνής..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Άνοιγμα Ï€Ïόσφατων"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "ΑποθηκεÏσετε σκηνής"
@@ -2565,14 +2610,6 @@ msgid "Save All Scenes"
msgstr "Αποθήκευση Ολων των Σκηνών"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Κλείσιμο σκηνής"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Άνοιγμα Ï€Ïόσφατων"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "ΜετατÏοπή σε..."
@@ -2602,25 +2639,37 @@ msgstr "ΕπαναφοÏά σκηνής"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Λοιπά έÏγα ή εÏγαλεία για όλη τη σκηνή."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "ΈÏγο"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Ρυθμίσεις έÏγου"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ΕÏγαλεία"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Εξαγωγή"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Εγκατάσταση ΠÏοτÏπου Χτισίματος Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Άνοιγμα φακέλου δεδομένων έÏγου"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ΕÏγαλεία"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Εγκατάσταση ΠÏοτÏπου Χτισίματος Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "ΕξεÏευνητής αχÏησιμοποίητων πόÏων"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2714,17 +2763,18 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
-"Όταν αυτή η επιλογή είναι ενεÏγοποιημένη, όποια δεσμή ενεÏγειών αποθηκευτεί "
+"Όταν αυτή η επιλογή είναι ενεÏγοποιημένη, όποια δέσμη ενεÏγειών αποθηκευτεί "
"θα επαναφοÏτωθεί στο παιχνίδι.\n"
"Όταν χÏησιμοποιηθεί απομακÏυσμένα σε μία συσκευή, αυτό είναι ποιο "
"αποτελεσματικό με δικτυωμένο σÏστημα αÏχείων."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "ΕπεξεÏγαστής"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Ρυθμίσεις επεξεÏγαστή"
#: editor/editor_node.cpp
@@ -2732,32 +2782,22 @@ msgid "Editor Layout"
msgstr "Διάταξη επεξεÏγαστή"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Βγάζει νόημα!"
+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"
+msgstr "Εναλλαγή Κονσόλας Συστήματος"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2772,14 +2812,16 @@ msgid "Open Editor Settings Folder"
msgstr "Άνοιγμα φακέλου Ïυθμίσεων επεξεÏγαστή"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "ΔιαχείÏιση Δυνατοτήτων ΕπεξεÏγαστή"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "ΔιαχείÏιση Ï€ÏοτÏπων εξαγωγής"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Βοήθεια"
@@ -2787,12 +2829,13 @@ msgstr "Βοήθεια"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Αναζήτηση"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "ΗλεκτÏονική τεκμηÏίωση"
@@ -2866,19 +2909,16 @@ msgid "Spins when the editor window redraws."
msgstr "ΠεÏιστÏέφεται όταν το παÏάθυÏο του επεξεÏγαστή επαναχÏωματίζεται."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Συνεχόμενη"
+msgstr "Συνεχόμενη Ανανέωση"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "ΕνημέÏωση αλλαγών"
+msgstr "Ανανέωση στην Αλλαγή"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "ΑπενεÏγοποίηση δείκτη ενημέÏωσης"
+msgstr "ΑπόκÏυψη Δείκτη ΕνημέÏωσης"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -2955,7 +2995,7 @@ msgstr "Κωδικός:"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
-msgstr "Άνοιξε & ΤÏέξε μία δεσμή ενεÏγειών"
+msgstr "Άνοιξε & ΤÏέξε μία δέσμη ενεÏγειών"
#: editor/editor_node.cpp
msgid "New Inherited"
@@ -2979,7 +3019,7 @@ msgstr "Άνοιγμα 3D επεξεÏγαστή"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Άνοιγμα επεξεÏγαστή δεσμής ενεÏγειών"
+msgstr "Άνοιγμα ΕπεξεÏγαστή Δεσμών ΕνεÏγειών"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3075,6 +3115,10 @@ msgstr "ΧÏόνος"
msgid "Calls"
msgstr "Κλήσεις"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "ΕπεξεÏγασία Κειμένου:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Îαι"
@@ -3133,7 +3177,7 @@ msgstr "Επιλέξτε ένα Viewport"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
-msgstr "Îεα δεσμή ενεÏγειών"
+msgstr "Îέα Δέσμη ΕνεÏγειών"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
@@ -3155,7 +3199,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 "Επικόλληση"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
@@ -3215,7 +3259,7 @@ msgstr "ΥπάÏχει ήδη μία σκηνή για επεξεÏγασία."
#: editor/editor_run_script.cpp
msgid "Couldn't instance script:"
-msgstr "ΑδÏνατη η δημιουÏγία στιγμιοτÏπου δεσμής ενεÏγειών:"
+msgstr "Αδυναμία κλωνοποίησης δέσμης ενεÏγειών:"
#: editor/editor_run_script.cpp
msgid "Did you forget the 'tool' keyword?"
@@ -3223,7 +3267,7 @@ msgstr "Μήπως ξεχάσατε τη λέξη-κλειδί \"tool\"?"
#: editor/editor_run_script.cpp
msgid "Couldn't run script:"
-msgstr "ΑδÏνατη η εκτέλεση της δεσμής ενεÏγειών:"
+msgstr "Αδυναμία εκτέλεσης δέσμης ενεÏγειών:"
#: editor/editor_run_script.cpp
msgid "Did you forget the '_run' method?"
@@ -3246,7 +3290,8 @@ msgid "Import From Node:"
msgstr "Εισαγωγή σκηνής από κόμβο:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Εκ νέου λήψη"
#: editor/export_template_manager.cpp
@@ -3263,6 +3308,10 @@ msgid "Download"
msgstr "Λήψη"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Λείπει)"
@@ -3326,12 +3375,10 @@ msgid "No response."
msgstr "Δεν λήφθηκε απόκÏιση."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Το αίτημα απέτυχε."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Î’Ïόχος ανακατευθήνσεων."
@@ -3345,15 +3392,22 @@ msgid "Download Complete."
msgstr "Η λήψη ολοκληÏώθηκε."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Δεν ήταν δυνατή η αποθήκευση θέματος σε αÏχείο:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Αποτυχία εγκατάστασης Ï€ÏοτÏπων. Οι Ï€Ïοβληματικές αÏχειοθήκες μποÏοÏν να "
"βÏεθοÏν στο '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Σφάλμα κατά Ï„o αίτημα για διεÏθηνση url: "
#: editor/export_template_manager.cpp
@@ -3440,22 +3494,11 @@ msgstr ""
"Επιλέξτε έναν διακομιστή κατοπτÏισμοÏ: (Shift+Click για άνοιγμα στο "
"Ï€ÏόγÏαμμα πεÏιήγησης)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"ΑδÏνατο το άνοιγμα του αÏχείου file_type_cache.cch για εγγÏαφή, παÏάλειψη "
-"αποθήκευσης cache Ï„Ïπου αÏχείου!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Αγαπημένα"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Δεν ήταν δυνατή η πλοήγηση στο '%s', καθώς δεν βÏέθηκε στο σÏστημα αÏχείων!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Κατάσταση: Η εισαγωγή απέτυχε. ΠαÏακαλοÏμε διοÏθώστε το αÏχείο και "
@@ -3490,14 +3533,14 @@ msgid "Provided name contains invalid characters."
msgstr "Το δοσμένο όνομα πεÏιέχει άκυÏους χαÏακτήÏες."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Το όνομα πεÏιέχει άκυÏους χαÏακτήÏες."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "ΥπάÏχει ήδη ένα αÏχείο ή φάκελος με αυτό το όνομα."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Το όνομα πεÏιέχει άκυÏους χαÏακτήÏες."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Μετονομασία αÏχείου:"
@@ -3553,9 +3596,14 @@ msgstr "ΑναπαÏαγωγή..."
msgid "Move To..."
msgstr "Μετακίνηση σε..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Îέα σκηνή"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
-msgstr "Îεα δεσμή ενεÏγειών..."
+msgstr "Îέα Δέσμη ΕνεÏγειών..."
#: editor/filesystem_dock.cpp
msgid "New Resource..."
@@ -3569,7 +3617,7 @@ msgstr "Ανάπτυξη Όλων"
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Collapse All"
-msgstr "ΣÏμπτηξη Όλων"
+msgstr "ΣÏμπτυξη Όλων"
#: editor/filesystem_dock.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -3618,9 +3666,14 @@ msgstr "ΥπάÏχει ήδη αÏχείο ή φάκελος με το ίδιο
msgid "Overwrite"
msgstr "Αντικατάσταση"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "ΔημιουÏγία από σκηνή"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr "ΔημιουÏγία δεσμής ενεÏγειών"
+msgstr "ΔημιουÏγία δέσμης ΕνεÏγειών"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
msgid "Find in Files"
@@ -3680,6 +3733,14 @@ msgid "Search complete"
msgstr "ΟλοκλήÏωση αναζήτησης"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "ΠÏοσθήκη σε Ομάδα"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "ΚατάÏγηση από την ομάδα"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "ΥπαÏκτό όνομα ομάδας."
@@ -3687,12 +3748,23 @@ msgstr "ΥπαÏκτό όνομα ομάδας."
msgid "Invalid group name."
msgstr "ΆκυÏο όνομα ομάδας."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "ΔιαχείÏηση ομάδων"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "ΔιαγÏαφή διάταξης"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Ομάδες"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Κόμβοι εκτός ομάδας"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3705,12 +3777,13 @@ msgid "Nodes in Group"
msgstr "Κόμβοι σε ομάδα"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "ΠÏοσθήκη σε Ομάδα"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "ΚατάÏγηση από την ομάδα"
+#, fuzzy
+msgid "Group Editor"
+msgstr "ΕπεξεÏγαστής Δεσμών ΕνεÏγειών"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3775,21 +3848,21 @@ msgstr "ΔημιουÏία για πλέγμα: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr "Εκτέλεση Ï€ÏοσαÏμοσμένης δέσμης ενεÏγειών..."
+msgstr "Εκτέλεση ΠÏοσαÏμοσμένης Δέσμης ΕνεÏγειών..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
-msgstr "Δεν ήταν δυνατή η φόÏτωση της δεσμής ενεÏγειών για μετά την εισαγωγή:"
+msgstr "Δεν ήταν δυνατή η φόÏτωση της δέσμης ενεÏγειών για μετά την εισαγωγή:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
msgstr ""
-"ΆκυÏη / χαλασμένη δεσμή ενεÏγειών για την διαδικασία της μετ-εισαγωγής "
-"(ελέγξτε την κονσόλα):"
+"ΆκυÏη/χαλασμένη δέσμη ενεÏγειών για την διαδικασία της μετεισαγωγής (ελέγξτε "
+"την κονσόλα):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
-msgstr "Σφάλμα κατά την εκτέλεση της δέσμης ενεÏγειών μετ-εισαγωγής:"
+msgstr "Σφάλμα κατά την εκτέλεση της δέσμης ενεÏγειών μετεισαγωγής:"
#: editor/import/resource_importer_scene.cpp
msgid "Saving..."
@@ -3843,7 +3916,7 @@ msgstr "Ανάπτυξη Όλων των Ιδιοτήτων"
#: editor/inspector_dock.cpp
msgid "Collapse All Properties"
-msgstr "ΣÏμπτηξη Όλων των Ιδιοτήτων"
+msgstr "ΣÏμπτυξη Όλων των Ιδιοτήτων"
#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -3919,7 +3992,8 @@ msgid "MultiNode Set"
msgstr "Σετ πολλαπλών κόμβων"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Επιλέξτε ένα κόμβο για να επεξεÏγαστείτε τα σήματα και τις ομάδες."
#: editor/plugin_config_dialog.cpp
@@ -3944,7 +4018,7 @@ msgstr "Γλώσσα:"
#: editor/plugin_config_dialog.cpp
msgid "Script Name:"
-msgstr "Όνομα δεσμής ενεÏγειών:"
+msgstr "Όνομα Δέσμης ΕνεÏγειών:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
@@ -4680,10 +4754,6 @@ msgid "View Files"
msgstr "ΠÏοβολή αÏχείων"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Δεν είναι δυνατή η επίλυση του ονόματος του κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î®:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Σφάλμα σÏνδεσης, παÏακαλώ ξαναπÏοσπαθήστε."
@@ -4696,14 +4766,47 @@ msgid "No response from host:"
msgstr "Δεν λήφθηκε απόκÏιση από τον κεντÏικό υπολογιστή:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Δεν είναι δυνατή η επίλυση του ονόματος του κεντÏÎ¹ÎºÎ¿Ï Ï…Ï€Î¿Î»Î¿Î³Î¹ÏƒÏ„Î®:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Το αίτημα απέτυχε, κώδικας επιστÏοφής:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Το αίτημα απέτυχε."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Δεν ήταν δυνατή η αποθήκευση θέματος σε αÏχείο:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Το αίτημα απέτυχε, πάÏα πολλές ανακατευθήνσεις"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Î’Ïόχος ανακατευθήνσεων."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Το αίτημα απέτυχε, κώδικας επιστÏοφής:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ΧÏόνος"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
"Εσφαλμένος κωδικός κατακεÏματισμοÏ, θα θεωÏηθεί ότι το αÏχείο έχει αλοιωθεί."
@@ -4745,6 +4848,10 @@ msgid "Idle"
msgstr "ΑνενεÏγό"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Εγκατάσταση..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Ξαναδοκίμασε"
@@ -4773,13 +4880,17 @@ msgid "Last"
msgstr "Τελευταίο"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Όλα"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Εκ νέου εισαγωγή..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "ΠÏόσθετα"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4787,8 +4898,8 @@ msgid "Sort:"
msgstr "Ταξινόμηση:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "ΑντιστÏοφή"
+msgid "Reverse sorting."
+msgstr "ΑντιστÏοφή ταξινόμησης."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4800,7 +4911,8 @@ msgid "Site:"
msgstr "ΔιεÏθυνση:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "ΥποστήÏιξη..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4812,6 +4924,11 @@ msgid "Testing"
msgstr "Δοκιμιμαστικά"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "ΦόÏτωσε..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ΑÏχείο ZIP των Asset"
@@ -4870,32 +4987,32 @@ msgid "Rotation Step:"
msgstr "Βήμα πεÏιστÏοφής:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Μετακίνηση κάθετου οδηγοÏ"
+msgid "Move Vertical Guide"
+msgstr "Μετακίνηση Κάθετου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "ΔημιουÏγία νέου κάθετου οδηγοÏ"
+msgid "Create Vertical Guide"
+msgstr "ΔημιουÏγία Κάθετου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "ΑφαίÏεση κάθετου οδηγοÏ"
+msgid "Remove Vertical Guide"
+msgstr "ΑφαίÏεση Κάθετου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Μετακίνηση οÏιζόντιου οδηγοÏ"
+msgid "Move Horizontal Guide"
+msgstr "Μετακίνηση ΟÏιζόντιου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "ΔημιουÏγία νέου οÏιζόντιου οδηγοÏ"
+msgid "Create Horizontal Guide"
+msgstr "ΔημιουÏγία ΟÏιζόντιου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "ΑφαίÏεση οÏιζόντιου οδηγοÏ"
+msgid "Remove Horizontal Guide"
+msgstr "ΑφαίÏεση ΟÏιζόντιου ΟδηγοÏ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "ΔημιουÏγία νέων οÏιζοντίων και κάθετων οδηγών"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "ΔημιουÏγία ΟÏιζοντίων και Καθέτων Οδηγών"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4978,6 +5095,11 @@ msgid "Paste Pose"
msgstr "Επικόληση στάσης"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "ΕκκαθάÏιση Οστών"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "ΔημιουÏγία ΠÏοσαÏμοσμένων Οστών από Κόμβους"
@@ -5008,6 +5130,7 @@ msgid "Zoom Reset"
msgstr "ΕπαναφοÏά Μεγέθυνσης"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Επιλογή λειτουÏγίας"
@@ -5029,14 +5152,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Δεξί κλικ: Επιλογή λίστας βάθους"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "ΛειτουÏγία μετακίνησης"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "ΛειτουÏγία πεÏιστÏοφής"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "ΛειτουÏγία Κλιμάκωσης"
@@ -5063,6 +5189,7 @@ msgid "Toggle snapping."
msgstr "Εναλλαγή κουμπώματος."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "ΧÏήση κουμπώματος"
@@ -5079,11 +5206,6 @@ msgid "Use Rotation Snap"
msgstr "ΧÏήση κουμπώματος πεÏιστÏοφής"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "ΔιαμόÏφωση κουμπώματος..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Σχετικό κοÏμπωμα"
@@ -5096,6 +5218,11 @@ msgid "Smart Snapping"
msgstr "Έξυπνο ΚοÏμπωμα"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "ΔιαμόÏφωση κουμπώματος..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "ΚοÏμπωμα στον Γονέα"
@@ -5310,16 +5437,6 @@ msgstr "ΟÏισμός λαβής"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Σφάλμα κατά την φόÏτωση εικόνας:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Δεν υπάÏχουν εικονοστοιχεία με διαφάνεια >128 στην εικόνα..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "ΦόÏτωση μάσκας εκπομπής"
@@ -5327,9 +5444,8 @@ msgstr "ΦόÏτωση μάσκας εκπομπής"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "Επανεκκίνηση Ï„ÏŽÏα"
+msgstr "Επανεκκίνηση"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5633,14 +5749,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Η πηγαία επιφάνεια δεν είναι έγκυÏη (Δεν υπάÏχουν επιφάνειες)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Ο γονέας δεν έχει συμπαγείς επιφάνειες για να συμπληÏωθοÏν."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Δεν ήταν δυνατή η χαÏτογÏάφηση της πεÏιοχής."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Έπιλέξτε ένα πηγαίο πλέγμα:"
@@ -5726,20 +5834,27 @@ msgid "Generation Time (sec):"
msgstr "ΧÏόνος παÏαγωγής (sec):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Οι επιφάνειες έχουν μηδενικό εμβαδόν!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Ο κόμβος δεν πεÏιέχει γεωμετÏία (Επιφάνειες)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Δεν υπάÏχουν επιφάνειες!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Ο κόμβος δεν πεÏιέχει γεωμετÏία."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Ο κόμβος δεν πεÏιέχει γεωμετÏία (Επιφάνειες)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Ο κόμβος δεν πεÏιέχει γεωμετÏία."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6073,7 +6188,6 @@ msgid "Grid Settings"
msgstr "Ρυθμίσεις Πλέγματος"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "ΚοÏμπωμα"
@@ -6179,12 +6293,9 @@ msgid "Error writing TextFile:"
msgstr "Σφάλμα εγγÏαφής TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Σφάλμα φόÏτωσης αÏχείου."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Σφάλμα φόÏτωσης αÏχείου."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Δεν ήταν δυνατή η εÏÏεση πλακιδίου:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6207,7 +6318,8 @@ msgid "Error Importing"
msgstr "Σφάλμα εισαγωγής"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Îέο TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6244,18 +6356,16 @@ msgid "Find Next"
msgstr "ΕÏÏεση επόμενου"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "ΦιλτÏάÏισμα ιδιοτήτων"
+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 "ΛειτουÏγία φιλτÏαÏίσματος:"
+msgstr "ΦιλτÏάÏισμα μεθόδων"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6275,11 +6385,11 @@ msgstr "Μετακίνηση κάτω"
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
-msgstr "Επόμενη δεσμή ενεÏγειών"
+msgstr "Επόμενη Δέμη ΕνεÏγειών"
#: editor/plugins/script_editor_plugin.cpp
msgid "Previous script"
-msgstr "ΠÏοηγοÏμενη δεσμή ενεÏγειών"
+msgstr "ΠÏοηγοÏμενη Δέσμη ΕνεÏγειών"
#: editor/plugins/script_editor_plugin.cpp
msgid "File"
@@ -6290,16 +6400,21 @@ msgid "Open..."
msgstr "Άνοιγμα..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Άνοιγμα Δέσμης ΕνεÏγειών"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Αποθήκευση όλων"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr "Απλή επαναφόÏτωση δεσμής ενεÏγειών"
+msgstr "Απλή ΕπαναφόÏτωση Δέσμης ΕνεÏγειών"
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
-msgstr "ΑντιγÏαφή διαδÏομής δεσμής ενεÏγειών"
+msgstr "ΑντιγÏαφή ΔιαδÏομής Δέσμης ΕνεÏγειών"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Previous"
@@ -6327,13 +6442,13 @@ msgid "Save Theme"
msgstr "Αποθήκευση θέματος"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Κλείσιμο τεκμηÏίωσης"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Κλείσιμο όλων"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Κλείσιμο τεκμηÏίωσης"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Εκτέλεση"
@@ -6421,6 +6536,11 @@ msgstr "Αποσφαλματωτής"
msgid "Search Results"
msgstr "Αποτελέσματα Αναζήτησης"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ΕκκαθάÏιση Ï€Ïόσφατων σκηνών"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "ΣÏνδεση σε μέθοδο:"
@@ -6489,8 +6609,9 @@ msgid "Syntax Highlighter"
msgstr "Επισημαντής ΣÏνταξης"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Πήγαινε Σε"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6498,9 +6619,8 @@ msgid "Bookmarks"
msgstr "Αγαπημένα"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "ΔημιουÏγία σημείων."
+msgstr "Σημεία Διακοπής"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6524,22 +6644,6 @@ msgid "Toggle Comment"
msgstr "Εναλλαγή σχολιασμοÏ"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Εναλλαγή Αγαπημένου"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Πήγαινε στο Επόμενο Αγαπημένο"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Πήγαινε στο ΠÏοηγοÏμενο Αγαπημένο"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "ΑφαίÏεση Όλων των Αγαπημένων"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Δίπλωμα/Ξεδίπλωμα γÏαμμής"
@@ -6560,6 +6664,11 @@ msgid "Complete Symbol"
msgstr "ΣυμπλήÏωση συμβόλου"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Μεγέθυνση επιλογής"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "ΠεÏικοπή ÎºÎ±Ï„Î±Î»Î·ÎºÏ„Î¹ÎºÎ¿Ï ÎºÎµÎ½Î¿Ï Î´Î¹Î±ÏƒÏ„Î®Î¼Î±Ï„Î¿Ï‚"
@@ -6576,29 +6685,32 @@ msgid "Auto Indent"
msgstr "Αυτόματη στοιχειοθέτηση"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Εναλλαγή σημείου διακοπής"
+msgid "Find Previous"
+msgstr "ΈυÏεση Ï€ÏοηγοÏμενου"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "ΑφαίÏεση όλων των σημείων διακοπής"
+msgid "Find in Files..."
+msgstr "ΕÏÏεση σε ΑÏχεία..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Πήγαινε στο επόμενο σημείο διακοπής"
+msgid "Contextual Help"
+msgstr "Βοήθεια ανάλογα με τα συμφÏαζόμενα"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "ΕπιστÏοφή στο Ï€ÏοηγοÏμενο σημείο διακοπής"
+msgid "Toggle Bookmark"
+msgstr "Εναλλαγή Αγαπημένου"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "ΈυÏεση Ï€ÏοηγοÏμενου"
+msgid "Go to Next Bookmark"
+msgstr "Πήγαινε στο Επόμενο Αγαπημένο"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "ΕÏÏεση σε ΑÏχεία..."
+msgid "Go to Previous Bookmark"
+msgstr "Πήγαινε στο ΠÏοηγοÏμενο Αγαπημένο"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "ΑφαίÏεση Όλων των Αγαπημένων"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6609,8 +6721,21 @@ msgid "Go to Line..."
msgstr "Πήγαινε σε γÏαμμή..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Βοήθεια ανάλογα με τα συμφÏαζόμενα"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Εναλλαγή σημείου διακοπής"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "ΑφαίÏεση όλων των σημείων διακοπής"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Πήγαινε στο επόμενο σημείο διακοπής"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "ΕπιστÏοφή στο Ï€ÏοηγοÏμενο σημείο διακοπής"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6791,8 +6916,12 @@ msgid "Rear"
msgstr "Πίσω"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Στοίχιση με ΠÏοβολή"
+msgid "Align Transform with View"
+msgstr "Στοίχιση ÎœÎµÏ„Î±ÏƒÏ‡Î·Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Î¼Îµ ΠÏοβολή"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Στοίχιση ΠεÏιστÏοφής με ΠÏοβολή"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6848,8 +6977,9 @@ msgid "Audio Listener"
msgstr "ΑκÏοατής ήχου"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Φαινόμενο ÎτόπλεÏ"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "ΕνεÏγοποίηση ΦίλτÏου"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6905,8 +7035,8 @@ msgid "Snap Nodes To Floor"
msgstr "ΚοÏμπωμα Κόμβων στο Δάπεδο"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Επιλογή λειτουÏγίας (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6919,30 +7049,11 @@ msgstr ""
"Alt + Δεξί κλικ: Επιλογή λίστας βάθους"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "ΛειτουÏγία μετακίνησης (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "ΛειτουÏγία πεÏιστÏοφής (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "ΛειτουÏγία κλιμάκωσης (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Τοπικές συντεταγμένες"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "ΛειτουÏγία Ï„Î¿Ï€Î¹ÎºÎ¿Ï Ï‡ÏŽÏου (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "ΛειτουÏγία κουμπώματος (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Κάτω όψη"
@@ -6983,26 +7094,6 @@ msgid "Focus Selection"
msgstr "Εστίαση στην επιλογή"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Στοίχηση επιλογής με την Ï€Ïοβολή"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "ΕÏγαλείο επιλογής"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "ΕÏγαλείο μετακίνησης"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "ΕÏγαλείο πεÏιστÏοφής"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "ΕÏγαλείο κλιμάκωσης"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Εναλλαγή ελεÏθεÏης κάμεÏας"
@@ -7057,7 +7148,8 @@ msgstr "ΠÏοβολή πλέγματος"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Ρυθμίσεις"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7350,10 +7442,6 @@ msgid "TextureRegion"
msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Δεν ήταν δυνατή η αποθήκευση θέματος σε αÏχείο:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "ΠÏοσθήκη όλων των στοιχείων"
@@ -7438,11 +7526,13 @@ msgid "Submenu"
msgstr "Υπό-ΜενοÏ"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Στοιχείο 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Στοιχείο 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7547,14 +7637,6 @@ msgid "Transpose"
msgstr "Μετατόπιση"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "ΣυμμετÏία στον άξονα Χ"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "ΣυμμετÏία στον άξονα Î¥"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "ΑπενεÏγοποίηση Αυτόματων Πλακιδίων"
@@ -7567,9 +7649,10 @@ msgid "Paint Tile"
msgstr "Βάψιμο πλακιδίου"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+Δεξί Κλικ: ΖωγÏάφισμα ΓÏαμμής\n"
"Shift+Ctrl+Δεξί Κλικ: ΖωγÏάφισμα ΟÏθογωνίου"
@@ -7867,6 +7950,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Μόνο GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "ΠÏοσθήκη εισόδου +"
@@ -7943,6 +8030,11 @@ msgid "Duplicate Nodes"
msgstr "ΑναπαÏαγωγή Κόμβων"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Επικόλληση κόμβων"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "ΔιαγÏαφή Κόμβων"
@@ -7963,6 +8055,11 @@ msgid "Light"
msgstr "Φως"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "ΔημιουÏγία Κόμβου Σκίασης"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "ΔημιουÏγία Κόμβου Σκίασης"
@@ -8035,6 +8132,22 @@ msgid "Color uniform."
msgstr "Ενιαία μεταβλητή χÏώματος."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "ΕπιστÏέφει το λογικό αποτέλεσμα της σÏγκÏισης για %s δÏο παÏαμέτÏων."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Ίσο (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "ΜεγαλÏτεÏο (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "ΜεγαλÏτεÏο ή Ίσο (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8044,11 +8157,49 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"ΕπιστÏέφει το λογικό αποτέλεσμα της σÏγκÏισης του INF με βαθμωτή παÏάμετÏο."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"ΕπιστÏέφει το λογικό αποτέλεσμα της σÏγκÏισης του NaN με βαθμωτή παÏάμετÏο."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "ΜικÏότεÏο (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "ΜικÏότεÏο ή Ίσο (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Άνισο (!=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
"ΕπιστÏέφει ένα συσχετισμένο διάνυσμα εάν η λογική τιμή είναι αληθής ή ψευδής."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "ΕπιστÏέφει το λογικό αποτέλεσμα της σÏγκÏισης δÏο παÏαμέτÏων."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"ΕπιστÏέφει το λογικό αποτέλεσμα της σÏγκÏισης του INF (ή NaN) με μια βαθμωτή "
+"παÏάμετÏο."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Λογική σταθεÏά."
@@ -8057,43 +8208,36 @@ msgid "Boolean uniform."
msgstr "Λογική ενιαία μεταβλητή."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for all shader modes."
-msgstr "ΠαÏάμετÏος εισόδου «uv» για όλες τις λειτουÏγίες σκίασης."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για όλες τις λειτουÏγίες σκίασης."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Input parameter."
msgstr "ΠαÏάμετÏος εισόδου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr "ΠαÏάμετÏος εισόδου «uv» για σκίαση κοÏυφής και τμήματος."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση κοÏυφής και τμήματος."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr "ΠαÏάμετÏος εισόδου «view» για σκίαση τμήματος και φωτός."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση τμήματος και φωτός."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for fragment shader mode."
-msgstr "ΠαÏάμετÏος εισόδου «side» για σκίαση τμήματος."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση τμήματος."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for light shader mode."
-msgstr "ΠαÏάμετÏος εισόδου «diffuse» για σκίαση φωτός."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση φωτός."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex shader mode."
-msgstr "ΠαÏάμετÏος εισόδου «custom» για σκίαση κοÏυφής."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση κοÏυφής."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr "ΠαÏάμετÏος εισόδου «uv» για σκίαση κοÏυφής και τμήματος."
+msgstr "ΠαÏάμετÏος εισόδου «%s» για σκίαση κοÏυφής και τμήματος."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar function."
@@ -8144,18 +8288,16 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "ΕπιστÏέφει το τόξο συνημιτόνου της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
-"(Μόνο GLES3) ΕπιστÏέφει το αντίστÏοφο υπεÏβολικό συνημίτονο της παÏαμέτÏου."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "ΕπιστÏέφει το αντίστÏοφο υπεÏβολικό συνημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "ΕπιστÏέφει το τόξο ημιτόνου της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
-"(Μόνο GLES3) ΕπιστÏέφει το αντίστÏοφο υπεÏβολικό ημίτονο της παÏαμέτÏου."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "ΕπιστÏέφει το αντίστÏοφο υπεÏβολικό ημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8166,9 +8308,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "ΕπιστÏέφει το τόξο εφαπτομένης των παÏαμέτÏων."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr ""
-"(Μόνο GLES3) ΕπιστÏέφει την αντίστÏοφη υπεÏβολική εφαπτομένη της παÏαμέτÏου."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "ΕπιστÏέφει την αντίστÏοφη υπεÏβολική εφαπτομένη της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8184,8 +8325,8 @@ msgid "Returns the cosine of the parameter."
msgstr "ΕπιστÏέφει το συνημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(Μόνο GLES3) ΕπιστÏέφει το υπεÏβολικό συνημίτονο της παÏαμέτÏου."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "ΕπιστÏέφει το υπεÏβολικό συνημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8254,12 +8395,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / βαθμωτό μέγεθος"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Μόνο GLES3) Î’Ïίσκει τον κοντινότεÏο ακέÏαιο στην παÏάμετÏο."
+msgid "Finds the nearest integer to the parameter."
+msgstr "Î’Ïίσκει τον κοντινότεÏο ακέÏαιο στην παÏάμετÏο."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr "(Μόνο GLES3) Î’Ïίσκει τον κοντινότεÏο άÏτιο ακέÏαιο στην παÏάμετÏο."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Î’Ïίσκει τον κοντινότεÏο άÏτιο ακέÏαιο στην παÏάμετÏο."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -8274,32 +8415,34 @@ msgid "Returns the sine of the parameter."
msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(Μόνο GLES3) ΕπιστÏέφει το υπεÏβολικό ημίτονο της παÏαμέτÏου."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "ΕπιστÏέφει το υπεÏβολικό ημίτονο της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "ΕπιστÏέφει την τετÏαγωνική Ïίζα της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
"ΣυνάÏτηση SmoothStep( βαθμωτό(ÏŒÏιο0), βαθμωτό(ÏŒÏιο1), βαθμωτό(x) ).\n"
"\n"
"ΕπιστÏέφει 0.0 αν x < ÏŒÏιο0 και 1.0 αν x > ÏŒÏιο1. Αλλιώς επιστÏέφει μια "
-"παÏεμβεβλημένη τιμή ανάμεσα στο 0.0 και το 1.0 χÏησιμοποιώντας πολυώνυμα "
+"παÏεμβλημένη τιμή ανάμεσα στο 0.0 και το 1.0 χÏησιμοποιώντας πολυώνυμα "
"Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"ΣυνάÏτηση Step( βαθμωτό(ÏŒÏιο), βαθμωτό(x) ).\n"
"\n"
@@ -8310,12 +8453,12 @@ msgid "Returns the tangent of the parameter."
msgstr "ΕπιστÏέφει την εφαπτομένη της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr "(Μόνο GLES3) ΕπιστÏέφει την υπεÏβολική εφαπτομένη της παÏαμέτÏου."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "ΕπιστÏέφει την υπεÏβολική εφαπτομένη της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr "(Μόνο GLES3) Î’Ïίσκει την πεÏικομμένη τιμή της παÏαμέτÏου."
+msgid "Finds the truncated value of the parameter."
+msgstr "Î’Ïίσκει την πεÏικομμένη τιμή της παÏαμέτÏου."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8354,12 +8497,16 @@ msgid "Perform the texture lookup."
msgstr "Εκτέλεση αντιστοιχίας υφής."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Ενιαία μεταβλητή κυβικής υφής."
+msgid "Cubic texture uniform lookup."
+msgstr "Αναζήτηση ενιαίας μεταβλητής κυβικής υφής."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr "Αναζήτηση ενιαίας μεταβλητής 2D υφής."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "Ενιαία μεταβλητή 2D υφής."
+msgid "2D texture uniform lookup with triplanar."
+msgstr "ΤÏιεπίπεδη αναζήτηση ενιαίας μεταβλητής 2D υφής."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8367,7 +8514,7 @@ msgstr "ΣυνάÏτηση μετασχηματισμοÏ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8375,174 +8522,206 @@ 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 ""
+"Υπολογισμός Ï„Î±Î½Ï…ÏƒÏ„Î¹ÎºÎ¿Ï Î³Î¹Î½Î¿Î¼Î­Î½Î¿Ï… δÏο διανυσμάτων.\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 ""
+msgid "Calculates the determinant of a transform."
+msgstr "Υπολογίζει την οÏίζουσα ενός μετασχηματισμοÏ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Υπολογίζει το αντίστÏοφο ενός μετασχηματισμοÏ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Υπολογίζει το ανάστÏοφο ενός μετασχηματισμοÏ."
#: 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 "Συνθέτει διάνυσμα από 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 ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"ΕπιστÏέφει ένα διάνυσμα ίδιας κατεÏθυνσης με ένα διάνυσμα αναφοÏάς. Η "
+"συνάÏτηση έχει 3 διανυσματικές παÏαμέτÏους: 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 "ΓÏαμμική παÏεμβολή Î¼ÎµÏ„Î±Î¾Ï 2 διανυσμάτων."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+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 "
+"Returns the 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 ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "ΕπιστÏέφει το διάνυσμα που δείχνει Ï€Ïος την κατεÏθυνση διάθλασης."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"ΣυνάÏτηση SmoothStep( διάνυσμα(ÏŒÏιο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
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"ΣυνάÏτηση SmoothStep( βαθμωτό(ÏŒÏιο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
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"ΣυνάÏτηση Step( διάνυσμα(ÏŒÏιο), διάνυσμα(x) ).\n"
+"\n"
+"ΕπιστÏέφει 0.0 αν x < ÏŒÏιο αλλιώς 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"ΣυνάÏτηση Step( βαθμωτό(ÏŒÏιο), διάνυσμα(x) ).\n"
+"\n"
+"ΕπιστÏέφει 0.0 αν x < ÏŒÏιο αλλιώς 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "ΠÏοσθέτει 2 διανÏσματα."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "ΔιαιÏεί 2 διανÏσματα."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "Πολλαπλασιάζει 2 διανÏσματα."
#: 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 "ΑφαίÏεση 2 διανυσμάτων."
#: 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 ""
@@ -8550,70 +8729,92 @@ 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."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Μόνο σε σκίαση Τμήματος/Φωτός) Βαθμωτή παÏάγωγη συνάÏτηση."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Μόνο σε σκίαση Τμήματος/Φωτός) Διανυσματική παÏάγωγη συνάÏτηση."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Διανυσματικά) ΠαÏάγωγος στο «x» με τοπική "
+"διαφόÏιση."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Βαθμωτά) ΠαÏάγωγος στο «x» με τοπική "
+"διαφόÏιση."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Διανυσματικά) ΠαÏάγωγος στο «y» με τοπική "
+"διαφόÏιση."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Βαθμωτά) ΠαÏάγωγος στο «y» με τοπική "
+"διαφόÏιση."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Διανυσματικά) ΆθÏοισμα απόλυτης παÏαγώγου "
+"σε «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'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Μόνο σε σκίαση Τμήματος/Φωτός) (Βαθμωτά) ΆθÏοισμα απόλυτης παÏαγώγου σε «x» "
+"και «y»."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
msgstr "Οπτικό ΠÏόγÏαμμα Σκίασης"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "ΕπεξεÏγασία φίλτÏων"
+msgstr "ΕπεξεÏγασία Οπτικής Ιδιότητας"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Visual Shader Mode Changed"
-msgstr "Αλλαγές Ï€ÏογÏάμματος σκίασης"
+msgstr "Αλλαγή ΛειτουÏγίας ÎŸÏ€Ï„Î¹ÎºÎ¿Ï Î ÏογÏάμματος Σκίασης"
#: editor/project_export.cpp
msgid "Runnable"
@@ -8632,6 +8833,8 @@ msgid ""
"Failed to export the project for platform '%s'.\n"
"Export templates seem to be missing or invalid."
msgstr ""
+"Αποτυχία εξαγωγής έÏγου στην πλατφόÏμα «%s».\n"
+"Τα Ï€Ïότυπα εξαγωγής λείπουν ή είναι άκυÏα."
#: editor/project_export.cpp
msgid ""
@@ -8639,21 +8842,21 @@ msgid ""
"This might be due to a configuration issue in the export preset or your "
"export settings."
msgstr ""
+"Αποτυχία εξαγωγής έÏγου στην πλατφόÏμα «%s».\n"
+"Αυτό μποÏεί να οφείλεται σε λάθος της διαμόÏφωσης εξαγωγής ή στις Ïυθμίσεις "
+"εξαγωγής σας."
#: editor/project_export.cpp
-#, fuzzy
msgid "Release"
-msgstr "μόλις απελευθεÏώθηκε"
+msgstr "ΚυκλοφοÏία"
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "Εξαγωγή για %s"
+msgstr "Εξαγωγή Όλων"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "Η διαδÏομή δεν υπάÏχει."
+msgstr "Η δεδομένη διαδÏομή εξαγωγής δεν υπάÏχει:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
@@ -8669,9 +8872,8 @@ msgid "Add..."
msgstr "ΠÏοσθήκη..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Path"
-msgstr "Εξαγωγή έÏγου"
+msgstr "ΔιαδÏομή Εξαγωγής"
#: editor/project_export.cpp
msgid "Resources"
@@ -8732,56 +8934,54 @@ msgid "Feature List:"
msgstr "Λίστα δυνατοτήτων:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script"
-msgstr "Îεα δεσμή ενεÏγειών"
+msgstr "Δέσμες ΕνεÏγειών"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script Export Mode:"
-msgstr "ΛειτουÏγία εξαγωγής:"
+msgstr "ΛειτουÏγία Εξαγωγής Δεσμών ΕνεÏγειών:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Text"
-msgstr "Υφή"
+msgstr "Κείμενο"
#: editor/project_export.cpp
-#, fuzzy
msgid "Compiled"
-msgstr "Συμπίεση"
+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 "Κλειδί ΚÏυπτογÏάφησης Δεσμών ΕνεÏγειών (256-bit σε δεκαεξαδικό):"
#: editor/project_export.cpp
msgid "Export PCK/Zip"
msgstr "Εξαγωγή PCK/ZIP"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "ΛειτουÏγία εξαγωγής:"
+msgstr "ΛειτουÏγία εξαγωγής;"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All"
-msgstr "Εξαγωγή"
+msgstr "Εξαγωγή Όλων"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
msgstr "Τα Ï€Ïότυπα εξαγωγής για αυτή την πλατφόÏτμα λείπουν:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "ΔιαχείÏιση Ï€ÏοτÏπων εξαγωγής"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Εξαγωγή με αποσφαλμάτωση"
@@ -8790,23 +8990,20 @@ msgid "The path does not exist."
msgstr "Η διαδÏομή δεν υπάÏχει."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
-msgstr ""
-"ΠαÏακαλοÏμε επιλέξτε έναν φάκελο που δεν πεÏιέχει ένα αÏχείο 'project.godot'."
+msgstr "ΆκυÏο αÏχείο έÏγου «.zip», δεν πεÏιέχει αÏχείο «project.godot»."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
msgstr "ΠαÏακαλοÏμε επιλέξτε έναν άδειο φάκελο."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Please choose a 'project.godot' or '.zip' file."
-msgstr "ΠαÏακαλοÏμε επιλέκτε ένα αÏχείο 'project.godot'."
+msgstr "ΠαÏακαλοÏμε επιλέξτε ένα αÏχείο «project.godot» ή «.zip»."
#: editor/project_manager.cpp
msgid "Directory already contains a Godot project."
-msgstr ""
+msgstr "Ο κατάλογος πεÏιέχει ήδη ένα έÏγο της Godot."
#: editor/project_manager.cpp
msgid "New Game Project"
@@ -8894,17 +9091,16 @@ msgid "Project Path:"
msgstr "ΔιαδÏομή έÏγου:"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Project Installation Path:"
-msgstr "ΔιαδÏομή έÏγου:"
+msgstr "ΔιαδÏομή Εγκατάστασης ΕÏγου:"
#: editor/project_manager.cpp
msgid "Renderer:"
-msgstr ""
+msgstr "Μέθοδος Απόδοσης:"
#: editor/project_manager.cpp
msgid "OpenGL ES 3.0"
-msgstr ""
+msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid ""
@@ -8913,10 +9109,14 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
+"ΥψηλότεÏη οπτική ποιότητα\n"
+"Διάθεση όλων των δυνατοτήτων\n"
+"Μη-συμβατό με παλαιότεÏο υλικό\n"
+"Δεν Ï€Ïοτείνεται για διαδικτυακά παιχνίδια"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
-msgstr ""
+msgstr "OpenGL ES 2.0"
#: editor/project_manager.cpp
msgid ""
@@ -8925,10 +9125,16 @@ msgid ""
"Works on most hardware\n"
"Recommended for web games"
msgstr ""
+"ΧαμηλότεÏη οπτική ποιότητα\n"
+"ΜεÏική διάθεση δυνατοτήτων\n"
+"ΔουλεÏει στο πεÏισσότεÏο υλικό\n"
+"ΠÏοτείνεται για διαδικτυακά παιχνίδια"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
msgstr ""
+"Η μέθοδος απόδοσης μποÏεί να αλλάξει αÏγότεÏα, αλλά οι σκηνές μποÏεί να "
+"απαιτοÏν αναπÏοσαÏμογή."
#: editor/project_manager.cpp
msgid "Unnamed Project"
@@ -8936,8 +9142,16 @@ msgstr "Ανώνυμο έÏγο"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Εισαγωγή υπαÏÎºÏ„Î¿Ï Î­Ïγου"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
-msgstr "Δεν ήταν δυνατό το άνοιγμα του έÏγου"
+msgstr "Αδυνατό το άνοιγμα του έÏγου στο «%s»."
#: editor/project_manager.cpp
msgid "Are you sure to open more than one project?"
@@ -8955,6 +9169,15 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
+"Το ακόλουθο αÏχείο Ïυθμίσεων έÏγου δεν οÏίζει την έκδοση της Godot με την "
+"οποία δημιουÏγήθηκε.\n"
+"\n"
+"%s\n"
+"\n"
+"Εάν συνεχίσετε με το άνοιγμα του, θα μετατÏαπεί στην Ï„Ïέχουσα μοÏφή "
+"Ïυθμίσεων της Godot.\n"
+"ΠÏοσοχή: Δεν θα μποÏείτε να ανοίξετε το έÏγο με Ï€ÏοηγοÏμενες εκδόσεις της "
+"μηχανής στο μέλλον."
#: editor/project_manager.cpp
msgid ""
@@ -8967,23 +9190,32 @@ 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"
+"ΕπεξεÏγαστείτε το έÏγο και οÏίστε την κÏÏια σκηνή στις «Ρυθμίσεις έÏγου» "
+"κάτω από την κατηγοÏία «Application»."
#: editor/project_manager.cpp
msgid ""
@@ -8994,62 +9226,59 @@ 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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"ΑφαίÏεση έÏγου από την λίστα; (Τα πεÏιεχόμενα το φακέλου δεν θα "
-"Ï„ÏοποποιηθοÏν)"
+"ΑφαίÏεση %d έÏγων από την λίστα;\n"
+"Τα πεÏιεχόμενα των καταλόγων των έÏγων δεν θα Ï„ÏοποποιηθοÏν."
#: 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"
msgstr "ΔιαχειÏιστής"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Λίστα έÏγων"
+#, fuzzy
+msgid "Projects"
+msgstr "ΈÏγο"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9064,19 +9293,14 @@ msgid "New Project"
msgstr "Îέο έÏγο"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "ΑφαίÏεση σημείου"
+msgstr "ΑφαίÏεση Απόντων"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "ΠÏότυπα"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Έξοδος"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Επανεκκίνηση Ï„ÏŽÏα"
@@ -9085,13 +9309,12 @@ 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"
-"Θέλετε να εξεÏευνήσετε μεÏικά παÏαδείγματα στην βιβλιοθήκη πόÏων;"
+"Θέλετε να εξεÏευνήσετε μεÏικά επίσημα παÏαδείγματα στην βιβλιοθήκη πόÏων;"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9110,36 +9333,32 @@ msgid "Mouse Button"
msgstr "Κουμπί ποντικιοÏ"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
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"
msgstr "Μετονομασία συμβάντος εισόδου"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "Αλλαγή ονόματος κίνησης:"
+msgstr "Αλλαγή ÎεκÏής Ζώνης ΕνέÏγειας"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
msgstr "ΠÏοσθήκη συμβάντος εισόδου"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "All Devices"
-msgstr "Συσκευή"
+msgstr "Όλες οι Συσκευές"
#: editor/project_settings_editor.cpp
msgid "Device"
@@ -9186,24 +9405,20 @@ msgid "Wheel Down Button"
msgstr "Ροδέλα κάτω"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Left Button"
-msgstr "Ροδέλα πάνω"
+msgstr "ΑÏιστεÏÏŒ Κουμπί Ροδέλας"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Right Button"
-msgstr "Δεξί κουμπί"
+msgstr "Δεξί Κουμπί Ροδέλας"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 1"
-msgstr "Κουμπί 6"
+msgstr "Κουμπί Χ 1"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 2"
-msgstr "Κουμπί 6"
+msgstr "Κουμπί Χ 2"
#: editor/project_settings_editor.cpp
msgid "Joypad Axis Index:"
@@ -9347,7 +9562,7 @@ msgstr "ΠαÏάκαμψη για..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
-msgstr ""
+msgstr "Ο επεξεÏγαστής Ï€Ïέπει να επανεκκινηθεί για να εφαÏμοστοÏν οι αλλαγές."
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -9363,7 +9578,7 @@ msgstr "ΕνέÏγεια"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
-msgstr ""
+msgstr "ÎεκÏή Ζώνη"
#: editor/project_settings_editor.cpp
msgid "Device:"
@@ -9406,14 +9621,12 @@ msgid "Locales Filter"
msgstr "ΦίλτÏο τοπικών Ïυθμίσεων"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "Εμφάνιση όλων των τοπικών Ïυθμίσεων"
+msgstr "Εμφάνιση Όλων των Τοπικών Ρυθμίσεων"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "Εμφάνιση μόνο επιλεγμένων τοπικών Ïυθμίσεων"
+msgstr "Εμφάνιση Μόνο Επιλεγμένων Τοπικών Ρυθμίσεων"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
@@ -9427,6 +9640,10 @@ msgstr "ΠεÏιοχές:"
msgid "AutoLoad"
msgstr "Αυτόματη φόÏτωση"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "ΠÏόσθετα"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Μηδέν"
@@ -9479,139 +9696,121 @@ msgstr "Επιλογή εικονικής μεθόδου"
msgid "Select Method"
msgstr "Επιλογή μεθόδου"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Δεν ήταν δυνατή η εκτέλεση του εÏγαλείου PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"Δεν ήταν δυνατή η επαναφόÏτωση της εικόνας που έχει μετατÏαπεί με το "
-"εÏγαλείο PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Batch Rename"
-msgstr "Μετονομασία"
+msgstr "Ομαδική Μετονομασία"
#: editor/rename_dialog.cpp
msgid "Prefix"
-msgstr ""
+msgstr "ΠÏόθεμα"
#: editor/rename_dialog.cpp
msgid "Suffix"
-msgstr ""
+msgstr "Επίθεμα"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "Επιλογές κουμπώματος"
+msgstr "ΠÏοχωÏημένες Επιλογές"
#: editor/rename_dialog.cpp
msgid "Substitute"
-msgstr ""
+msgstr "Αντικατάσταση"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node name"
-msgstr "Όνομα κόμβου:"
+msgstr "Όνομα κόμβου"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
-msgstr ""
+msgstr "Όνομα Î³Î¿Î½Î¹ÎºÎ¿Ï ÎºÏŒÎ¼Î²Î¿Ï…, εάν είναι διαθέσιμο"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "ΕÏÏεση είδους κόμβου"
+msgstr "Είδος Κόμβου"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Current scene name"
-msgstr "ΤÏέχουσα σκηνή"
+msgstr "Όνομα Ï„Ïέχουσας σκηνής"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Root node name"
-msgstr "Όνομα ÏÎ¹Î¶Î¹ÎºÎ¿Ï ÎºÏŒÎ¼Î²Î¿Ï…:"
+msgstr "Όνομα ÏÎ¹Î¶Î¹ÎºÎ¿Ï ÎºÏŒÎ¼Î²Î¿Ï…"
#: editor/rename_dialog.cpp
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
-#, fuzzy
msgid "Step"
-msgstr "Βήμα:"
+msgstr "Βήμα"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
-msgstr ""
+msgstr "Τιμή κατά την οποία αυξάνεται ο μετÏητής ανά κόμβο"
#: editor/rename_dialog.cpp
msgid "Padding"
-msgstr ""
+msgstr "ΑναπλήÏωση"
#: editor/rename_dialog.cpp
msgid ""
"Minimum number of digits for the counter.\n"
"Missing digits are padded with leading zeros."
msgstr ""
+"Ελάχιστος αÏιθμός ψηφίων μετÏητή.\n"
+"Τα εναπομείναντα ψηφία συμπληÏώνονται με μπÏοστινά μηδενικά."
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expressions"
-msgstr "Αλλαγή έκφÏασης"
+msgstr "Κανονικές ΕκφÏάσεις"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Post-Process"
-msgstr "Δεσμή ενεÏγειών μετ-επεξεÏγασίας:"
+msgstr "ΜετεπεξεÏγασία"
#: editor/rename_dialog.cpp
msgid "Keep"
-msgstr ""
+msgstr "ΔιατήÏηση"
#: editor/rename_dialog.cpp
msgid "CamelCase to under_scored"
-msgstr ""
+msgstr "CamelCase σε under_scored"
#: editor/rename_dialog.cpp
msgid "under_scored to CamelCase"
-msgstr ""
+msgstr "under_scored σε CamelCase"
#: editor/rename_dialog.cpp
msgid "Case"
-msgstr ""
+msgstr "ΧαÏακτήÏες"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Lowercase"
-msgstr "Πεζά"
+msgstr "Κάνε Πεζά"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "To Uppercase"
-msgstr "Κεφαλαία"
+msgstr "Κάνε Κεφαλαία"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Reset"
-msgstr "ΕπαναφοÏά μεγέθυνσης"
+msgstr "ΕπαναφοÏά"
#: editor/rename_dialog.cpp
msgid "Error"
@@ -9679,7 +9878,7 @@ msgstr "ΑÏχικοποίηση σκηνής ως παιδί"
#: editor/scene_tree_dock.cpp
msgid "Clear Script"
-msgstr "ΕκκαθάÏιση δεσμής ενεÏγειών"
+msgstr "ΕκκαθάÏιση Δέσμης ΕνεÏγειών"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
@@ -9700,19 +9899,21 @@ msgstr "ΑναπαÏαγωγή Κόμβων"
#: editor/scene_tree_dock.cpp
msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
msgstr ""
+"Αδυναμία επαναπÏοσδιοÏÎ¹ÏƒÎ¼Î¿Ï Î³Î¿Î½Î­Ï‰Î½ σε κληÏονομημένες σκηνές, δεν μποÏεί να "
+"αλλάξει η σειÏά των κόμβων."
#: editor/scene_tree_dock.cpp
msgid "Node must belong to the edited scene to become root."
msgstr ""
+"Ο κόμβος Ï€Ïέπει να ανήκει στην επεξεÏγαζόμενη σκηνή για να γίνει Ïιζικός."
#: editor/scene_tree_dock.cpp
msgid "Instantiated scenes can't become root"
-msgstr ""
+msgstr "Η Ïίζα δεν μποÏεί να είναι κλωνοποιημένη σκηνή"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make node as Root"
-msgstr "Βγάζει νόημα!"
+msgstr "Κάνε κόμβο Ïίζα"
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)?"
@@ -9725,8 +9926,8 @@ msgstr "Δεν είναι δυνατή η εκτέλεση με τον πηγαÎ
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on instanced scenes."
msgstr ""
-"Αυτή η λειτουÏγία δεν μποÏεί να γίνει σε σκηνές από τις οποίες έχουν "
-"δημιουÏγηθεί στιγμιότυπα."
+"Αυτή η λειτουÏγία δεν μποÏεί να γίνει σε κλωνοποιημένες σκηνές από τις "
+"οποίες έχουν δημιουÏγηθεί στιγμιότυπα."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -9737,6 +9938,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"
@@ -9751,34 +9954,28 @@ msgid "Make Local"
msgstr "Κάνε τοπικό"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "New Scene Root"
-msgstr "Βγάζει νόημα!"
+msgstr "Îέα Ρίζα Σκηνής"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "ΔημιουÏγία κόμβου"
+msgstr "ΔημιουÏγία Î¡Î¹Î¶Î¹ÎºÎ¿Ï ÎšÏŒÎ¼Î²Î¿Ï…:"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "2D Scene"
-msgstr "Σκηνή"
+msgstr "2D Σκηνή"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "3D Scene"
-msgstr "Σκηνή"
+msgstr "3D Σκηνή"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "User Interface"
-msgstr "ΕκκαθάÏιση κληÏονομικότητας"
+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!"
@@ -9792,13 +9989,18 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
-msgstr "ΣÏνδεση δεσμής ενεÏγειών"
+msgstr "ΣÏνδεση Δέσμης ΕνεÏγειών"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "ΑφαίÏεση κόμβων"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Αλλαγή ονόματος θÏÏας εξόδου"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9823,32 +10025,32 @@ msgid "Clear Inheritance"
msgstr "ΕκκαθάÏιση κληÏονομικότητας"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
-msgstr "Άνοιγμα ηλεκτÏονικής τεκμηÏίωσης της Godot"
+msgstr "Άνοιγμα ΤεκμηÏίωσης"
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
msgstr "ΠÏοσθήκη κόμβου ως παιδί"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "ΣÏμπτηξη Όλων"
+msgstr "ΣÏμπτυξη Όλων"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
msgstr "Αλλαγή Ï„Ïπου"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Extend Script"
-msgstr "Άνοιγμα δεσμής ενεÏγειών"
+msgstr "Επέκταση Δέσμης ΕνεÏγειών"
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "ΕπαναπÏοσδιοÏισμός Γονέα"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Scene Root"
-msgstr "Βγάζει νόημα!"
+msgstr "Κάνε Ρίζα Σκηνής"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -9867,9 +10069,8 @@ msgid "Delete (No Confirm)"
msgstr "ΔιαγÏαφή (ΧωÏίς επιβεβαίωση)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "ΠÏοσθήκη/ΔημιουÏγία κόμβου"
+msgstr "ΠÏοσθήκη/ΔημιουÏγία Κόμβου."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -9881,11 +10082,11 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Attach a new or existing script for the selected node."
-msgstr "ΣÏνδεση νέας ή υπαÏκτής δεσμής ενεÏγειών για τον επιλεγμένο κόμβο."
+msgstr "ΣÏνδεση νέας ή υπαÏκτής δέσμης ενεÏγειών για τον επιλεγμένο κόμβο."
#: editor/scene_tree_dock.cpp
msgid "Clear a script for the selected node."
-msgstr "ΕκκαθάÏιση δεσμής ενεÏγειών για τον επιλεγμένο κόμβο."
+msgstr "ΕκκαθάÏιση δέσμης ενεÏγειών για τον επιλεγμένο κόμβο."
#: editor/scene_tree_dock.cpp
msgid "Remote"
@@ -9900,24 +10101,20 @@ msgid "Clear Inheritance? (No Undo!)"
msgstr "ΕκκαθάÏιση κληÏονομικότητας; (Δεν γίνεται ανέÏαιση!)"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Toggle Visible"
-msgstr "Εναλλαγή οÏατότητας"
+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:"
@@ -9926,50 +10123,49 @@ msgstr "ΠÏοειδοποίηση διαμόÏφωσης κόμβου:"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
-"Ο κόμβος έχει συνδέσεις και ομάδες\n"
+"Ο κόμβος έχει συνδέσεις και ομάδες.\n"
"Πατήστε για να δείξετε την πλατφόÏμα σημάτων."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Ο κόμβος έχει συνδέσεις\n"
"Πατήστε για να δείξετε την πλατφόÏμα σημάτων."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Ο κόμβος έχει και ομάδες\n"
"Πατήστε για να δείξετε την πλατφόÏμα σημάτων."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Άνοιγμα δεσμής ενεÏγειών"
+msgstr "Άνοιγμα Δέσμης ΕνεÏγειών:"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid ""
"Node is locked.\n"
"Click to unlock it."
msgstr ""
-"Ο κόμβος είναι κλειδομένος.\n"
-"Πατήστε για ξεκλείδωμα"
+"Ο κόμβος είναι κλειδωμένος.\n"
+"Πατήστε για ξεκλείδωμα."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid ""
"Children are not selectable.\n"
"Click to make selectable."
msgstr ""
"Τα παιδιά δεν είναι επιλέξιμα.\n"
-"Πατήστε για να τα κάνετε επιλέξιμα"
+"Πατήστε για να τα κάνετε επιλέξιμα."
#: editor/scene_tree_editor.cpp
msgid "Toggle Visibility"
@@ -9980,6 +10176,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:"
@@ -10002,39 +10200,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'"
@@ -10042,65 +10233,60 @@ msgstr "Σφάλμα κατά την φόÏτωση Ï€ÏοτÏπου '%s'"
#: editor/script_create_dialog.cpp
msgid "Error - Could not create script in filesystem."
-msgstr ""
-"Σφάλμα - Δεν ήταν δυνατή η δημιουÏγία δεσμής ενεÏγειών στο σÏστημα αÏχείων."
+msgstr "Σφάλμα - Αδυναμία δημιουÏγίας δέσμης ενεÏγειών στο σÏστημα αÏχείων."
#: editor/script_create_dialog.cpp
msgid "Error loading script from %s"
-msgstr "Σφάλμα κατά την φόÏτωση δεσμής ενεÏγειών από %s"
+msgstr "Σφάλμα κατά την φόÏτωση δέσμής ενεÏγειών από %s"
+
+#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Αντικατάσταση"
#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Δ/Υ"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
-msgstr "Άνοιγμα επεξεÏγαστή δεσμής ενεÏγειών"
+msgstr "Άνοιγμα Δέσμης ΕνεÏγειών / Επιλογή Θέσης"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script"
-msgstr "Άνοιγμα δεσμής ενεÏγειών"
+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 και _"
+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"
@@ -10124,7 +10310,7 @@ msgstr "Ενσωμάτωση"
#: editor/script_create_dialog.cpp
msgid "Attach Node Script"
-msgstr "ΣÏνδεση δεσμής ενεÏγειών κόμβου"
+msgstr "ΣÏνδεση Δέσμης ΕνεÏγειών Κόμβου"
#: editor/script_editor_debugger.cpp
msgid "Remote "
@@ -10135,9 +10321,8 @@ msgid "Bytes:"
msgstr "Ψηφιολέξεις:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Stack Trace"
-msgstr "Στοίβαξη καÏέ"
+msgstr "Ίχνος Στοίβας"
#: editor/script_editor_debugger.cpp
msgid "Pick one or more items from the list to display the graph."
@@ -10235,7 +10420,7 @@ msgstr "ΟÏισμός από το δέντÏο"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Εξαγωγή μετÏικών ως CSV"
#: editor/settings_config_dialog.cpp
#, fuzzy
@@ -10253,6 +10438,10 @@ msgid "Change Shortcut"
msgstr "Αλλαγή αγκυÏών"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Ρυθμίσεις επεξεÏγαστή"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "ΣυντομεÏσεις"
@@ -10407,11 +10596,11 @@ msgstr "Η παÏάμετÏος step είναι μηδέν!"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not a script with an instance"
-msgstr "Δεν είναι δεσμή ενεÏγειών με στιγμιότυπο"
+msgstr "Δεν είναι δέσμη ενεÏγειών με στιγμιότυπο"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not based on a script"
-msgstr "Δεν είναι βασισμένο σε δεσμή ενεÏγειών"
+msgstr "Δεν είναι βασισμένο σε δέσμη ενεÏγειών"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not based on a resource file"
@@ -10424,12 +10613,12 @@ msgstr "ΆκυÏη μοÏφή Î»ÎµÎ¾Î¹ÎºÎ¿Ï ÏƒÏ„Î¹Î³Î¼Î¹Î¿Ï„Ïπων (λείπÎ
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (can't load script at @path)"
msgstr ""
-"ΆκυÏη μοÏφή Î»ÎµÎ¾Î¹ÎºÎ¿Ï ÏƒÏ„Î¹Î³Î¼Î¹Î¿Ï„Ïπων (αδÏνατη η φόÏτωση της δεσμής ενεÏγειών στο "
+"ΆκυÏη μοÏφή Î»ÎµÎ¾Î¹ÎºÎ¿Ï ÏƒÏ„Î¹Î³Î¼Î¹Î¿Ï„Ïπων (αδÏνατη η φόÏτωση της δέσμης ενεÏγειών στο "
"@path)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (invalid script at @path)"
-msgstr "ΆκυÏη μοÏφή Î»ÎµÎ¾Î¹ÎºÎ¿Ï ÏƒÏ„Î¹Î³Î¼Î¹Î¿Ï„Ïπων (Μη έγκυÏη δεσμή ενεÏγειών στο @path)"
+msgstr "ΆκυÏη μοÏφή Î»ÎµÎ¾Î¹ÎºÎ¿Ï ÏƒÏ„Î¹Î³Î¼Î¹Î¿Ï„Ïπων (Μη έγκυÏη δέσμη ενεÏγειών στο @path)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
@@ -10684,10 +10873,30 @@ msgid "Set Variable Type"
msgstr "ΟÏισμός Ï„Ïπου μεταβλητής"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Δεν μποÏεί να συγχέεται με υπαÏκτό ενσωματωμένο όνομα Ï„Ïπου."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "ΔημιουÏγία νέου οÏθογωνίου."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Μεταβλητές:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "ΔημιουÏγία νέου οÏθογωνίου."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "ΔημιουÏγία νέου πολυγώνου."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Το όνομα δεν είναι έγκυÏο αναγνωÏιστικό:"
@@ -10805,7 +11014,7 @@ msgstr "ΣÏνδεση κόμβων"
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
-msgstr "Η δεσμή ενεÏγειών έχει ήδη συνάÏτηση '%s'"
+msgstr "Η δέσμη ενεÏγειών έχει ήδη συνάÏτηση «%s»"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Input Value"
@@ -10882,10 +11091,6 @@ msgid "Cut Nodes"
msgstr "Αποκοπή κόμβων"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Επικόλληση κόμβων"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Μέλη"
@@ -10928,11 +11133,11 @@ msgstr ": ΆκυÏοι παÏάμετÏοι: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
-msgstr "Το VariableGet δεν βÏέθηκε στη δεσμή ενεÏγειών: "
+msgstr "Το VariableGet δεν βÏέθηκε στη δέσμη ενεÏγειών: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableSet not found in script: "
-msgstr "Το VariableSet δεν βÏέθηκε στη δεσμή ενεÏγειών: "
+msgstr "Το VariableSet δεν βÏέθηκε στη δέσμη ενεÏγειών: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
@@ -11177,8 +11382,8 @@ msgid ""
"scenes). The first created one will work, while the rest will be ignored."
msgstr ""
"Μόνο ένα οÏατό CanvasModulate επιτÏέπεται σε κάθε σκηνή (ή σÏνολο "
-"στιγμιότυπων σκηνών). Το Ï€Ïώτο που δημιουÏγήθηκε θα δουλέψει, ενώ τα άλλα θα "
-"αγνοηθοÏν."
+"κλωνοποιημένων σκηνών). Το Ï€Ïώτο που δημιουÏγήθηκε θα δουλέψει, ενώ τα άλλα "
+"θα αγνοηθοÏν."
#: scene/2d/collision_object_2d.cpp
#, fuzzy
@@ -11597,7 +11802,7 @@ msgstr ""
msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
msgstr ""
-"Μόνο ένα WorldEnvironment επιτÏέπεται σε κάθε σκηνή (ή σÏνολο στιγμιοτÏπων "
+"Μόνο ένα WorldEnvironment επιτÏέπεται σε κάθε σκηνή (ή σÏνολο κλωνοποιημένων "
"σκηνών)."
#: scene/3d/world_environment.cpp
@@ -11748,27 +11953,11 @@ msgid ""
"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
"texture to some node for display."
msgstr ""
-"Το Viewport δεν έχει οÏισθεί ως «render target». Αν σκοπεÏετε να δείχνει τα "
+"Το Viewport δεν έχει οÏισθεί ως στόχος απόδοσης. Αν σκοπεÏετε να δείχνει τα "
"πεÏιεχόμενα του, κάντε το να κληÏονομεί ένα Control, ώστε να αποκτήσει "
"μέγεθος. Αλλιώς, κάντε το ένα RenderTarget και οÏίστε το internal texture σε "
"έναν κόμβο για απεικόνιση."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Σφάλμα κατά την αÏχικοποίηση του FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Άγνωστη μοÏφή γÏαμματοσειÏάς."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Σφάλμα κατά την φόÏτωση της γÏαμματοσειÏάς."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Μη έγκυÏο μέγεθος γÏαμματοσειÏάς."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Είσοδος"
@@ -11783,6 +11972,11 @@ msgstr "Μη έγκυÏη πηγή!"
msgid "Invalid source for shader."
msgstr "Μη έγκυÏη πηγή!"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Μη έγκυÏη πηγή!"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11799,6 +11993,131 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No Matches"
+#~ msgstr "Δεν υπάÏχουν αντιστοιχίες"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "ΑδÏνατο το άνοιγμα του αÏχείου file_type_cache.cch για εγγÏαφή, παÏάλειψη "
+#~ "αποθήκευσης cache Ï„Ïπου αÏχείου!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Δεν ήταν δυνατή η πλοήγηση στο '%s', καθώς δεν βÏέθηκε στο σÏστημα "
+#~ "αÏχείων!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Σφάλμα κατά την φόÏτωση εικόνας:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Δεν υπάÏχουν εικονοστοιχεία με διαφάνεια >128 στην εικόνα..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Ο γονέας δεν έχει συμπαγείς επιφάνειες για να συμπληÏωθοÏν."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Δεν ήταν δυνατή η χαÏτογÏάφηση της πεÏιοχής."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Οι επιφάνειες έχουν μηδενικό εμβαδόν!"
+
+#~ msgid "No faces!"
+#~ msgstr "Δεν υπάÏχουν επιφάνειες!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Σφάλμα φόÏτωσης αÏχείου."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Σφάλμα φόÏτωσης αÏχείου."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Φαινόμενο ÎτόπλεÏ"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Επιλογή λειτουÏγίας (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "ΛειτουÏγία μετακίνησης (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "ΛειτουÏγία πεÏιστÏοφής (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "ΛειτουÏγία κλιμάκωσης (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Τοπικές συντεταγμένες"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "ΛειτουÏγία κουμπώματος (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "ΕÏγαλείο επιλογής"
+
+#~ msgid "Tool Move"
+#~ msgstr "ΕÏγαλείο μετακίνησης"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "ΕÏγαλείο πεÏιστÏοφής"
+
+#~ msgid "Tool Scale"
+#~ msgstr "ΕÏγαλείο κλιμάκωσης"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "ΑφαίÏεση όλων των απόντων έÏγων από την λίστα; (Τα πεÏιεχόμενα το φακέλου "
+#~ "δεν θα Ï„ÏοποποιηθοÏν)"
+
+#~ msgid "Project List"
+#~ msgstr "Λίστα έÏγων"
+
+#~ msgid "Exit"
+#~ msgstr "Έξοδος"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Δεν ήταν δυνατή η εκτέλεση του εÏγαλείου PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "Δεν ήταν δυνατή η επαναφόÏτωση της εικόνας που έχει μετατÏαπεί με το "
+#~ "εÏγαλείο PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Σφάλμα κατά την αÏχικοποίηση του FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Άγνωστη μοÏφή γÏαμματοσειÏάς."
+
+#~ msgid "Error loading font."
+#~ msgstr "Σφάλμα κατά την φόÏτωση της γÏαμματοσειÏάς."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Μη έγκυÏο μέγεθος γÏαμματοσειÏάς."
+
+#~ msgid "Previous Folder"
+#~ msgstr "ΠÏοηγοÏμενος φάκελος"
+
+#~ msgid "Next Folder"
+#~ msgstr "Επόμενος φάκελος"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Αυτόματο Άνοιγμα ΣτιγμιοτÏπων Οθόνης"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Άνοιγμα σε εξωτεÏικό επεξεÏγαστή εικόνων."
+
+#~ msgid "Reverse"
+#~ msgstr "ΑντιστÏοφή"
+
+#~ msgid "Mirror X"
+#~ msgstr "ΣυμμετÏία στον άξονα Χ"
+
+#~ msgid "Mirror Y"
+#~ msgstr "ΣυμμετÏία στον άξονα Î¥"
+
#~ msgid "Generating solution..."
#~ msgstr "Επίλυση..."
@@ -12549,9 +12868,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "ΔιαγÏαφή επιλογής"
-#~ msgid "Could not find tile:"
-#~ msgstr "Δεν ήταν δυνατή η εÏÏεση πλακιδίου:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Όνομα στοιχείου ή αναγνωÏιστικοÏ:"
@@ -12814,9 +13130,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "ΠληÏοφοÏίες"
-#~ msgid "Re-Import..."
-#~ msgstr "Εκ νέου εισαγωγή..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Δεν υπάÏχουν μάσκες bit για εισαγωγή!"
@@ -13205,9 +13518,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "ΣτεÏεοφωνικό"
-#~ msgid "Window"
-#~ msgstr "ΠαÏάθυÏο"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Κλιμάκωση to %s%%."
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 2289770903..7434ca1246 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -4,18 +4,19 @@
# This file is distributed under the same license as the Godot source code.
# Scott Starkey <yekrats@gmail.com>, 2019.
# AlexHoratio <yukithetupper@gmail.com>, 2019.
+# Teashrock <kajitsu22@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-07-02 10:48+0000\n"
-"Last-Translator: AlexHoratio <yukithetupper@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:34+0000\n"
+"Last-Translator: Teashrock <kajitsu22@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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -57,7 +58,6 @@ msgid "On call to '%s':"
msgstr "En voko al '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Libera"
@@ -126,6 +126,31 @@ msgid "Anim Change Call"
msgstr "Animado Aliigi Alvokon"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animado Aliigi Kernakadron Fojon"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animado Aliigi Transiron"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animado Aliigi Transformon"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animado Aliigi Kernakadron Valoron"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animado Aliigi Alvokon"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Aliigi Animadon Longecon"
@@ -443,12 +468,11 @@ 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 ""
+msgstr "Elektaro ĉiuj"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Nur Elektaro"
+msgstr "Elektaro nur"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -625,16 +649,18 @@ msgid "Line Number:"
msgstr "Lineo-Numeron:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "AnstataÅ­igis %d apero(j)n."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Ne Rezultoj"
+#, fuzzy
+msgid "%d match."
+msgstr "Trovis %d matĉo(j)n."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "AnstataÅ­igis %d apero(j)n."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Trovis %d matĉo(j)n."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -687,21 +713,24 @@ msgstr "Lineoj kaj kolumnoj numeroj."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr ""
+msgstr "Metodo en celo nodo devas esti specifita."
#: editor/connections_dialog.cpp
+#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
+"Celo metodo maltrovita. Indiku ekzistanta metodo aÅ­ ligu la skripto al celo "
+"nodo."
#: editor/connections_dialog.cpp
msgid "Connect to Node:"
-msgstr ""
+msgstr "Konektu al nodo:"
#: editor/connections_dialog.cpp
msgid "Connect to Script:"
-msgstr ""
+msgstr "Konektu al skripto:"
#: editor/connections_dialog.cpp
msgid "From Signal:"
@@ -709,13 +738,13 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "La sceno ne enhavas ajnan skriptojn."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
msgid "Add"
-msgstr ""
+msgstr "Aldonu"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
@@ -726,15 +755,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
-msgstr ""
+msgstr "Forigu"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr ""
+msgstr "Aldonu alvoko argumento:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr ""
+msgstr "Aldona argumentoj de alvoko:"
#: editor/connections_dialog.cpp
msgid "Advanced"
@@ -742,7 +771,7 @@ msgstr "Altnivela"
#: editor/connections_dialog.cpp
msgid "Deferred"
-msgstr ""
+msgstr "Diferita"
#: editor/connections_dialog.cpp
msgid ""
@@ -751,15 +780,15 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr ""
+msgstr "Unu pafo"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr ""
+msgstr "Malkonektas la signalo post Äia unua emisio."
#: editor/connections_dialog.cpp
msgid "Cannot connect signal"
-msgstr ""
+msgstr "Ne povas konekti signalo"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -773,27 +802,27 @@ msgstr ""
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr ""
+msgstr "FermiÄu"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr ""
+msgstr "Konektu"
#: editor/connections_dialog.cpp
msgid "Signal:"
-msgstr ""
+msgstr "Signalo:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr ""
+msgstr "Konektu '%s' al '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
-msgstr ""
+msgstr "Malkonektu '%s' de '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect all from signal: '%s'"
-msgstr ""
+msgstr "Malkonektu ĉiuj de signalo: '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -802,11 +831,11 @@ msgstr ""
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Disconnect"
-msgstr ""
+msgstr "Malkonektu"
#: editor/connections_dialog.cpp
msgid "Connect a Signal to a Method"
-msgstr ""
+msgstr "Konektu la signalo al metodo"
#: editor/connections_dialog.cpp
msgid "Edit Connection:"
@@ -818,7 +847,7 @@ msgstr ""
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr ""
+msgstr "Signaloj"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
@@ -826,56 +855,55 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Disconnect All"
-msgstr ""
+msgstr "Malkonektu ĉiuj"
#: editor/connections_dialog.cpp
msgid "Edit..."
-msgstr ""
+msgstr "Redaktu..."
#: editor/connections_dialog.cpp
msgid "Go To Method"
-msgstr ""
+msgstr "Iru al metodo"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr ""
+msgstr "ÅœanÄu la tipon de %s"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
-msgstr ""
+msgstr "ÅœanÄu"
#: editor/create_dialog.cpp
msgid "Create New %s"
-msgstr ""
+msgstr "Kreu novan %s"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
#: editor/filesystem_dock.cpp
msgid "Favorites:"
-msgstr ""
+msgstr "Favoritaj:"
#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
-msgstr ""
+msgstr "Serĉo:"
#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Matches:"
-msgstr ""
+msgstr "Matĉoj:"
#: editor/create_dialog.cpp editor/plugin_config_dialog.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Description:"
-msgstr ""
+msgstr "Priskribo:"
#: editor/dependency_editor.cpp
msgid "Search Replacement For:"
@@ -900,20 +928,20 @@ msgstr ""
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Dependencies"
-msgstr ""
+msgstr "Dependecoj"
#: editor/dependency_editor.cpp
msgid "Resource"
-msgstr ""
+msgstr "Rimedo"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_settings_editor.cpp editor/script_create_dialog.cpp
msgid "Path"
-msgstr ""
+msgstr "Pado"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
-msgstr ""
+msgstr "Dependecoj:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
@@ -952,7 +980,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -988,7 +1016,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1077,14 +1105,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1101,7 +1129,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1118,7 +1146,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1585,12 +1612,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1651,7 +1677,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1702,7 +1728,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1727,23 +1753,29 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Iri al AntaÅ­a PaÅo"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Iri al Neksta PaÅo"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1976,6 +2008,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2272,6 +2308,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2365,6 +2409,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2418,6 +2466,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Duplikati"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2445,20 +2498,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2491,24 +2540,33 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Redaktu..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2588,12 +2646,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2609,14 +2667,6 @@ 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 ""
@@ -2637,14 +2687,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2652,12 +2702,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2930,6 +2981,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3091,7 +3146,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3108,6 +3163,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3169,12 +3228,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3188,13 +3245,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3279,19 +3340,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3324,11 +3377,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3387,6 +3440,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3450,6 +3507,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Krei"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3510,6 +3572,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3517,12 +3587,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3535,11 +3613,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3746,7 +3824,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4488,10 +4566,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4504,14 +4578,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tempo:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4552,6 +4655,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4580,13 +4687,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4594,7 +4703,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4607,7 +4716,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4619,6 +4728,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4669,31 +4782,33 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Forigi Nevalidajn Åœlosilojn"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Forigi Nevalidajn Åœlosilojn"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4773,6 +4888,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4801,6 +4920,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4821,14 +4941,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4852,6 +4975,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4868,11 +4992,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4885,6 +5004,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5092,16 +5216,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5412,14 +5526,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5503,19 +5609,24 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "La sceno ne enhavas ajnan skriptojn."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5842,7 +5953,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5948,11 +6058,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5976,7 +6082,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6057,6 +6163,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6094,11 +6204,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6186,6 +6296,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6252,6 +6366,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6286,92 +6401,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skali Elektaron"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6549,7 +6669,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6605,7 +6729,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6659,7 +6783,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6670,27 +6794,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6734,26 +6838,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6808,7 +6892,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7101,10 +7185,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7189,11 +7269,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7298,14 +7378,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7319,8 +7391,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7599,6 +7671,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7675,6 +7751,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7695,6 +7776,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7767,6 +7852,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7774,10 +7875,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7866,7 +8001,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7874,7 +8009,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7886,7 +8021,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7903,7 +8038,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7972,11 +8107,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7992,7 +8127,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8003,7 +8138,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8012,7 +8147,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8020,11 +8155,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8064,11 +8199,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8077,7 +8216,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8095,15 +8234,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8152,7 +8291,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8167,6 +8306,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8180,19 +8323,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8201,7 +8344,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8210,14 +8353,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8262,47 +8405,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8469,6 +8619,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8615,6 +8769,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8684,8 +8846,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8705,7 +8867,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8729,10 +8891,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9066,6 +9224,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9118,14 +9280,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9411,6 +9565,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9453,6 +9611,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9524,19 +9686,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9627,6 +9789,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9655,7 +9821,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9815,6 +9981,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10225,10 +10395,27 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Kreu novan %s"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10413,10 +10600,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11146,22 +11329,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Nekonata tipara formo."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Eraro dum Åargante tiparon."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Nevalida tipara grando."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Enigo"
@@ -11175,6 +11342,11 @@ msgstr "Nevalida fonto por ombrigilo."
msgid "Invalid source for shader."
msgstr "Nevalida fonto por ombrigilo."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Nevalida fonto por ombrigilo."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11190,3 +11362,15 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#~ msgid "No Matches"
+#~ msgstr "Ne Rezultoj"
+
+#~ msgid "Unknown font format."
+#~ msgstr "Nekonata tipara formo."
+
+#~ msgid "Error loading font."
+#~ msgstr "Eraro dum Åargante tiparon."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Nevalida tipara grando."
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 10f46b198c..08a6012cc2 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -44,7 +44,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:47+0000\n"
+"PO-Revision-Date: 2019-08-22 17:23+0000\n"
"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
@@ -53,19 +53,19 @@ 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.8-dev\n"
+"X-Generator: Weblate 3.9-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 "El argumento para convert() no es correcto, utiliza constantes TYPE_*."
+msgstr "El argumento para convert() es invalido, utiliza constantes TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr ""
-"No hay suficientes bytes para decodificar bytes, o el formato no es válido."
+"No hay suficientes bytes para decodificar bytes, o el formato es invalido."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -96,7 +96,6 @@ msgid "On call to '%s':"
msgstr "En llamada a '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Libre"
@@ -165,6 +164,26 @@ msgid "Anim Change Call"
msgstr "Cambiar Llamada de Animación"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Cambiar Tiempo de Múltiples Keyframes de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Cambiar Múltiples Transiciones de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Cambiar Múltiples Transforms de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Cambiar Valor de Múltiples Keyframes de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Cambiar Múltiples Llamadas de Animación"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Cambiar Duración de la Animación"
@@ -439,7 +458,7 @@ msgstr "Método no encontrado en el objeto: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
-msgstr "Mover Claves de Anim"
+msgstr "Mover Claves de Animación"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
@@ -670,16 +689,18 @@ msgid "Line Number:"
msgstr "Número de Línea:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d ocurrencia(s) reemplazada(s)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Sin Coincidencias"
+#, fuzzy
+msgid "%d match."
+msgstr "Se encontraron %d coincidencias."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d ocurrencia(s) reemplazada(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Se encontraron %d coincidencias."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -829,9 +850,8 @@ msgid "Connect"
msgstr "Conectar"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Señales:"
+msgstr "Señal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -909,8 +929,7 @@ msgstr "Favoritos:"
msgid "Recent:"
msgstr "Recientes:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -998,9 +1017,9 @@ msgid "Owners Of:"
msgstr "Propietarios De:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "¿Eliminar los archivos seleccionados del proyecto? (irreversible)"
+msgstr ""
+"¿Eliminar los archivos seleccionados del proyecto? (No puede ser restaurado)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1012,7 +1031,7 @@ msgstr ""
"funcionar.\n"
"¿Eliminarlos de todos modos? (irreversible)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "No se puede eliminar:"
@@ -1048,7 +1067,7 @@ msgstr "¿Eliminar permanentemente %d ítem(s)? (¡No se puede deshacer!)"
msgid "Show Dependencies"
msgstr "Mostrar Dependencias"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorador de Recursos Huérfanos"
@@ -1137,14 +1156,16 @@ msgid "License"
msgstr "Licencia"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licencia de Terceros"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine se basa en una serie de bibliotecas libres y de código abierto "
@@ -1165,7 +1186,8 @@ msgid "Licenses"
msgstr "Licencias"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Error al abrir el archivo empaquetado, no tiene formato zip."
#: editor/editor_asset_installer.cpp
@@ -1182,7 +1204,6 @@ msgid "Success!"
msgstr "¡Éxito!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalar"
@@ -1553,6 +1574,7 @@ 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 ""
+"En la exportación de 32 bits el PCK embebido no puede ser mayor de 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1662,12 +1684,11 @@ msgid "New"
msgstr "Nuevo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importar"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportar"
@@ -1728,7 +1749,7 @@ msgstr "Mostrar en Explorador de Archivos"
msgid "New Folder..."
msgstr "Nueva Carpeta..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Recargar"
@@ -1779,7 +1800,7 @@ msgstr "Avanzar"
msgid "Go Up"
msgstr "Subir"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Act./Desact. Archivos Ocultos"
@@ -1804,24 +1825,28 @@ msgid "Move Favorite Down"
msgstr "Bajar Favorito"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Carpeta Anterior"
+msgid "Go to previous folder."
+msgstr "Ir a la carpeta anterior."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Carpeta Siguiente"
+msgid "Go to next folder."
+msgstr "Ir a la carpeta siguiente."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Ir a la carpeta padre."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Refrescar archivos."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Eliminar carpeta actual de favoritos."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
-msgstr "Ver/Ocultar archivos ocultos."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "Mostrar/Ocultar archivos ocultos."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -2065,6 +2090,11 @@ msgstr "Limpiar"
msgid "Clear Output"
msgstr "Limpiar Salida"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Ventana"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "La exportación del proyecto falló con el código de error %d."
@@ -2390,6 +2420,15 @@ msgid "Pick a Main Scene"
msgstr "Selecciona una Escena Principal"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Cerrar Escena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Cerrar Escena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"No se pudo activar el plugin addon: Ha fallado el análisis de la "
@@ -2509,6 +2548,11 @@ msgstr "Reproducir Esta Escena"
msgid "Close Tab"
msgstr "Cerrar Pestaña"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Cerrar Pestaña"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Cerrar Otras Pestañas"
@@ -2562,6 +2606,10 @@ msgid "Go to previously opened scene."
msgstr "Ir a la escena abierta previamente."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar Texto"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Pestaña siguiente"
@@ -2589,6 +2637,10 @@ msgstr "Nueva Escena Heredada..."
msgid "Open Scene..."
msgstr "Abrir Escena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Abrir Reciente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Guardar Escena"
@@ -2598,14 +2650,6 @@ msgid "Save All Scenes"
msgstr "Guardar Todas las Escenas"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Cerrar Escena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Abrir Reciente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Convertir a..."
@@ -2635,25 +2679,36 @@ msgstr "Revertir Escena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Herramientas variadas de proyecto o escena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Proyecto"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Ajustes del proyecto"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Herramientas"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Exportar…"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Instalar plantilla de compilación de Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Abrir Carpeta de Datos del Proyecto"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Herramientas"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Instalar plantilla de compilación de Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorador de Recursos Huérfanos"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2751,12 +2806,13 @@ msgstr ""
"Cuando se use remotamente en un dispositivo, esto es mas eficiente con un "
"sistema de archivos de red."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Configuración del Editor"
#: editor/editor_node.cpp
@@ -2774,14 +2830,6 @@ msgstr ""
"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 "Cambiar a Pantalla Completa"
@@ -2802,14 +2850,16 @@ msgid "Open Editor Settings Folder"
msgstr "Abrir Carpeta de Configuración del Editor"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Administrar Características del Editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Administrar Plantillas de Exportación"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ayuda"
@@ -2817,12 +2867,13 @@ msgstr "Ayuda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Buscar"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentación Online"
@@ -3102,6 +3153,10 @@ msgstr "Tiempo"
msgid "Calls"
msgstr "Llamadas"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Editar Texto:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Activado"
@@ -3275,7 +3330,8 @@ msgid "Import From Node:"
msgstr "Importar Desde Nodo:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Volver a Descargar"
#: editor/export_template_manager.cpp
@@ -3292,6 +3348,10 @@ msgid "Download"
msgstr "Descargar"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(No encontrado)"
@@ -3355,12 +3415,10 @@ msgid "No response."
msgstr "No responde."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Petición Fallida."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Redireccionar Loop."
@@ -3374,15 +3432,22 @@ msgid "Download Complete."
msgstr "Descarga Completada."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "No se pudo guardar el tema a un archivo:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Fallo la instalación de plantillas. Las plantillas problemáticas pueden ser "
"encontradas en '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Error al solicitar url: "
#: editor/export_template_manager.cpp
@@ -3468,23 +3533,11 @@ msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
"Seleccionar un mirror de la lista: (Shift + Clic: Abrir en el Navegador)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"No se puede abrir file_type_cache.cch para escribir, no se guardará el cache "
-"de tipos de archivo!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoritos"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"¡No se puede navegar a '%s' ya que no se ha encontrado en el sistema de "
-"archivos!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Estado: No se pudo importar el archivo. Por favor, arregla el archivo y "
@@ -3519,14 +3572,14 @@ msgid "Provided name contains invalid characters."
msgstr "El nombre contiene caracteres inválidos."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "El nombre contiene caracteres inválidos."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Ya existe un archivo o carpeta con este nombre."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "El nombre contiene caracteres inválidos."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Renombrar archivo:"
@@ -3582,6 +3635,11 @@ msgstr "Duplicar..."
msgid "Move To..."
msgstr "Mover a..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nueva Escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nuevo Script..."
@@ -3647,6 +3705,11 @@ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación."
msgid "Overwrite"
msgstr "Sobreescribir"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Crear desde escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Crear Script"
@@ -3709,6 +3772,14 @@ msgid "Search complete"
msgstr "Búsqueda completa"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Añadir al Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Eliminar del Grupo"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "El nombre del grupo ya existe."
@@ -3716,12 +3787,23 @@ msgstr "El nombre del grupo ya existe."
msgid "Invalid group name."
msgstr "Nombre de grupo inválido."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Administrar Grupos"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Eliminar grupo de imágenes"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupos"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nodos fuera del Grupo"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3734,12 +3816,12 @@ msgid "Nodes in Group"
msgstr "Nodos dentro del Grupo"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Añadir al Grupo"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Eliminar del Grupo"
+msgid "Group Editor"
+msgstr "Editor de Grupos"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3948,7 +4030,8 @@ msgid "MultiNode Set"
msgstr "Establecer multinodo"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Selecciona un nodo para editar señales y grupos."
#: editor/plugin_config_dialog.cpp
@@ -4712,10 +4795,6 @@ msgid "View Files"
msgstr "Ver Archivos"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "No se ha podido resolver el nombre de dominio:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Error de conexión, por favor inténtelo otra vez."
@@ -4728,14 +4807,47 @@ msgid "No response from host:"
msgstr "No hay respuesta desde el host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "No se ha podido resolver el nombre de dominio:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Petición fallida, código:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Petición Fallida."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "No se pudo guardar el tema a un archivo:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Petición fallida, demasiadas redirecciones"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Redireccionar Loop."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Petición fallida, código:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tiempo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Error de descarga, al parecer el archivo ha sido manipulado."
@@ -4776,6 +4888,10 @@ msgid "Idle"
msgstr "Inactivo"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instalar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Reintentar"
@@ -4804,13 +4920,17 @@ msgid "Last"
msgstr "Último"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Todos"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Reimportar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4818,8 +4938,8 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Invertir"
+msgid "Reverse sorting."
+msgstr "Orden inverso."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4831,7 +4951,8 @@ msgid "Site:"
msgstr "Sitio:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Soporte..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4843,6 +4964,11 @@ msgid "Testing"
msgstr "Prueba"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Cargar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Archivo ZIP de elementos"
@@ -4900,32 +5026,32 @@ msgid "Rotation Step:"
msgstr "Step de Rotación:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Mover guía vertical"
+msgid "Move Vertical Guide"
+msgstr "Mover Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Crear nueva guía vertical"
+msgid "Create Vertical Guide"
+msgstr "Crear Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Eliminar guía vertical"
+msgid "Remove Vertical Guide"
+msgstr "Eliminar Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Mover guía horizontal"
+msgid "Move Horizontal Guide"
+msgstr "Mover Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Crear nueva guía horizontal"
+msgid "Create Horizontal Guide"
+msgstr "Crear Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Eliminar guía horizontal"
+msgid "Remove Horizontal Guide"
+msgstr "Eliminar Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Crear nuevas guías horizontales y verticales"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Crear Guías Horizontales y Verticales"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -5008,6 +5134,11 @@ msgid "Paste Pose"
msgstr "Pegar Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Limpiar Huesos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Crear Hueso(s) Personalizado(s) a partir de Nodo(s)"
@@ -5038,6 +5169,7 @@ msgid "Zoom Reset"
msgstr "Resetear el Zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Modo de Selección"
@@ -5060,14 +5192,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + Clic Derecho: Selección en listado de solapamientos"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Modo Movimiento"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Modo Rotación"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Modo Escalado"
@@ -5094,6 +5229,7 @@ msgid "Toggle snapping."
msgstr "Act./Desact. alineado."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Usar Snap"
@@ -5110,11 +5246,6 @@ msgid "Use Rotation Snap"
msgstr "Usar Snap de Rotación"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurar Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relativo"
@@ -5127,6 +5258,11 @@ msgid "Smart Snapping"
msgstr "Ajuste Inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Ajustar al Padre"
@@ -5341,16 +5477,6 @@ msgstr "Establecer Handle"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Error al cargar la imagen:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-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"
@@ -5662,14 +5788,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "El origen de la superficie no es correcto (sin caras)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "La superficie padre no tiene caras solidas para poblar."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "No se pudo mapear el área."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selecciona una Mesh de Origen:"
@@ -5754,20 +5872,27 @@ msgid "Generation Time (sec):"
msgstr "Tiempo de Generación (seg):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "¡Las caras no contienen área!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "El nodo no posee geometría (caras)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "¡Sin caras!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "El nodo no tiene geometría."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "El nodo no posee geometría (caras)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "El nodo no tiene geometría."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6101,7 +6226,6 @@ msgid "Grid Settings"
msgstr "Configuración del Grid"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Snap"
@@ -6207,12 +6331,9 @@ msgid "Error writing TextFile:"
msgstr "Error al escribir el TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Error: no se pudo cargar el archivo."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Error no se pudo cargar el archivo."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "No se pudo cargar el tile:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6235,7 +6356,8 @@ msgid "Error Importing"
msgstr "Error al Importar"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nuevo TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6316,6 +6438,11 @@ msgid "Open..."
msgstr "Abrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Abrir Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Guardar Todo"
@@ -6353,13 +6480,13 @@ msgid "Save Theme"
msgstr "Guardar Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Cerrar Documentación"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Cerrar Todo"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Cerrar Documentación"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Ejecutar"
@@ -6447,6 +6574,11 @@ msgstr "Depurador"
msgid "Search Results"
msgstr "Resultados de la Búsqueda"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Limpiar escenas recientes"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Conexiones al método:"
@@ -6515,8 +6647,9 @@ msgid "Syntax Highlighter"
msgstr "Resaltador de Sintaxis"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Ir A"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6524,9 +6657,8 @@ msgid "Bookmarks"
msgstr "Marcadores"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Crear puntos."
+msgstr "Puntos de interrupción"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6550,22 +6682,6 @@ msgid "Toggle Comment"
msgstr "Act./Desact. Comentario"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Act./Desact. Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Ir al Siguiente Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Ir al Marcador Anterior"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Eliminar Todos los Marcadores"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Plegar/Desplegar Línea"
@@ -6586,6 +6702,11 @@ msgid "Complete Symbol"
msgstr "Completar Símbolo"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Escalar Selección"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Eliminar Espacios Sobrantes al Final"
@@ -6602,29 +6723,32 @@ msgid "Auto Indent"
msgstr "Autoindentar"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Act./Desact. Breakpoint"
+msgid "Find Previous"
+msgstr "Buscar Anterior"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Eliminar Todos los Breakpoints"
+msgid "Find in Files..."
+msgstr "Buscar en Archivos..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Ir al Siguente Breakpoint"
+msgid "Contextual Help"
+msgstr "Ayuda Contextual"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Ir al Breakpoint Anterior"
+msgid "Toggle Bookmark"
+msgstr "Act./Desact. Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Buscar Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Ir al Siguiente Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Buscar en Archivos..."
+msgid "Go to Previous Bookmark"
+msgstr "Ir al Marcador Anterior"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Eliminar Todos los Marcadores"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6635,8 +6759,21 @@ msgid "Go to Line..."
msgstr "Ir a Línea..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Ayuda Contextual"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Act./Desact. Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Eliminar Todos los Breakpoints"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Ir al Siguente Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Ir al Breakpoint Anterior"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6815,8 +6952,12 @@ msgid "Rear"
msgstr "Detrás"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Alinear con Vista"
+msgid "Align Transform with View"
+msgstr "Alinear Transform con Vista"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Alinear Rotación con Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6871,8 +7012,9 @@ msgid "Audio Listener"
msgstr "Oyente de Audio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Activar Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Habilitar Filtrado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6927,8 +7069,8 @@ msgid "Snap Nodes To Floor"
msgstr "Ajustar Nodos al Suelo"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Modo de Selección (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6941,30 +7083,11 @@ msgstr ""
"Alt + Clic Derecho: Selección en la lista de superposición"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Modo Movimiento (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Modo Rotación (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Modo Escalado (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordenadas Locales"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Modo de Espacio Local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Modo de Snap (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vista Inferior"
@@ -7005,26 +7128,6 @@ msgid "Focus Selection"
msgstr "Foco en Selección"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Alinear Selección Con Vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Seleccionar Herramienta"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Herramienta Mover"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Herramienta Rotar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Herramienta Escalar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Act./Desact. Vista Libre"
@@ -7079,7 +7182,8 @@ msgstr "Ver Grid"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Configuración"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7372,10 +7476,6 @@ msgid "TextureRegion"
msgstr "Región de Textura"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-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"
@@ -7460,11 +7560,13 @@ msgid "Submenu"
msgstr "Submenú"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Ãtem 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Ãtem 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7569,14 +7671,6 @@ msgid "Transpose"
msgstr "Transponer"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Voltear X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Voltear Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Desactivar Autotile"
@@ -7589,9 +7683,10 @@ msgid "Paint Tile"
msgstr "Dibujar tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift + Clic derecho: Trazar línea\n"
"Shift + Ctrl + Clic derecho: Pintar Rectángulo"
@@ -7889,6 +7984,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Sólo GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Añadir entrada +"
@@ -7965,6 +8064,11 @@ msgid "Duplicate Nodes"
msgstr "Duplicar Nodos"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Pegar Nodos"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Eliminar Nodos"
@@ -7985,6 +8089,11 @@ msgid "Light"
msgstr "Luz"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Crear Nodo Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Crear Nodo Shader"
@@ -8057,6 +8166,23 @@ msgid "Color uniform."
msgstr "Color uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+"Devuelve el resultado booleano de la comparación de %s entre dos parámetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Igual (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Mayor Que (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Mayor o Igual Que (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8066,12 +8192,52 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre INF y un parámetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre NaN y un parámetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Menor Que (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Menor o Igual Que (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Diferente (!=)"
+
+#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Devuelve el resultado booleano de la comparación entre dos parámetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre INF (o NaN) y un "
+"parámetro escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Constante booleana."
@@ -8160,16 +8326,16 @@ msgid "Returns the arc-cosine of the parameter."
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 "(Sólo GLES3) Devuelve el coseno hiperbólico inverso del parámetro."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "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 "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 "(Sólo GLES3) Devuelve el seno hiperbólico inverso del parámetro."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Devuelve el seno hiperbólico inverso del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8180,8 +8346,8 @@ msgid "Returns the arc-tangent of the parameters."
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 "(Sólo GLES3) Devuelve la tangente hiperbólica inversa del parámetro."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Devuelve la tangente hiperbólica inversa del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8197,8 +8363,8 @@ msgid "Returns the cosine of the parameter."
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 "(Sólo GLES3) Devuelve el coseno hiperbólico del parámetro."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Devuelve el coseno hiperbólico del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8267,12 +8433,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Sólo GLES3) Encuentra el entero más cercano al parámetro."
+msgid "Finds the nearest integer to the parameter."
+msgstr "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 "(Sólo GLES3) Encuentra el entero más cercano al parámetro."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "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."
@@ -8287,18 +8453,19 @@ msgid "Returns the sine of the parameter."
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 "(Sólo GLES3) Devuelve el seno hiperbólico del parámetro."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Devuelve el seno hiperbólico del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Devuelve la raíz cuadrada del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8309,10 +8476,11 @@ msgstr ""
"polinomios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
@@ -8323,12 +8491,12 @@ msgid "Returns the tangent of the parameter."
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 "(Sólo GLES3) Devuelve la tangente hiperbólica del parámetro."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "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 "(Sólo GLES3) Encuentra el valor truncado del parámetro."
+msgid "Finds the truncated value of the parameter."
+msgstr "Encuentra el valor truncado del parámetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8367,12 +8535,16 @@ msgid "Perform the texture lookup."
msgstr "Realiza una búsqueda de texturas."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Textura cúbica uniforme."
+msgid "Cubic texture uniform lookup."
+msgstr "Búsqueda de textura cúbica uniforme."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr "Búsqueda de textura uniforme 2D."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "Textura 2D uniforme."
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Búsqueda de textura uniforme 2D con triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8380,7 +8552,7 @@ msgstr "Función Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8388,7 +8560,7 @@ 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"
+"Calcular 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 "
@@ -8405,16 +8577,16 @@ msgid "Decomposes transform to four vectors."
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 "(Sólo GLES3) Calcula el determinante de una transformación."
+msgid "Calculates the determinant of a transform."
+msgstr "Calcula el determinante de una transformación."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(Sólo GLES3) Calcula el inverso de una transformación."
+msgid "Calculates the inverse of a transform."
+msgstr "Calcula el inverso de una transformación."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(Sólo GLES3) Calcula la transposición de una transformación."
+msgid "Calculates the transpose of a transform."
+msgstr "Calcula la transposición de una transformación."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8462,16 +8634,16 @@ msgstr "Calcula el producto punto de dos vectores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
-"Devuelve un vector que apunta en la misma dirección que un vector de "
+"Devuelve el 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."
+"producto de 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."
@@ -8482,6 +8654,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Interpolación lineal entre dos vectores."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolación lineal entre dos vectores."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Calcula el producto normalizado del vector."
@@ -8495,21 +8672,22 @@ msgstr "1.0 / vector"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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 "
+"Devuelve el vector que apunta en la dirección de 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 "Devuelve un vector que apunta en dirección a su refracción."
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Devuelve el vector que apunta en la dirección de refracción."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8520,10 +8698,11 @@ msgstr ""
"polinomios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8534,20 +8713,22 @@ msgstr ""
"polinomios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
@@ -8602,61 +8783,65 @@ msgstr ""
"esta)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
-msgstr "(Sólo GLES3) (Sólo modo Fragmento/Luz) Función de derivación escalar."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(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."
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(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."
+"(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."
+"(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."
+"(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 "
+"(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."
+"(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."
+"(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."
+"(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 "
+"(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'."
+"(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'."
+"(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'."
+"(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'."
+"(Sólo modo Fragmento/Luz) (Escalar) Suma del derivado absoluto en 'x' e 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8832,6 +9017,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Faltan plantillas de exportación para esta plataforma:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Administrar Plantillas de Exportación"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exportar con depuración"
@@ -8991,6 +9180,15 @@ msgid "Unnamed Project"
msgstr "Proyecto Sin Nombre"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importar Proyecto Existente"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "No se puede abrir el proyecto en '%s'."
@@ -9087,12 +9285,13 @@ msgstr ""
"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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"¿Eliminar todos los proyectos faltantes de la lista? (El contenido de las "
-"carpetas no se modificará)"
+"¿Eliminar %d proyectos de la lista?\n"
+"El contenido de las carpetas del proyecto no se modificará."
#: editor/project_manager.cpp
msgid ""
@@ -9117,8 +9316,9 @@ msgid "Project Manager"
msgstr "Administrador de Proyectos"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Listado de Proyectos"
+#, fuzzy
+msgid "Projects"
+msgstr "Proyecto"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9141,10 +9341,6 @@ msgid "Templates"
msgstr "Plantillas"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Salir"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Reiniciar Ahora"
@@ -9484,6 +9680,10 @@ msgstr "Idiomas:"
msgid "AutoLoad"
msgstr "AutoLoad"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Cero"
@@ -9536,15 +9736,6 @@ msgstr "Seleccionar Método Virtual"
msgid "Select Method"
msgstr "Seleccionar Método"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "No se pudo ejecutar la herramienta PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"No se pudo volver a cargar la imagen convertida usando la herramienta PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Renombrar por lote"
@@ -9840,6 +10031,11 @@ msgid "Remove Node(s)"
msgstr "Eliminar Nodo(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Cambiar nombre del puerto de salida"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9884,6 +10080,10 @@ msgid "Extend Script"
msgstr "Extender Script"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Reemparentar a Nuevo Nodo"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Convertir en Raíz de Escena"
@@ -9956,24 +10156,27 @@ msgid "Node configuration warning:"
msgstr "Alerta de configuración de nodos:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"El nodo tiene conexión/es y grupo/s.\n"
"Clic para mostrar el panel de señales."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"El nodo tiene conexiones.\n"
"Haz clic para mostrar el panel de señales."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"El nodo está en el/los grupo(s).\n"
@@ -10073,6 +10276,11 @@ msgid "Error loading script from %s"
msgstr "Error al cargar script desde %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sobreescribir"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/D"
@@ -10101,8 +10309,8 @@ msgid "Script is valid."
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 _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Permitido: a-z, A-Z, 0-9, _ y ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10166,7 +10374,7 @@ msgstr "Proceso Hijo Conectado"
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr "Error de Copia"
+msgstr "Copiar Error"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -10261,6 +10469,10 @@ msgid "Change Shortcut"
msgstr "Cambiar Atajo"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Configuración del Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Atajos"
@@ -10683,10 +10895,30 @@ msgid "Set Variable Type"
msgstr "Establecer Tipo de la Variable"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "No debe coincidir con un nombre de tipo built-in existente."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Cree un nuevo rectángulo."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variables:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Cree un nuevo rectángulo."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Crear un nuevo polígono."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "El nombre no es un identificador válido:"
@@ -10875,10 +11107,6 @@ msgid "Cut Nodes"
msgstr "Cortar Nodos"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Pegar Nodos"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Editar Miembros"
@@ -11189,13 +11417,12 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
-"Se debe crear o establecer un recurso SpriteFrames en la propiedad 'Frames' "
-"para que AnimatedSprite pueda mostrar frames."
+"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
+"\" para que AnimatedSprite pueda mostrar frames."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11259,12 +11486,12 @@ 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\" "
"property."
msgstr ""
-"Se debe asignar una textura con la forma de la luz a la propiedad 'texture'."
+"Se debe proporcionar una textura con la forma de la luz a la propiedad \" "
+"Texture\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11274,11 +11501,10 @@ msgstr ""
"tenga efecto."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+"El polígono oclusor para este oclusor está vacío. Por favor, dibuja un "
+"polígono."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11377,18 +11603,16 @@ msgstr ""
"RigidBody2D, KinematicBody2D, etc. para que puedan tener forma."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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."
+"VisibilityEnabler2D funciona mejor cuando se usa con la raíz de la escena "
+"editada directamente como padre."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera tiene que tener un nodo ARVROrigin como padre"
+msgstr "ARVRCamera tiene que tener un nodo ARVROrigin como padre."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11478,13 +11702,12 @@ 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."
msgstr ""
-"Se debe proveer de una forma a CollisionShape para que funcione. Por favor, "
-"¡crea un recurso \"shape\"!"
+"Se debe proporcionar un shape para que CollisionShape funcione. Por favor, "
+"crea un recurso de shape para ello."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11521,6 +11744,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Un SpotLight con un ángulo superior a 90 grados no puede proyectar sombras."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11567,13 +11791,12 @@ msgstr ""
"PathFollow solo funciona cuando está asignado como hijo de un nodo Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"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."
+"PathFollow's ROTATION_ORIENTED requiere que \"Up Vector\" esté activado en "
+"el recurso Curve de su Path padre."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11586,12 +11809,12 @@ msgstr ""
"En lugar de esto, cambie el tamaño en las formas de colisión hijas."
#: scene/3d/remote_transform.cpp
-#, 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."
+"La propiedad \"Remote Path\" debe apuntar a un nodo Spatial o derivado de "
+"Spatial válido para que funcione."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11608,13 +11831,12 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Se debe crear o establecer un recurso SpriteFrames en la propiedad 'Frames' "
-"para que AnimatedSprite3D pueda mostrar frames."
+"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
+"\" para que AnimatedSprite3D pueda mostrar frames."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11629,6 +11851,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment requiere que su propiedad \"Environment\" contenga un "
+"Environment para que tenga un efecto visible."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11667,9 +11891,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
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "No hay asignado ningún nodo AnimationNode raíz para el gráfico."
+msgstr "No se ha establecido ningún nodo AnimationNode raíz para el gráfico."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11682,9 +11905,8 @@ msgstr ""
"La ruta asignada al AnimationPlayer no apunta a un nodo AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "La raíz del AnimationPlayer no es un nodo válido."
+msgstr "La raíz del nodo AnimationPlayer no es un nodo válido."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11711,7 +11933,6 @@ msgid "Add current color as a preset."
msgstr "Añadir el color actual como preset."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
@@ -11719,7 +11940,7 @@ msgid ""
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' "
+"Si no tienes intención de añadir un script, utiliza un nodo de Control "
"sencillo."
#: scene/gui/control.cpp
@@ -11740,31 +11961,28 @@ msgid "Please Confirm..."
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, 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."
+"Los popups se ocultarán por defecto a menos que llames a popup() o a "
+"cualquiera de las funciones popup*(). Puedes hacerlos visibles para su "
+"edición, pero se esconderán al iniciar."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Si \"Exp Edit\" está activado, \"Min Value\" debe ser mayor que 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer está pensado para funcionar con un control hijo únicamente.\n"
-"Usa un contenedor como hijo (VBox,HBox,etc), o un Control y ajusta el tamaño "
-"mínimo manualmente."
+"ScrollContainer está pensado para funcionar con un solo control hijo.\n"
+"Utiliza un container como hijo (VBox, HBox, etc.), o un Control y establece "
+"manualmente el tamaño mínimo personalizado."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11790,35 +12008,22 @@ msgstr ""
"pueda obtener un tamaño. De lo contrario, conviértelo en un RenderTarget y "
"asigna su textura interna a algún nodo para mostrarlo."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Error al arrancar FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Formato de tipografía desconocido."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error al cargar la tipografía."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Tamaño de tipografía incorrecto."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrada"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Fuente inválida para el shader."
+msgstr "Fuente inválida para la vista previa."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Fuente inválida para el shader."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Función de comparación inválida para este tipo."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Asignación a función."
@@ -11835,6 +12040,131 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid "No Matches"
+#~ msgstr "Sin Coincidencias"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "No se puede abrir file_type_cache.cch para escribir, no se guardará el "
+#~ "cache de tipos de archivo!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "¡No se puede navegar a '%s' ya que no se ha encontrado en el sistema de "
+#~ "archivos!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Error al cargar la imagen:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "No hay píxeles con transparencia > 128 en la imagen..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "La superficie padre no tiene caras solidas para poblar."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "No se pudo mapear el área."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "¡Las caras no contienen área!"
+
+#~ msgid "No faces!"
+#~ msgstr "¡Sin caras!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Error: no se pudo cargar el archivo."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Error no se pudo cargar el archivo."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Activar Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Modo de Selección (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Modo Movimiento (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Modo Rotación (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Modo Escalado (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordenadas Locales"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Modo de Snap (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Seleccionar Herramienta"
+
+#~ msgid "Tool Move"
+#~ msgstr "Herramienta Mover"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Herramienta Rotar"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Herramienta Escalar"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "¿Eliminar todos los proyectos faltantes de la lista? (El contenido de las "
+#~ "carpetas no se modificará)"
+
+#~ msgid "Project List"
+#~ msgstr "Listado de Proyectos"
+
+#~ msgid "Exit"
+#~ msgstr "Salir"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "No se pudo ejecutar la herramienta PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "No se pudo volver a cargar la imagen convertida usando la herramienta "
+#~ "PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Error al arrancar FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Formato de tipografía desconocido."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error al cargar la tipografía."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Tamaño de tipografía incorrecto."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Carpeta Anterior"
+
+#~ msgid "Next Folder"
+#~ msgstr "Carpeta Siguiente"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Abrir Capturas de Pantalla Automáticamente"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Abrir en un editor de imágenes externo."
+
+#~ msgid "Reverse"
+#~ msgstr "Invertir"
+
+#~ msgid "Mirror X"
+#~ msgstr "Voltear X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Voltear Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Generando solución..."
@@ -12604,9 +12934,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Erase selection"
#~ msgstr "Eliminar selección"
-#~ msgid "Could not find tile:"
-#~ msgstr "No se pudo cargar el tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nombre o ID de Item:"
@@ -12885,9 +13212,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Info"
#~ msgstr "Info"
-#~ msgid "Re-Import..."
-#~ msgstr "Reimportar..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "¡Sin máscaras de bits para importar!"
@@ -13284,9 +13608,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Stereo"
#~ msgstr "Estéreo"
-#~ msgid "Window"
-#~ msgstr "Ventana"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Escalando al %s%%."
@@ -13542,9 +13863,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Add Image Group"
#~ msgstr "Añadir grupo de imágenes"
-#~ msgid "Delete Image Group"
-#~ msgstr "Eliminar grupo de imágenes"
-
#~ msgid "Project Export Settings"
#~ msgstr "Ajustes de exportación del proyecto"
@@ -13629,9 +13947,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Export Project PCK"
#~ msgstr "Exportar PCK del proyecto"
-#~ msgid "Export..."
-#~ msgstr "Exportar…"
-
#~ msgid "Project Export"
#~ msgstr "Exportar proyecto"
@@ -13729,6 +14044,3 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Deploy File Server Clients"
#~ msgstr "Hacer Deploy de Clientes del Servidor de Archivos"
-
-#~ msgid "Group Editor"
-#~ msgstr "Editor de Grupos"
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 185b50f0c6..9208cc669c 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -16,8 +16,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:47+0000\n"
-"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
+"PO-Revision-Date: 2019-08-11 10:24+0000\n"
+"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
"Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/"
"godot-engine/godot/es_AR/>\n"
"Language: es_AR\n"
@@ -68,7 +68,6 @@ msgid "On call to '%s':"
msgstr "En la llamada a '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Gratis"
@@ -137,6 +136,26 @@ msgid "Anim Change Call"
msgstr "Cambiar Call de Anim"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Cambiar Tiempo de Múltiples Keyframes de Anim"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Cambiar Múltiples Transiciones de Anim"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Cambiar Múltiples Transforms de Anim"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Cambiar Valor de Múltiples Keyframes de Anim"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Cambiar Múltiples Llamadas de Anim"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Cambiar Duración de la Animación"
@@ -640,16 +659,18 @@ msgid "Line Number:"
msgstr "Numero de Línea:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d ocurrencia(s) Reemplazadas."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Sin Coincidencias"
+#, fuzzy
+msgid "%d match."
+msgstr "Se encontraron %d coincidencias."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d ocurrencia(s) Reemplazadas."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Se encontraron %d coincidencias."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -799,9 +820,8 @@ msgid "Connect"
msgstr "Conectar"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Señales:"
+msgstr "Señal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -878,8 +898,7 @@ msgstr "Favoritos:"
msgid "Recent:"
msgstr "Recientes:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -967,9 +986,9 @@ msgid "Owners Of:"
msgstr "Dueños De:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Quitar los archivos seleccionados del proyecto? (imposible deshacer)"
+msgstr ""
+"¿Eliminar los archivos seleccionados del proyecto? (No puede ser restaurado)"
#: editor/dependency_editor.cpp
msgid ""
@@ -981,7 +1000,7 @@ msgstr ""
"funcionar.\n"
"Quitarlos de todos modos? (imposible deshacer)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "No se puede remover:"
@@ -1017,7 +1036,7 @@ msgstr "Eliminar permanentemente %d item(s)? (Imposible deshacer!)"
msgid "Show Dependencies"
msgstr "Mostrar Dependencias"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorador de Recursos Huérfanos"
@@ -1106,14 +1125,16 @@ msgid "License"
msgstr "Licencia"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licencia de Terceros"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine depende de un número de licencias de terceros, libres y de "
@@ -1134,7 +1155,8 @@ msgid "Licenses"
msgstr "Licencias"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Error al abrir el archivo de paquete. No está en formato zip."
#: editor/editor_asset_installer.cpp
@@ -1151,7 +1173,6 @@ msgid "Success!"
msgstr "¡Éxito!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalar"
@@ -1521,6 +1542,7 @@ msgstr "Plantilla no encontrada:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"En la exportación de 32 bits el PCK embebido no puede ser mayor de 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1630,12 +1652,11 @@ msgid "New"
msgstr "Nuevo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importar"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportar"
@@ -1696,7 +1717,7 @@ msgstr "Mostrar en Explorador de Archivos"
msgid "New Folder..."
msgstr "Nueva Carpeta..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Refrescar"
@@ -1747,7 +1768,7 @@ msgstr "Avanzar"
msgid "Go Up"
msgstr "Subir"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Act/Desact. Archivos Ocultos"
@@ -1772,24 +1793,28 @@ msgid "Move Favorite Down"
msgstr "Bajar Favorito"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Carpeta Anterior"
+msgid "Go to previous folder."
+msgstr "Ir a la carpeta anterior."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Carpeta Siguiente"
+msgid "Go to next folder."
+msgstr "Ir a la carpeta siguiente."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Ir a la carpeta padre."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Refrescar archivos."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Quitar carpeta actual de favoritos."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
-msgstr "Ver/Ocultar archivos ocultos."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "Mostrar/Ocultar archivos ocultos."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -2030,6 +2055,11 @@ msgstr "Limpiar"
msgid "Clear Output"
msgstr "Limpiar Salida"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Ventana"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "La exportación del proyecto falló con el código de error %d."
@@ -2355,6 +2385,15 @@ msgid "Pick a Main Scene"
msgstr "Elegí una Escena Principal"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Cerrar Escena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Cerrar Escena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"No se pudo activar el plugin de addon en: '%s' falló el parseo de la "
@@ -2474,6 +2513,11 @@ msgstr "Reproducir Esta Escena"
msgid "Close Tab"
msgstr "Cerrar Pestaña"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Cerrar Pestaña"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Cerrar Otras Pestañas"
@@ -2527,6 +2571,10 @@ msgid "Go to previously opened scene."
msgstr "Ir a la escena abierta previamente."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar Texto"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Pestaña siguiente"
@@ -2554,6 +2602,10 @@ msgstr "Nueva Escena Heredada..."
msgid "Open Scene..."
msgstr "Abrir Escena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Abrir Reciente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Guardar Escena"
@@ -2563,14 +2615,6 @@ msgid "Save All Scenes"
msgstr "Guardar Todas las Escenas"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Cerrar Escena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Abrir Reciente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Convertir A..."
@@ -2600,25 +2644,36 @@ msgstr "Revertir Escena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Herramientas misceláneas a nivel proyecto o escena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Proyecto"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Configuración de Proyecto"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Herramientas"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Exportar..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Instalar plantilla de compilación de Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Abrir Carpeta de Datos del Proyecto"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Herramientas"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Instalar plantilla de compilación de Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorador de Recursos Huérfanos"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2717,12 +2772,13 @@ msgstr ""
"Cuando se use remotamente en un dispositivo, esto es más eficiente con un "
"sistema de archivos de red."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Configuración del Editor"
#: editor/editor_node.cpp
@@ -2738,14 +2794,6 @@ 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"
@@ -2766,14 +2814,16 @@ msgid "Open Editor Settings Folder"
msgstr "Abrir Carpeta de Configuración del Editor"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Administrar Características del Editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gestionar Plantillas de Exportación"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ayuda"
@@ -2781,12 +2831,13 @@ msgstr "Ayuda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Buscar"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentación Online"
@@ -3067,6 +3118,10 @@ msgstr "Tiempo"
msgid "Calls"
msgstr "Llamadas"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Editar Texto:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "On"
@@ -3239,7 +3294,8 @@ msgid "Import From Node:"
msgstr "Importar Desde Nodo:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Volver a Descargar"
#: editor/export_template_manager.cpp
@@ -3256,6 +3312,10 @@ msgid "Download"
msgstr "Descargar"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Faltante)"
@@ -3319,12 +3379,10 @@ msgid "No response."
msgstr "Sin respuesta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Solicitud fallida."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Bucle de redireccionamiento."
@@ -3338,15 +3396,22 @@ msgid "Download Complete."
msgstr "Descarga Completa."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "No se pudo guardar el tema a un archivo:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Fallo la instalación de plantillas. Las plantillas problemáticas pueden ser "
"encontradas en '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Error al pedir el url: "
#: editor/export_template_manager.cpp
@@ -3432,22 +3497,11 @@ msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
"Seleccionar un mirror de la lista: (Shift+Click: Abrir en el Navegador)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"No se puede abrir file_type_cache.cch para escribir, no se guardará el cache "
-"de tipos de archivo!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoritos"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"No se puede navegar a '%s' ya que no se encontro en el sistema de archivos!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Estado: Falló la importación del archivo. Por favor arreglá el archivo y "
@@ -3482,14 +3536,14 @@ msgid "Provided name contains invalid characters."
msgstr "El nombre indicado contiene caracteres inválidos."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "El nombre indicado contiene caracteres inválidos."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Un archivo o carpeta con este nombre ya existe."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "El nombre indicado contiene caracteres inválidos."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Renombrando archivo:"
@@ -3545,6 +3599,11 @@ msgstr "Duplicar..."
msgid "Move To..."
msgstr "Mover A..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nueva Escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nuevo Script.."
@@ -3610,6 +3669,11 @@ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación."
msgid "Overwrite"
msgstr "Sobreescribir"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Crear desde Escena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Crear Script"
@@ -3672,6 +3736,14 @@ msgid "Search complete"
msgstr "Búsqueda completa"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Agregar al Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Quitar del Grupo"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "El nombre del grupo ya existe."
@@ -3679,12 +3751,23 @@ msgstr "El nombre del grupo ya existe."
msgid "Invalid group name."
msgstr "Nombre de grupo inválido."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Administrar Grupos"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Eliminar Grupo de Imágenes"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupos"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nodos fuera del Grupo"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3697,12 +3780,12 @@ msgid "Nodes in Group"
msgstr "Nodos dentro del Grupo"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Agregar al Grupo"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Quitar del Grupo"
+msgid "Group Editor"
+msgstr "Editor de Grupos"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3912,7 +3995,8 @@ msgid "MultiNode Set"
msgstr "Setear MultiNodo"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Seleccionar un Nodo para editar Señales y Grupos."
#: editor/plugin_config_dialog.cpp
@@ -4676,10 +4760,6 @@ msgid "View Files"
msgstr "Ver Archivos"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "No se ha podido resolver el nombre del host:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Error de conexión, por favor intentá de nuevo."
@@ -4692,14 +4772,47 @@ msgid "No response from host:"
msgstr "No hay respuesta desde el host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "No se ha podido resolver el nombre del host:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Solicitud fallida. Código de retorno:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Solicitud fallida."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "No se pudo guardar el tema a un archivo:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Solicitud fallida, demasiadas redireccinoes"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Bucle de redireccionamiento."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Solicitud fallida. Código de retorno:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tiempo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Hash de descarga incorrecto, asumiendo que el archivo fue manipulado."
@@ -4740,6 +4853,10 @@ msgid "Idle"
msgstr "Desocupado"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instalar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Reintentar"
@@ -4768,13 +4885,17 @@ msgid "Last"
msgstr "Ultimo"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Todos"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Reimportando..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4782,8 +4903,8 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Invertir"
+msgid "Reverse sorting."
+msgstr "Orden inverso."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4795,7 +4916,8 @@ msgid "Site:"
msgstr "Sitio:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Soporte..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4807,6 +4929,11 @@ msgid "Testing"
msgstr "Prueba"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Cargar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Archivo ZIP de Assets"
@@ -4864,32 +4991,32 @@ msgid "Rotation Step:"
msgstr "Step de Rotación:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Mover guía vertical"
+msgid "Move Vertical Guide"
+msgstr "Mover Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Crear nueva guía vertical"
+msgid "Create Vertical Guide"
+msgstr "Crear Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Quitar guía vertical"
+msgid "Remove Vertical Guide"
+msgstr "Eliminar Guía Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Mover guía horizontal"
+msgid "Move Horizontal Guide"
+msgstr "Mover Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Crear nueva guía horizontal"
+msgid "Create Horizontal Guide"
+msgstr "Crear Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Quitar guía horizontal"
+msgid "Remove Horizontal Guide"
+msgstr "Eliminar Guía Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Crear nuevas guías horizontales y verticales"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Crear Guías Horizontales y Verticales"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4973,8 +5100,12 @@ msgstr "Pegar Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Restablecer Huesos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
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
msgid "Clear Bones"
@@ -5003,6 +5134,7 @@ msgid "Zoom Reset"
msgstr "Reset de Zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Modo Seleccionar"
@@ -5025,14 +5157,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Click Der.: Selección en depth list"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Modo Mover"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Modo Rotar"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Modo de Escalado"
@@ -5058,6 +5193,7 @@ msgid "Toggle snapping."
msgstr "Act/Desact. alineado."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Usar Snap"
@@ -5074,11 +5210,6 @@ msgid "Use Rotation Snap"
msgstr "Usar Snap de Rotación"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurar Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Usar Snap Relativo"
@@ -5091,6 +5222,11 @@ msgid "Smart Snapping"
msgstr "Ajuste inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Ajustar al Padre"
@@ -5305,16 +5441,6 @@ msgstr "Setear Handle"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Error al cargar la imagen:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Sin pixeles con transparencia > 128 en 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"
@@ -5626,14 +5752,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "La superficie de origen es inválida (sin caras)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "La superficie padre no tiene caras solidas para poblar."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "No se pudo mapear el area."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Seleccioná una Mesh de Origen:"
@@ -5718,20 +5836,27 @@ msgid "Generation Time (sec):"
msgstr "Tiempo de Generación (seg):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Las caras no contienen area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "El nodo no contiene geometría (caras)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Sin caras!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "El nodo no contiene geometría."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "El nodo no contiene geometría (caras)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "El nodo no contiene geometría."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6065,7 +6190,6 @@ msgid "Grid Settings"
msgstr "Ajustes de Grilla"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Esnapear"
@@ -6171,12 +6295,9 @@ msgid "Error writing TextFile:"
msgstr "Error al escribir el TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Error: no se pudo cargar el archivo."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Error no se pudo cargar el archivo."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "No se pudo cargar el tile:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6199,7 +6320,8 @@ msgid "Error Importing"
msgstr "Error al Importar"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nuevo TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6280,6 +6402,11 @@ msgid "Open..."
msgstr "Abrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Abrir Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Guardar Todo"
@@ -6317,13 +6444,13 @@ msgid "Save Theme"
msgstr "Guardar Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Cerrar Docs"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Cerrar Todos"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Cerrar Docs"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Ejecutar"
@@ -6411,6 +6538,11 @@ msgstr "Depurador"
msgid "Search Results"
msgstr "Resultados de la Búsqueda"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Restablecer Escenas Recientes"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Conexiones al método:"
@@ -6428,10 +6560,11 @@ 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 ""
+"No se encuentra el método conectado '%s' para la señal '%s' del nodo '%s' al "
+"nodo '%s'."
#: editor/plugins/script_text_editor.cpp
msgid "Line"
@@ -6478,8 +6611,9 @@ msgid "Syntax Highlighter"
msgstr "Resaltador de Sintaxis"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Ir A"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6487,9 +6621,8 @@ msgid "Bookmarks"
msgstr "Marcadores"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Crear puntos."
+msgstr "Puntos de interrupción"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6513,22 +6646,6 @@ msgid "Toggle Comment"
msgstr "Act/Desact. Comentario"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Act./Desact. Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Ir al Siguiente Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Ir al Marcador Anterior"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Eliminar Todos los Marcadores"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Expandir/Colapsar Línea"
@@ -6549,6 +6666,11 @@ msgid "Complete Symbol"
msgstr "Completar Símbolo"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Escalar Selección"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Eliminar Espacios Sobrantes al Final"
@@ -6565,29 +6687,32 @@ msgid "Auto Indent"
msgstr "Auto Indentar"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Act/Desact. Breakpoint"
+msgid "Find Previous"
+msgstr "Encontrar Anterior"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Quitar Todos los Breakpoints"
+msgid "Find in Files..."
+msgstr "Buscar en Archivos..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Ir al Breakpoint Siguiente"
+msgid "Contextual Help"
+msgstr "Ayuda Contextual"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Ir al Breakpoint Anterior"
+msgid "Toggle Bookmark"
+msgstr "Act./Desact. Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Encontrar Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Ir al Siguiente Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Buscar en Archivos..."
+msgid "Go to Previous Bookmark"
+msgstr "Ir al Marcador Anterior"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Eliminar Todos los Marcadores"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6598,8 +6723,21 @@ msgid "Go to Line..."
msgstr "Ir a Línea..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Ayuda Contextual"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Act/Desact. Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Quitar Todos los Breakpoints"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Ir al Breakpoint Siguiente"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Ir al Breakpoint Anterior"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6778,8 +6916,12 @@ msgid "Rear"
msgstr "Detrás"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Alinear con Vista"
+msgid "Align Transform with View"
+msgstr "Alinear Transform con Vista"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Alinear Rotación con Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6834,8 +6976,9 @@ msgid "Audio Listener"
msgstr "Oyente de Audio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Activar Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Habilitar Filtrado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6890,8 +7033,8 @@ msgid "Snap Nodes To Floor"
msgstr "Ajustar Nodos al Suelo"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Modo Seleccionar (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6904,30 +7047,11 @@ msgstr ""
"Alt+Click Der.: Selección en depth list"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Modo Mover (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Modo Rotar (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Modo Escalar (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordenadas Locales"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Modo de Espacio Local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Modo de Snap (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vista Inferior"
@@ -6968,26 +7092,6 @@ msgid "Focus Selection"
msgstr "Foco en Selección"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Alinear Selección Con Vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Seleccionar Herramienta"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Herramienta Mover"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Herramienta Rotar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Herramienta Escalar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Act./Desact. Vista Libre"
@@ -7042,7 +7146,8 @@ msgstr "Ver Grilla"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Configuración"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7335,10 +7440,6 @@ msgid "TextureRegion"
msgstr "Región de Textura"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "No se pudo guardar el tema a un archivo:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Agregar Todos los Items"
@@ -7423,11 +7524,13 @@ msgid "Submenu"
msgstr "Submenú"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Ãtem 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Ãtem 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7532,14 +7635,6 @@ msgid "Transpose"
msgstr "Transponer"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Espejar X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Espejar Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Desactivar Autotile"
@@ -7552,9 +7647,10 @@ msgid "Paint Tile"
msgstr "Pintar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift + Clic derecho: Dibujar línea\n"
"Shift + Ctrl + Clic derecho: Pintar Rectángulo"
@@ -7851,6 +7947,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Sólo GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Añadir entrada +"
@@ -7927,6 +8027,11 @@ msgid "Duplicate Nodes"
msgstr "Duplicar Nodos"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Pegar Nodos"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Eliminar Nodos"
@@ -7947,404 +8052,470 @@ msgid "Light"
msgstr "Luz"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Crear Nodo Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
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 Escala de Grises."
#: 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(subexponer)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Operador Darken(oscurecer)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Solo Diferencias"
+msgstr "Operador Difference(diferencia)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Operador Dodge(sobreexponer)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "HardLight operator"
-msgstr ""
+msgstr "Operador HardLight(luz fuerte)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "Operador Lighten(aclarar)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Operador Overlay(superponer)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Operador Screen(trama)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "Operador SoftLight(luz suave)."
#: 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 the boolean result of the %s comparison between two parameters."
+msgstr ""
+"Devuelve el resultado booleano de la comparación de %s entre dos parámetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Igual (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Mayor Que (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Mayor o Igual Que (>=)"
#: 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 the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre INF y un parámetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre NaN y un parámetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Menor Que (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Menor o Igual Que (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "No igual (!=)"
#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Devuelve el resultado booleano de la comparación entre dos parámetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Devuelve el resultado booleano de la comparación entre INF (o NaN) y un "
+"parámetro escalar."
#: 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 ""
+msgstr "Uniform booleano."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "Parámetro de entrada %s' para todos los modos de shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Alinear al Padre"
+msgstr "Parámetro de entrada."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modos vertex y fragment shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modos fragment y light shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modo fragment shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modo light shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modo vertex shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "Parámetro de entrada '%s' para modos vertex y fragment shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Cambiar Función Escalar"
+msgstr "Función Escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "Cambiar 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). 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). Proporcion áurea."
#: 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 ""
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "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 ""
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "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 ""
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "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 ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "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 ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "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 ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "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 ""
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "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
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"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
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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 ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "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 ""
+msgid "Finds the truncated value of the parameter."
+msgstr "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 escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Cambiar Uniforme Escalar"
+msgstr "Uniform escalar."
#: 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 Uniforme Textura"
+msgid "Cubic texture uniform lookup."
+msgstr "Búsqueda en uniform de textura cúbica."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "2D texture uniform."
-msgstr "Cambiar Uniforme Textura"
+msgid "2D texture uniform lookup."
+msgstr "Búsqueda en uniform de textura 2D."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Búsqueda en uniform de textura 2D con triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Cuadro de diálogo de Transform..."
+msgstr "Función Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8352,174 +8523,207 @@ 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 ""
+"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 un transform a partir de cuatro vectores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Descompone un transform en cuatro vectores."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr ""
+msgid "Calculates the determinant of a transform."
+msgstr "Calcula la determinante de un transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Calcula el inverso de un transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Calcula la transposición de un transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Multiplica transform por transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Multiplica vector por transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Transformación Abortada."
+msgstr "Constante transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Transformación Abortada."
+msgstr "Uniform de transform."
#: 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 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 ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Devuelve el 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 de 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
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+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 "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Devuelve el vector que apunta en la dirección de 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 ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Devuelve el vector que apunta en la dirección de refracción."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"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
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"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
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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 "Suma 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 vectorial."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "Asignación a uniform."
+msgstr "Uniform vectorial."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8527,56 +8731,80 @@ 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 ""
+"Devuelve el falloff en base al producto punto de la superficie normal y la "
+"dirección de vista de la camara ( pasale los puntos asociados)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Sólo modo Fragmento/Luz) Función derivada escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Sólo modo Fragmento/Luz) Función derivada vectorial."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Sólo modo Fragmento/Luz) (Vector) Derivada 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."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Sólo modo Fragmento/Luz) (Escalar) Derivada 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."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Sólo modo Fragmento/Luz) (Vector) Derivada 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."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Sólo modo Fragmento/Luz) (Escalar) Derivada 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'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(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'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Sólo modo Fragmento/Luz) (Escalar) Suma de la derivada absoluta en 'x' e "
+"'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8753,6 +8981,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Faltan las plantillas de exportación para esta plataforma:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gestionar Plantillas de Exportación"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exportar Con Depuración"
@@ -8912,6 +9144,15 @@ msgid "Unnamed Project"
msgstr "Proyecto Sin Nombre"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importar Proyecto Existente"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "No se puede abrir el proyecto en '%s'."
@@ -8920,7 +9161,6 @@ msgid "Are you sure to open more than one project?"
msgstr "¿Estás seguro/a 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"
@@ -8943,7 +9183,6 @@ msgstr ""
"anteriores del 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"
@@ -8954,12 +9193,12 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
-"Las siguientes configuraciones de proyecto fueron generadas para una versión "
-"anterior del motor, y deben ser convertidas para esta versión:\n"
+"El siguiente archivo de configuración de proyecto fue generado por una "
+"versión anterior del motor, y debe se convertido para esta versión:\n"
"\n"
"%s\n"
"\n"
-"¿Querés convertirlas?\n"
+"¿Querés convertirlo?\n"
"Advertencia: No vas a poder volver a abrir el proyecto con versiones "
"anteriores del motor."
@@ -8972,15 +9211,14 @@ msgstr ""
"del motor y no son compatibles 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 sé puede ejecutar el proyecto: No se ha definido ninguna escena "
+"No se puede ejecutar el proyecto: No se ha definido ninguna escena "
"principal.\n"
-"Por favor editá el proyecto y seteá la escena principal en \"Ajustes de "
+"Por favor editá el proyecto y asigná la escena principal en \"Ajustes de "
"Proyecto\" bajo la categoría 'Aplicación'."
#: editor/project_manager.cpp
@@ -8992,63 +9230,60 @@ msgstr ""
"Por favor editá el proyecto para provocar la importación inicial."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "¿Estás seguro/a que quieres ejecutar más de un proyecto?"
+msgstr "¿Estás seguro/a que querés 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 ""
-"¿Quitar proyecto de la lista? (Los contenidos de la carpeta no serán "
-"modificados)"
+"¿Quitar %d proyectos de la lista?\n"
+"El contenido de las carpetas de proyecto no 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 ""
-"¿Quitar proyecto de la lista? (Los contenidos de la carpeta no serán "
-"modificados)"
+"¿Quitar este proyecto de la lista?\n"
+"El contenido de la carpeta de proyecto no será modificado."
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"¿Quitar proyecto de la lista? (Los contenidos de la carpeta no serán "
-"modificados)"
+"¿Quitar %d proyectos de la lista?\n"
+"El contenido de las carpetas de proyecto no será modificado."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
"Lenguaje cambiado.\n"
-"La interfaz de usuario se actualizara la próxima vez que el editor o gestor "
-"de proyectos inicie."
+"La interfaz de usuario se actualizara luego de reiniciar el editor o 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 examinar %s carpetas en busca de proyectos de Godot. "
-"¿Confirmar?"
+"¿Estás seguro de querer examinar %s carpetas en busca de proyectos de Godot "
+"existentes?\n"
+"Podría demorar un rato."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestor de Proyectos"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Listado de Proyectos"
+#, fuzzy
+msgid "Projects"
+msgstr "Proyecto"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9063,19 +9298,14 @@ msgid "New Project"
msgstr "Proyecto Nuevo"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Quitar punto"
+msgstr "Eliminar Faltantes"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "Plantillas"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Salir"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Reiniciar Ahora"
@@ -9084,13 +9314,12 @@ 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 tenés ningun proyecto.\n"
-"Te gustaría explorar los ejemplos oficiales en la Biblioteca de Assets?"
+"Actualmente no tenés ningún proyecto.\n"
+"¿Te gustaría explorar los ejemplos oficiales en la Biblioteca de Assets?"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9117,9 +9346,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"
@@ -9338,9 +9566,8 @@ msgid "Override For..."
msgstr "Sobreescribir Para..."
#: 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"
@@ -9399,14 +9626,12 @@ msgid "Locales Filter"
msgstr "Filtro de Locales"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "Mostrar todos los locales"
+msgstr "Mostrar Todas las Localizaciones"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "Mostrar solo los locales seleccionados"
+msgstr "Mostrar Sólo las Localizaciones Seleccionadas"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
@@ -9420,6 +9645,10 @@ msgstr "Locales:"
msgid "AutoLoad"
msgstr "AutoLoad"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9472,15 +9701,6 @@ msgstr "Seleccionar Método Virtual"
msgid "Select Method"
msgstr "Seleccionar Método"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "No se pudo ejecutar la herramienta PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"No se pudo volver a cargar la imagen convertida usando la herramienta PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Renombrar en Masa"
@@ -9494,9 +9714,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"
@@ -9757,9 +9976,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!"
@@ -9779,6 +9997,11 @@ msgid "Remove Node(s)"
msgstr "Quitar Nodo(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Cambiar nombre del puerto de salida"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9803,18 +10026,16 @@ msgid "Clear Inheritance"
msgstr "Limpiar Herencia"
#: 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 "Agregar Nodo Hijo"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Colapsar Todos"
+msgstr "Expandir/Colapsar Todo"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -9825,6 +10046,10 @@ msgid "Extend Script"
msgstr "Extender Script"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Reemparentar a Nuevo Nodo"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Convertir en Raíz de Escena"
@@ -9845,9 +10070,8 @@ msgid "Delete (No Confirm)"
msgstr "Eliminar (Sin Confirmación)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Agregar/Crear un Nuevo Nodo"
+msgstr "Añadir/Crear un Nuevo Nodo."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -9882,52 +10106,51 @@ msgid "Toggle 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:"
msgstr "Advertencia de configuración de nodo:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"El nodo tiene conexión/es y grupo/s.\n"
"Clic para mostrar el panel de señales."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"El nodo tiene conexiones.\n"
"Click para mostrar el panel de señales."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"El nodo está en un grupo/s.\n"
"Click 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 ""
@@ -9979,39 +10202,32 @@ msgid "Select a Node"
msgstr "Seleccionar un Nodo"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "La ruta está vacía"
+msgstr "La ruta está vacía."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Nombre de archivo vacio"
+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 inválida"
+msgstr "Ruta base inválida."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Existe un directorio con el mismo nombre"
+msgstr "Existe un directorio con el mismo nombre."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Extensión invalida"
+msgstr "Extensión inválida."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Wrong extension chosen."
-msgstr "Extensión incorrecta elegida"
+msgstr "Extensión incorrecta elegida."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
@@ -10026,56 +10242,53 @@ msgid "Error loading script from %s"
msgstr "Error al cargar el script desde %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sobreescribir"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
#: 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"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "File exists, it will be reused."
-msgstr "El archivo existe, será reutilizado"
+msgstr "El archivo existe, será reutilizado."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Nombre de clase inválido"
+msgstr "Nombre de clase inválido."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid inherited parent name or path."
-msgstr "Ruta o nombre del padre heredado inválido"
+msgstr "Ruta o nombre 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 "Permitidos: a-z, A-Z, 0-9 y _"
+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 (dentro del archivo de escena)"
+msgstr "Script Integrado (dentro del archivo de escena)."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Crear script nuevo"
+msgstr "Se creará un nuevo archivo de script."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Cargar script existente"
+msgstr "Se cargará un archivo de script existente."
#: editor/script_create_dialog.cpp
msgid "Language"
@@ -10207,7 +10420,7 @@ msgstr "Setear Desde Arbol"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Exportar medidas como CSV"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10222,6 +10435,10 @@ msgid "Change Shortcut"
msgstr "Cambiar Atajo"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Configuración del Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Atajos"
@@ -10339,12 +10556,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 Update Spinner"
+msgstr "GDNative Singleton desactivado"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -10434,9 +10650,8 @@ msgid "GridMap Fill Selection"
msgstr "Llenar Selección en GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "Eliminar Seleccionados en GridMap"
+msgstr "Pegar lo Seleccionado en GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -10644,10 +10859,30 @@ msgid "Set Variable Type"
msgstr "Editar Tipo de Variable"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "No debe coincidir con el nombre de un tipo built-in ya existente."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Crear un rectángulo nuevo."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variables:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Crear un rectángulo nuevo."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Crear un nuevo polígono."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "El nombre no es un identificador válido:"
@@ -10816,9 +11051,8 @@ 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 "Seleccioná o creá una función para editar el grafo"
+msgstr "Selecciona o crea una función para editar el gráfico."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
@@ -10837,10 +11071,6 @@ msgid "Cut Nodes"
msgstr "Cortar Nodos"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Pegar Nodos"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Editar Miembros"
@@ -10957,15 +11187,21 @@ msgstr ""
#: 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."
@@ -10980,6 +11216,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, reinstalá desde el menú "
+"'Proyecto'."
#: platform/android/export/export.cpp
msgid ""
@@ -10988,20 +11227,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, reinstalá 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 podés 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."
@@ -11132,13 +11379,12 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
-"Un recurso SpriteFrames debe ser creado o seteado en la propiedad 'Frames' "
-"para que AnimatedSprite pueda mostrar frames."
+"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
+"\" para que AnimatedSprite pueda mostrar frames."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11201,12 +11447,12 @@ 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\" "
"property."
msgstr ""
-"Se debe proveer una textura con la forma de la luz a la propiedad 'texture'."
+"Se debe proporcionar una textura con la forma de la luz a la propiedad "
+"\"Texture\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11216,9 +11462,10 @@ msgstr ""
"efecto."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+msgstr ""
+"El polígono oclusor para este oclusor está vacío. Por favor, dibujá un "
+"polígono."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11316,51 +11563,44 @@ msgstr ""
"RigidBody2D, KinematicBody2D, etc. para que puedan tener forma."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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 "
+"VisibilityEnabler2D funciona mejor cuando se usa con la raíz de la escena "
"editada directamente como padre."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera debe tener un nodo ARVROrigin como su padre"
+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 debe tener un nodo ARVROrigin como su 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 de controlador no debe ser 0 o este controlador no será vinculado a un "
-"controlador real"
+"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 debe tener un nodo ARVROrigin como su 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 de anclaje no debe ser 0 o este anclaje no podrá ser vinculado a un "
-"anclaje real"
+"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 requiere un nodo hijo ARVRCamera"
+msgstr "ARVROrigin requiere un nodo hijo ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -11422,13 +11662,12 @@ 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."
msgstr ""
-"Se debe proveer un shape para que CollisionShape funcione. Creale un recurso "
-"shape!"
+"Se debe proporcionar un shape para que CollisionShape funcione. Por favor, "
+"crea un recurso de shape para ello."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11443,13 +11682,12 @@ 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 ""
-"Animar 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"
@@ -11466,6 +11704,8 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Un SpotLight con un ángulo mas ancho que 90 grados no puede proyectar "
+"sombras."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11497,13 +11737,12 @@ msgid ""
msgstr "Nada visible ya que no se asigno pasadas de dibujado a los meshes."
#: scene/3d/particles.cpp
-#, fuzzy
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
-"Animar Particles 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."
@@ -11511,13 +11750,12 @@ msgstr ""
"PathFollow solo funciona cuando está asignado como hijo de un nodo Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"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."
+"PathFollow's ROTATION_ORIENTED requiere que \"Up Vector\" esté activado en "
+"el recurso Curve de su Path padre."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11530,17 +11768,16 @@ msgstr ""
"Cambiá el tamaño de los collision shapes hijos."
#: scene/3d/remote_transform.cpp
-#, 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."
+"La propiedad \"Remote Path\" debe apuntar a un nodo Spatial o derivado de "
+"Spatial válido para que funcione."
#: 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 ""
@@ -11553,13 +11790,12 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Un recurso SpriteFrames debe ser creado o asignado en la propiedad 'Frames' "
-"para que AnimatedSprite3D pueda mostrar frames."
+"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
+"\" para que AnimatedSprite3D pueda mostrar frames."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11574,6 +11810,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment requiere que su propiedad \"Environment\" contenga un "
+"Environment para que tenga un efecto visible."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11612,9 +11850,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
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "No hay asignado ningún nodo AnimationNode raíz para el gráfico."
+msgstr "No se ha establecido ningún nodo AnimationNode raíz para el gráfico."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11627,9 +11864,8 @@ msgstr ""
"La ruta asignada al AnimationPlayer no apunta a un nodo AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "La raíz del AnimationPlayer no es un nodo válido."
+msgstr "La raíz del nodo AnimationPlayer no es un nodo válido."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11641,12 +11877,11 @@ msgstr "Elegir un color de la pantalla."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "Yaw"
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11657,22 +11892,24 @@ msgid "Add current color as a preset."
msgstr "Agregar color actual como preset."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
-"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."
+"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 tenés intención de añadir un script, utilizá un nodo de 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 ""
+"Los Tooltip de Ayuda no se mostrarán cuando los controles del Filtro del "
+"Mouse estén configurados en \"Ignore\". Para solucionarlo, establece el "
+"Filtro del Mouse en \"Stop\" o \"Pass\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
@@ -11683,31 +11920,28 @@ 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, 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."
+"Los popups se ocultarán por defecto a menos que llames a popup() o a "
+"cualquiera de las funciones popup*(). Puedes hacerlos visibles para su "
+"edición, pero se esconderán al iniciar."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Si \"Exp Edit\" está activado, \"Min Value\" debe ser mayor que 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer está diseñado para trabajar con un único control hijo.\n"
-"Usa un container como hijo (VBox, HBox, etc), o un Control y setea el tamaño "
-"mínimo personalizado de forma manual."
+"ScrollContainer está pensado para funcionar con un solo control hijo.\n"
+"Utilizá un container como hijo (VBox, HBox, etc.), o un Control y establecé "
+"manualmente el tamaño mínimo personalizado."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11733,35 +11967,22 @@ msgstr ""
"pueda obtener un tamaño. Alternativamente, haz un RenderTarget y asigna su "
"textura interna a algún otro nodo para mostrar."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Error inicializando FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Formato de tipografía desconocido."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error cargando tipografía."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Tamaño de tipografía inválido."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrada"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Fuente inválida para el shader."
+msgstr "Fuente inválida para la vista previa."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Fuente inválida para el shader."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Función de comparación inválida para este tipo."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Asignación a función."
@@ -11776,7 +11997,132 @@ 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 "No Matches"
+#~ msgstr "Sin Coincidencias"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "No se puede abrir file_type_cache.cch para escribir, no se guardará el "
+#~ "cache de tipos de archivo!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "No se puede navegar a '%s' ya que no se encontro en el sistema de "
+#~ "archivos!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Error al cargar la imagen:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Sin pixeles con transparencia > 128 en imagen..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "La superficie padre no tiene caras solidas para poblar."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "No se pudo mapear el area."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Las caras no contienen area!"
+
+#~ msgid "No faces!"
+#~ msgstr "Sin caras!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Error: no se pudo cargar el archivo."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Error no se pudo cargar el archivo."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Activar Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Modo Seleccionar (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Modo Mover (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Modo Rotar (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Modo Escalar (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordenadas Locales"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Modo de Snap (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Seleccionar Herramienta"
+
+#~ msgid "Tool Move"
+#~ msgstr "Herramienta Mover"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Herramienta Rotar"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Herramienta Escalar"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "¿Eliminar todos los proyectos faltantes de la lista? (El contenido de las "
+#~ "carpetas no se modificará)"
+
+#~ msgid "Project List"
+#~ msgstr "Listado de Proyectos"
+
+#~ msgid "Exit"
+#~ msgstr "Salir"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "No se pudo ejecutar la herramienta PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "No se pudo volver a cargar la imagen convertida usando la herramienta "
+#~ "PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Error inicializando FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Formato de tipografía desconocido."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error cargando tipografía."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Tamaño de tipografía inválido."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Carpeta Anterior"
+
+#~ msgid "Next Folder"
+#~ msgstr "Carpeta Siguiente"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Abrir Capturas de Pantalla Automaticamente"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Abrir en editor de imagenes externo."
+
+#~ msgid "Reverse"
+#~ msgstr "Invertir"
+
+#~ msgid "Mirror X"
+#~ msgstr "Espejar X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Espejar Y"
#~ msgid "Generating solution..."
#~ msgstr "Generando solución..."
@@ -12361,9 +12707,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Eliminar Selección"
-#~ msgid "Could not find tile:"
-#~ msgstr "No se pudo cargar el tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nombre o ID de Item:"
@@ -12632,9 +12975,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "Info"
-#~ msgid "Re-Import..."
-#~ msgstr "Reimportando..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Sin máscaras de bits para importar!"
@@ -13029,9 +13369,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "Estereo"
-#~ msgid "Window"
-#~ msgstr "Ventana"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Escalando a %s%%."
@@ -13268,9 +13605,6 @@ msgstr ""
#~ msgid "Add Image Group"
#~ msgstr "Agregar Grupo de Imágenes"
-#~ msgid "Delete Image Group"
-#~ msgstr "Eliminar Grupo de Imágenes"
-
#~ msgid "Project Export Settings"
#~ msgstr "Ajustes de Exportación del Proyecto"
@@ -13355,9 +13689,6 @@ msgstr ""
#~ msgid "Export Project PCK"
#~ msgstr "Exportar PCK de Proyecto"
-#~ msgid "Export..."
-#~ msgstr "Exportar..."
-
#~ msgid "Project Export"
#~ msgstr "Exportar Proyecto"
@@ -13462,6 +13793,3 @@ msgstr ""
#~ msgid "Deploy File Server Clients"
#~ msgstr "Hacer Deploy de Clientes del Servidor de Archivos"
-
-#~ msgid "Group Editor"
-#~ msgstr "Editor de Grupos"
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 5e5c7e153b..1540cf65d0 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -3,94 +3,99 @@
# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
# Jens <arrkiin@gmail.com>, 2019.
+# Mattias Aabmets <mattias.aabmets@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2019-07-19 13:41+0000\n"
+"Last-Translator: Mattias Aabmets <mattias.aabmets@gmail.com>\n"
"Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/"
"godot/et/>\n"
"Language: et\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 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 ""
+"Kehtetu argument sisestatud convert() funktsiooni, kasuta TYPE_* konstante."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr ""
+msgstr "Ebapiisav kogus baite nende dekodeerimiseks või kehtetu formaat."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Väljendis on kehtetu sisend %i (mitte edastatud)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr ""
+msgstr "'self' märksõna ei saa kasutada, sest loode puudub (mitte edastatud)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "Kehtetud väärtused operaatorisse %s, %s ja %s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr ""
+msgstr "Kehtetu %s tüübi indeks %s põhitüübi jaoks"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "Kehtetu '%s' nimega indeks %s põhitüübi jaoks"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
-msgstr ""
+msgstr "Kehtetud argumendid '%s' ehitamise jaoks"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "'%' kutsudes:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
-msgstr ""
+msgstr "Vaba"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Tasakaalustatud"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr ""
+msgstr "Peegel"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
-msgstr ""
+msgstr "Aeg:"
#: editor/animation_bezier_editor.cpp
msgid "Value:"
-msgstr ""
+msgstr "Väärtus:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr ""
+msgstr "Sisesta Võti Siia"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr ""
+msgstr "Kopeeri Valitud Võti (Võtmed)"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr ""
+msgstr "Kustuta Valitud Võti (Võtmed)"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr ""
+msgstr "Lisa Bezieri Punkt"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr ""
+msgstr "Liiguta Bezieri Punkte"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -121,13 +126,33 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
-msgid "Change Animation Length"
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr "Muuda Animatsiooni Pikkust"
+
+#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Muuda Animatsiooni Silmust"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -172,15 +197,15 @@ msgstr ""
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Functions:"
-msgstr ""
+msgstr "Funktsioonid:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr ""
+msgstr "Heliklipid:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "Animatsiooni Klipid:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
@@ -208,7 +233,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr ""
+msgstr "Aeg (Ajad): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -216,15 +241,15 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Continuous"
-msgstr ""
+msgstr "Pidev"
#: editor/animation_track_editor.cpp
msgid "Discrete"
-msgstr ""
+msgstr "Mittepidev"
#: editor/animation_track_editor.cpp
msgid "Trigger"
-msgstr ""
+msgstr "Päästik"
#: editor/animation_track_editor.cpp
msgid "Capture"
@@ -232,16 +257,16 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Nearest"
-msgstr ""
+msgstr "Lähim"
#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
msgid "Linear"
-msgstr ""
+msgstr "Sirgjooneline"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr ""
+msgstr "Kuupmõõtmeline"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
@@ -254,27 +279,27 @@ msgstr ""
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr ""
+msgstr "Sisesta Võti"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
-msgstr ""
+msgstr "Kopeeri Võti (Võtmed)"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
-msgstr ""
+msgstr "Kustuta Võti (Võtmed)"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr ""
+msgstr "Muuda Animatsiooni Uuendamise Töörežiimi"
#: editor/animation_track_editor.cpp
msgid "Change Animation Interpolation Mode"
-msgstr ""
+msgstr "Muuda Animatsiooni Interpolatsiooni Töörežiimi"
#: editor/animation_track_editor.cpp
msgid "Change Animation Loop Mode"
-msgstr ""
+msgstr "Muuda Animatsiooni Silmuse Töörežiimi"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -297,7 +322,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
msgid "Create"
-msgstr ""
+msgstr "Loo"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
@@ -321,7 +346,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Change Animation Step"
-msgstr ""
+msgstr "Muuda Animatsiooni Sammu"
#: editor/animation_track_editor.cpp
msgid "Rearrange Tracks"
@@ -341,23 +366,24 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "Animatsiooni rajad võivad osutada ainult AnimationPlayer sõlmedele."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
msgstr ""
+"Animatsiooni mängija ei saa animeerida iseennast, ainult teisi mängijaid."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "Ei saa lisada uut rada ilma tüveta"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
-msgstr ""
+msgstr "Lisa Bezieri Rada"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr ""
+msgstr "Raja tee on kehtetu, mistõttu ei sa lisada võtit."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
@@ -369,19 +395,19 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Add Track Key"
-msgstr ""
+msgstr "Lisa Raja Võti"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr ""
+msgstr "Raja tee on kehtetu, mistõttu ei saa lisada meetodi võtit."
#: editor/animation_track_editor.cpp
msgid "Add Method Track Key"
-msgstr ""
+msgstr "Lisa Meetodi Raja Võti"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
-msgstr ""
+msgstr "Meetod ei ole leitud objektis: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
@@ -389,11 +415,11 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
-msgstr ""
+msgstr "Lõikelaud on tühi"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
-msgstr ""
+msgstr "Kleebi Rajad"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
@@ -424,11 +450,11 @@ 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 ""
+msgstr "Vali Kõik"
#: editor/animation_track_editor.cpp
msgid "Select None"
-msgstr ""
+msgstr "Tühista Valik"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -448,11 +474,11 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "Sekundid"
#: editor/animation_track_editor.cpp
msgid "FPS"
-msgstr ""
+msgstr "Kaadrit/Sekundis"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -461,7 +487,7 @@ 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 "Muuda"
#: editor/animation_track_editor.cpp
msgid "Animation properties."
@@ -469,7 +495,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr ""
+msgstr "Kopeeri Rajad"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -489,31 +515,31 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
-msgstr ""
+msgstr "Kustuta Valim"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr ""
+msgstr "Mine Järgmisele Sammule"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr ""
+msgstr "Mine Eelmisele Sammule"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr ""
+msgstr "Optimiseeri Animatsiooni"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr ""
+msgstr "Korrasta Animatsiooni"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
-msgstr ""
+msgstr "Vali sõlm mida animeerida:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "Kasuta Bezieri Kurve"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -533,27 +559,27 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Optimize"
-msgstr ""
+msgstr "Optimiseeri"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr ""
+msgstr "Eemalda kehtetud võtmed"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr ""
+msgstr "Eemalda lahenduseta ja tühjad rajad"
#: editor/animation_track_editor.cpp
msgid "Clean-up all animations"
-msgstr ""
+msgstr "Korrasta kõik animatsioonid"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr ""
+msgstr "Korrasta Animatsioon(id) (EI SAA TAGASI VÕTTA!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
-msgstr ""
+msgstr "Korrasta"
#: editor/animation_track_editor.cpp
msgid "Scale Ratio:"
@@ -570,7 +596,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 ""
+msgstr "Kopeeri"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
@@ -605,15 +631,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -837,8 +863,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -932,7 +957,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -968,7 +993,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1057,14 +1082,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1081,7 +1106,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1098,7 +1123,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1565,12 +1589,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1631,7 +1654,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1682,7 +1705,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1707,23 +1730,29 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Mine Eelmisele Sammule"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Mine Järgmisele Sammule"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1956,6 +1985,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2252,6 +2285,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2345,6 +2386,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2398,6 +2443,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopeeri"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2425,20 +2475,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2471,24 +2517,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2568,12 +2622,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2589,14 +2643,6 @@ 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 ""
@@ -2617,14 +2663,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2632,12 +2678,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2909,6 +2956,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3070,7 +3121,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3087,6 +3138,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3148,12 +3203,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3167,13 +3220,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3258,19 +3315,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3303,11 +3352,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3366,6 +3415,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3429,6 +3482,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Loo"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3489,6 +3547,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3496,12 +3562,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3514,11 +3588,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3725,7 +3799,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4467,10 +4541,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4483,14 +4553,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Aeg:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4531,6 +4630,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4559,13 +4662,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4573,7 +4678,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4586,7 +4691,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4598,6 +4703,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4648,31 +4757,33 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Eemalda kehtetud võtmed"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Eemalda kehtetud võtmed"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4752,6 +4863,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4780,6 +4895,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4800,14 +4916,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4831,6 +4950,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4847,11 +4967,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4864,6 +4979,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5071,16 +5191,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5391,14 +5501,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5482,19 +5584,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5821,7 +5927,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5927,11 +6032,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5955,7 +6056,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6036,6 +6137,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6073,11 +6178,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6165,6 +6270,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6231,6 +6340,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6265,92 +6375,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Kustuta Valim"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6528,7 +6643,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6584,7 +6703,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6638,7 +6757,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6649,27 +6768,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6713,26 +6812,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6787,7 +6866,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7080,10 +7159,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7168,11 +7243,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7277,14 +7352,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7298,8 +7365,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7578,6 +7645,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7654,6 +7725,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7674,6 +7750,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7746,6 +7826,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7753,10 +7849,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7845,7 +7975,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7853,7 +7983,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7865,7 +7995,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7882,7 +8012,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7951,11 +8081,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7971,7 +8101,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7982,7 +8112,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -7991,7 +8121,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7999,11 +8129,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8043,11 +8173,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8056,7 +8190,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8074,15 +8208,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8131,7 +8265,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8146,6 +8280,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8159,19 +8297,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8180,7 +8318,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8189,14 +8327,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8241,47 +8379,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8448,6 +8593,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8594,6 +8743,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8663,8 +8820,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8684,7 +8841,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8708,10 +8865,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9045,6 +9198,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9097,14 +9254,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9390,6 +9539,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9432,6 +9585,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9503,19 +9660,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9606,6 +9763,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9634,7 +9795,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9794,6 +9955,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10204,10 +10369,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10392,10 +10573,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11125,22 +11302,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11153,6 +11314,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
new file mode 100644
index 0000000000..881afb2b7c
--- /dev/null
+++ b/editor/translations/eu.po
@@ -0,0 +1,11325 @@
+# Basque translation of the Godot Engine editor
+# Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
+# This file is distributed under the same license as the Godot source code.
+# Julen Irazoki <rktzbkr.julen@gmail.com>, 2019.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2019-08-15 10:23+0000\n"
+"Last-Translator: Julen Irazoki <rktzbkr.julen@gmail.com>\n"
+"Language-Team: Basque <https://hosted.weblate.org/projects/godot-engine/"
+"godot/eu/>\n"
+"Language: eu\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.8\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 ""
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr ""
+"Ez daude byte nahikoa byte-ak dekodetzeko, edota formatua ez da zuzena."
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+msgid "Create"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp 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 ""
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "FPS"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+#: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr ""
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select tracks to copy:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replaced %d occurrence(s)."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr ""
+
+#: editor/code_editor.cpp editor/rename_dialog.cpp
+msgid "Replace"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_settings_editor.cpp editor/script_create_dialog.cpp
+msgid "Path"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Remove selected files from the project? (Can't be restored)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio Bus, Drag and Drop to rearrange."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Enable"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Not in resource path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr ""
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem and Import Docks"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "New Folder..."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Refresh"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/inspector_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Hidden Files"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Preview:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr ""
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr ""
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+msgid "Inherits:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Brief Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "enum "
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There are currently no tutorials for this class, you can [color=$color][url="
+"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
+"url][/color]."
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr ""
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr ""
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr ""
+
+#: editor/editor_log.cpp editor/editor_profiler.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project export failed with error code %d."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error trying to save layout!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Default editor layout overridden."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Restored default layout to base settings."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene was never saved, please save it prior to running."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr ""
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "No"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This scene has never been saved. Save before running?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This action cannot be undone. Revert anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr ""
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When exporting or deploying, the resulting executable will attempt to "
+"connect to the IP of this computer in order to be debugged."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network FS"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, export or deploy will produce a minimal "
+"executable.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploy will use the USB cable for faster performance. This "
+"option speeds up testing for games with a large footprint."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: 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 ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Navigation meshes and polygons will be visible on the running game if this "
+"option is turned on."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Scene Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any changes made to the scene in the editor "
+"will be replicated in the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Script Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any script that is saved will be reloaded on "
+"the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle Fullscreen"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle System Console"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data/Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
+msgid "Search"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Issue Tracker"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause the scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_profiler.cpp
+msgid "Stop"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Node"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr ""
+
+#: editor/editor_node.cpp scene/resources/visual_shader.cpp
+msgid "Output"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will install the Android project for custom builds.\n"
+"Note that, in order to use it, it needs to be enabled per export preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+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 ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_export.cpp
+msgid "Export Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Password:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr ""
+
+#: editor/editor_profiler.cpp editor/plugins/animation_state_machine_editor.cpp
+#: editor/rename_dialog.cpp
+msgid "Start"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr ""
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the export menu."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "There is already file or folder with the same name in this location."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Search complete"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid " Files"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr ""
+
+#: editor/import_dock.cpp editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Save scenes, re-import and restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr ""
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Language:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node Moved"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Error!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr ""
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Add Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed sha256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Reverse sorting."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/project_settings_editor.cpp
+msgid "Category:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene (for images to be saved in the same dir), or pick a save "
+"path from the BakedLightmap properties."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move pivot"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated 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 ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr ""
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Convex Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Failed creating shapes!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Shape(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Collision Sibling(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr ""
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon->UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV->Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Type:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Request Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Help improve the Godot documentation by giving feedback."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Source"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "(ignore)"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "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
+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
+msgid "Delete Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed (FPS):"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Icon"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete patch '%s' from list?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files from project (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Patches"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Make Patch"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path does not exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a 'project.godot' or '.zip' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Directory already contains a Godot project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Shift+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Alt+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Control+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per Level counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set the counter restarts for each group of child nodes"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "CamelCase to under_scored"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "under_scored to CamelCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Error"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear a script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script is valid."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Language"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Inherits"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Template"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Child Process Connected"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video Mem"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr ""
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Base Type:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Available Nodes:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "ADB executable not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgstr ""
+
+#: 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."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "No build apk generated at: "
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier segments must be of non-zero length."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "A digit cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid ""
+"The character '%s' cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The Identifier must have at least one '.' separator."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "%d%%"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "(Time Left: %d:%02d s)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Meshes: "
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Lights:"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Lighting Meshes: "
+msgstr ""
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"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 ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the screen."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr ""
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+
+#: scene/resources/visual_shader.cpp
+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 ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr ""
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index fb41413eb2..9c919cfa50 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -74,7 +74,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "ازاد کردن"
@@ -146,6 +145,31 @@ msgstr "Ùراخوانی را در انیمیشن تغییر بده"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "تغییر زمان Ùریم کلید در انیمیشن"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "انتقال را در انیمیشن تغییر بده"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "انتقال را در انیمیشن تغییر بده"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "تغییر مقدار Ùریم کلید در انیمیشن"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Ùراخوانی را در انیمیشن تغییر بده"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "طول انیمیشن را تغییر بده"
@@ -658,17 +682,18 @@ msgid "Line Number:"
msgstr "شماره خط:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "تعداد d% رخداد جایگزین شد."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "تطبیقی ندارد"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "تعداد d% رخداد جایگزین شد."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "بین حرو٠کوچک و بزرگ لاتین تمایز قائل شو"
@@ -906,8 +931,7 @@ msgstr "برگزیده‌ها:"
msgid "Recent:"
msgstr "اخیر:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1011,7 +1035,7 @@ msgstr ""
"کنند.\n"
"آیا در هر صورت حذ٠شوند؟(بدون برگشت)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "امکان حذ٠وجود ندارد :"
@@ -1049,7 +1073,7 @@ msgstr "به طور دائمی تعداد 'd%' آیتم را حذ٠کند؟ (ب
msgid "Show Dependencies"
msgstr "بستگی‌ها"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "پوینده‌ی منبع جدا اÙتاده"
@@ -1138,14 +1162,15 @@ msgid "License"
msgstr "مجوز"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "مجوز‌های شخص ثالث"
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1162,7 +1187,7 @@ msgid "Licenses"
msgstr "گواهینامه"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1179,7 +1204,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "نصب کردن"
@@ -1674,12 +1698,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "وارد کردن"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "صدور"
@@ -1751,7 +1774,7 @@ msgstr "باز شدن مدیر پروژه؟"
msgid "New Folder..."
msgstr "ساختن پوشه..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1802,7 +1825,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1828,26 +1851,31 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "زبانه قبلی"
+msgid "Go to previous folder."
+msgstr "رÙتن به پوشه والد"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "ساختن پوشه"
+msgid "Go to next folder."
+msgstr "رÙتن به پوشه والد"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "رÙتن به پوشه والد"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "جستجوی کلاسها"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "ناتوان در ساختن پوشه."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2099,6 +2127,10 @@ msgstr "پاک کردن"
msgid "Clear Output"
msgstr "خروجی"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2398,6 +2430,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "باز کردن صحنه"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2495,6 +2536,11 @@ msgstr "پخش صحنه"
msgid "Close Tab"
msgstr "بستن"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "بستن"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2550,6 +2596,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "کپی کردن"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "زبانه بعدی"
@@ -2577,6 +2628,10 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr ""
@@ -2587,14 +2642,6 @@ msgid "Save All Scenes"
msgstr "ذخیره صحنه در ..."
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2624,26 +2671,37 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "پروژه"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "ترجیحات پروژه"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ابزارها"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "صدور"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "باز شدن مدیر پروژه؟"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ابزارها"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "پوینده‌ی منبع جدا اÙتاده"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2722,12 +2780,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "ویرایشگر"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "ویرایشگر ترجیحات"
#: editor/editor_node.cpp
@@ -2744,15 +2803,6 @@ 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 "حالت تمام صÙحه"
@@ -2778,14 +2828,15 @@ msgstr "ویرایشگر ترجیحات"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "مدیریت صدور قالب ها"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "مدیریت صدور قالب ها"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "راهنما"
@@ -2793,12 +2844,13 @@ msgstr "راهنما"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "جستجو"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3078,6 +3130,11 @@ msgstr "زمان:"
msgid "Calls"
msgstr "Ùراخوانی"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "عضوها"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3243,8 +3300,9 @@ msgid "Import From Node:"
msgstr "وارد کردن از گره:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
-msgstr ""
+#, fuzzy
+msgid "Redownload"
+msgstr "در حال بارگیری"
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -3260,6 +3318,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3323,13 +3385,11 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "در حال درخواست..."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3343,13 +3403,19 @@ msgid "Download Complete."
msgstr "دانلود کامل."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "امکان حذ٠وجود ندارد :"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "خطای آدرس درخواستی: "
#: editor/export_template_manager.cpp
@@ -3438,20 +3504,12 @@ msgstr "بارگیری قالب ها"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "برگزیده‌ها:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3488,15 +3546,15 @@ msgid "Provided name contains invalid characters."
msgstr "کاراکترهای معتبر:"
#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Name contains invalid characters."
msgstr "کاراکترهای معتبر:"
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
-msgstr ""
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Renaming file:"
msgstr "تغییر متغیر"
@@ -3559,6 +3617,11 @@ msgstr "انتخاب شده را به دو تا تکثیر کن"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "صحنه جدید"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3629,6 +3692,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "ساختن گره"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3698,6 +3766,14 @@ msgid "Search complete"
msgstr "جستجوی متن"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "بارگذاری خودکار 's%' هم اکنون موجود است!"
@@ -3707,12 +3783,22 @@ msgstr "بارگذاری خودکار 's%' هم اکنون موجود است!"
msgid "Invalid group name."
msgstr "نام نامعتبر."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "تغییر نام گره"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "حذ٠گره(ها)"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3725,12 +3811,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "گشودن ویرایشگر اسکریپت"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3940,7 +4027,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4731,10 +4818,6 @@ msgid "View Files"
msgstr "نمایش پرونده ها"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4748,14 +4831,46 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "در حال درخواست..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "امکان حذ٠وجود ندارد :"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "در حال درخواست..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "زمان:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4799,6 +4914,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "نصب کردن"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4828,13 +4948,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "همه"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "وارد کردن"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4842,8 +4965,9 @@ msgid "Sort:"
msgstr "مرتب‌سازی:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "معکوس"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "در حال درخواست..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4855,7 +4979,8 @@ msgid "Site:"
msgstr "تارنما:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "پشتیبانی..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4867,6 +4992,11 @@ msgid "Testing"
msgstr "آزمودن"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "بارگیری"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Ùایل های ZIP‌ منابع بازی"
@@ -4917,34 +5047,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "برداشتن متغیر"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "ساختن راهنمای عمودی"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "برداشتن متغیر"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "کلیدهای نامعتبر را حذ٠کن"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "ساختن راهنمای اÙÙ‚ÛŒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "کلیدهای نامعتبر را حذ٠کن"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "ساختن راهنمای عمودی"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5029,6 +5164,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "پخش سÙارشی صحنه"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "پخش سÙارشی صحنه"
@@ -5059,6 +5199,7 @@ msgid "Zoom Reset"
msgstr "بزرگنمایی کمتر"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "انتخاب حالت"
@@ -5079,14 +5220,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "انتخاب حالت"
@@ -5112,6 +5256,7 @@ msgid "Toggle snapping."
msgstr "یک Breakpoint درج کن"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5128,11 +5273,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5145,6 +5285,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5361,16 +5506,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5691,14 +5826,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5783,19 +5910,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6138,7 +6269,6 @@ msgid "Grid Settings"
msgstr "ترجیحات"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6247,12 +6377,7 @@ msgstr "خطا در بارگذاری:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "نمی‌تواند یک پوشه ایجاد شود."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "نمی‌تواند یک پوشه ایجاد شود."
#: editor/plugins/script_editor_plugin.cpp
@@ -6282,7 +6407,7 @@ msgstr "خطا در بارگذاری:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "ساختن پوشه..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6369,6 +6494,11 @@ msgid "Open..."
msgstr "باز کن"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "باز کردن و اجرای یک اسکریپت"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6409,14 +6539,14 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "Close All"
msgstr "بستن"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "اجرا"
@@ -6506,6 +6636,11 @@ msgstr ""
msgid "Search Results"
msgstr "جستجوی راهنما"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "صحنه جدید"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6578,6 +6713,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6615,26 +6751,6 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "دید آزاد"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "به گام بعدی برو"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "یک Breakpoint درج کن"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "برداشتن انتخاب شده"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "برو به خط"
@@ -6655,6 +6771,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "انتخاب شده را تغییر مقیاس بده"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6673,32 +6794,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "یک Breakpoint درج کن"
+msgid "Find Previous"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "یاÙتن"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "به گام بعدی برو"
+msgid "Toggle Bookmark"
+msgstr "دید آزاد"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "یک Breakpoint درج کن"
+msgid "Go to Next Bookmark"
+msgstr "به گام بعدی برو"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "یک Breakpoint درج کن"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "یاÙتن"
+msgid "Remove All Bookmarks"
+msgstr "برداشتن انتخاب شده"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6711,9 +6837,24 @@ msgid "Go to Line..."
msgstr "برو به خط"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "یک Breakpoint درج کن"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "به گام بعدی برو"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "یک Breakpoint درج کن"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6895,7 +7036,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6954,8 +7099,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Ùرزند قابل ویرایش"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -7011,9 +7157,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "انتخاب حالت"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7023,31 +7168,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "انتخاب حالت"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7088,27 +7212,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "همه‌ی انتخاب ها"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "دید آزاد"
@@ -7163,7 +7266,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "ترجیحات"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7474,10 +7578,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7569,11 +7669,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7685,14 +7785,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7707,8 +7799,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8023,6 +8115,10 @@ msgid "TileSet"
msgstr "صدور مجموعه کاشی"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "اÙزودن نقطه"
@@ -8110,6 +8206,12 @@ msgid "Duplicate Nodes"
msgstr "تکرار کلید‌های انیمیشن"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Paste Nodes"
+msgstr "مسیر به سمت گره:"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "حذ٠گره(ها)"
@@ -8133,6 +8235,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "ساختن گره"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "ساختن گره"
@@ -8210,6 +8317,22 @@ msgid "Color uniform."
msgstr "انتقال را در انیمیشن تغییر بده"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8217,10 +8340,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8310,7 +8467,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8318,7 +8475,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8330,7 +8487,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8347,7 +8504,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8416,11 +8573,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8436,7 +8593,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8447,7 +8604,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8456,7 +8613,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8464,11 +8621,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8509,11 +8666,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8523,7 +8684,7 @@ msgstr "انتخاب شده را تغییر مقیاس بده"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8541,15 +8702,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8601,7 +8762,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8616,6 +8777,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8629,19 +8794,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8650,7 +8815,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8659,14 +8824,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8711,47 +8876,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8931,6 +9103,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "مدیریت صدور قالب ها"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "صدور با اشکال زدا"
@@ -9085,6 +9261,15 @@ msgstr "پروژه بی نام"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "وارد کردن پروژه موجود"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "ناتوان در گشودن پروژه"
@@ -9154,8 +9339,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9178,8 +9363,9 @@ msgid "Project Manager"
msgstr "مدیر پروژه"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Ùهرست پروژه ها"
+#, fuzzy
+msgid "Projects"
+msgstr "پروژه"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9203,10 +9389,6 @@ msgid "Templates"
msgstr "قالب ها"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "خروج"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "راه اندازی دوباره"
@@ -9551,6 +9733,10 @@ msgstr "بومی‌سازی‌ها:"
msgid "AutoLoad"
msgstr "بارگیری خودکار"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9606,14 +9792,6 @@ msgstr "انتخاب حالت"
msgid "Select Method"
msgstr "انتخاب حالت"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9915,6 +10093,11 @@ msgid "Remove Node(s)"
msgstr "حذ٠گره(ها)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "مقدار آرایه را تغییر بده"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9961,6 +10144,11 @@ msgid "Extend Script"
msgstr "باز کردن و اجرای یک اسکریپت"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "گره تغییر والد"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -10037,19 +10225,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10149,6 +10337,10 @@ msgid "Error loading script from %s"
msgstr "خطای بارگذاری قلم."
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10182,7 +10374,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10350,6 +10542,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "ویرایشگر ترجیحات"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10792,10 +10988,30 @@ msgid "Set Variable Type"
msgstr "متغیر را ویرایش کن:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "نام نامعتبر. نباید یا یک نام نوع توکار برخوردی داشته باشد."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "ساختن %s جدید"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "متغیرها:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "ساختن %s جدید"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "انتخاب شده را تغییر مقیاس بده"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "نام یک شناسه‌ی معتبر نیست:"
@@ -10989,11 +11205,6 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "مسیر به سمت گره:"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "عضوها"
@@ -11813,22 +12024,6 @@ msgstr ""
"تا بتواند یک اندازه بگیرد. در غیر اینصورت، آن را یک RenderTarget قرار دهید و "
"باÙت داخلی آن را برای نمایش به تعدادی گره تخصیص دهید."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "خطا در ارزش‌دهی آغازین به FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Ùرمت قلم ناشناخته."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "خطای بارگذاری قلم."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "اندازهٔ قلم نامعتبر."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11843,6 +12038,11 @@ msgstr "اندازهٔ قلم نامعتبر."
msgid "Invalid source for shader."
msgstr "اندازهٔ قلم نامعتبر."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "اندازهٔ قلم نامعتبر."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11860,6 +12060,55 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "نمی‌تواند یک پوشه ایجاد شود."
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "انتخاب حالت"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "انتخاب حالت"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "همه‌ی انتخاب ها"
+
+#~ msgid "Project List"
+#~ msgstr "Ùهرست پروژه ها"
+
+#~ msgid "Exit"
+#~ msgstr "خروج"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "خطا در ارزش‌دهی آغازین به FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Ùرمت قلم ناشناخته."
+
+#~ msgid "Error loading font."
+#~ msgstr "خطای بارگذاری قلم."
+
+#~ msgid "Invalid font size."
+#~ msgstr "اندازهٔ قلم نامعتبر."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "زبانه قبلی"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "ساختن پوشه"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "گشودن ویرایشگر متن"
+
+#~ msgid "Reverse"
+#~ msgstr "معکوس"
+
+#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "ناتوان در ساختن پوشه."
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index c62d874f1b..9905d85038 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-07-09 10:47+0000\n"
+"PO-Revision-Date: 2019-08-04 14:23+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -65,7 +65,6 @@ msgid "On call to '%s':"
msgstr "Kutsuttaessa funktiota '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Vapauta"
@@ -134,6 +133,26 @@ msgid "Anim Change Call"
msgstr "Animaatio: muuta kutsua"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animaatio: muuta monen avainruudun aikaa"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Animaatio: muuta monta siirtymää"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Animaatio: muuta monta muunnosta"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animaatio: muuta monen avainruudun arvoa"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Animaatio: muuta monta kutsua"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Muuta animaation pituutta"
@@ -452,9 +471,8 @@ msgid "Select All"
msgstr "Valitse kaikki"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Valitse solmu"
+msgstr "Tyhjennä valinta"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -631,16 +649,18 @@ msgid "Line Number:"
msgstr "Rivinumero:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Korvattu %d osuvuutta."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Ei osumia"
+#, fuzzy
+msgid "%d match."
+msgstr "Löydettiin %d osuma(a)."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Korvattu %d osuvuutta."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Löydettiin %d osuma(a)."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -789,9 +809,8 @@ msgid "Connect"
msgstr "Yhdistä"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Signaalit:"
+msgstr "Signaali:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -867,8 +886,7 @@ msgstr "Suosikit:"
msgid "Recent:"
msgstr "Viimeaikaiset:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -956,9 +974,8 @@ msgid "Owners Of:"
msgstr "Omistajat kohteelle:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Poista valitut tiedostot projektista? (ei voi kumota)"
+msgstr "Poista valitut tiedostot projektista? (Ei voida palauttaa)"
#: editor/dependency_editor.cpp
msgid ""
@@ -970,7 +987,7 @@ msgstr ""
"toimivuuteen.\n"
"Poistetaanko silti? (ei mahdollisuutta kumota)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Ei voida poistaa:"
@@ -1006,7 +1023,7 @@ msgstr "Poista pysyvästi %d kohdetta? (Ei voi kumota!)"
msgid "Show Dependencies"
msgstr "Näytä riippuvuudet"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Irrallisten resurssien hallinta"
@@ -1095,14 +1112,16 @@ msgid "License"
msgstr "Lisenssi"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Kolmannen osapuolen lisenssi"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot moottori käyttää useita kolmannen osapuolen ilmaisia ja avoimia "
@@ -1123,7 +1142,8 @@ msgid "Licenses"
msgstr "Lisenssit"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Virhe avattaessa pakettitiedostoa, ei zip-muodossa."
#: editor/editor_asset_installer.cpp
@@ -1140,7 +1160,6 @@ msgid "Success!"
msgstr "Onnistui!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Asenna"
@@ -1328,7 +1347,6 @@ msgid "Must not collide with an existing engine class name."
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 built-in type name."
msgstr ""
"Ei saa mennä päällekkäin olemassa olevan sisäänrakennetun tyypin nimen "
@@ -1513,6 +1531,7 @@ msgstr "Mallitiedostoa ei löytynyt:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"32-bittisissä vienneissä sisällytetty PCK ei voi olla suurempi kuin 4 Gt."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1539,9 +1558,8 @@ msgid "Node Dock"
msgstr "Solmutelakka"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "Tiedostojärjestelmätelakka"
+msgstr "Tiedostojärjestelmä- ja tuontitelakat"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1594,7 +1612,6 @@ msgid "File '%s' format is invalid, import aborted."
msgstr "Tiedoston '%s' tiedostomuoto on virheellinen, tuonti keskeytetty."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
@@ -1611,9 +1628,8 @@ msgid "Unset"
msgstr "Poista asetus"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Nykyinen profiili"
+msgstr "Nykyinen profiili:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1625,19 +1641,17 @@ msgid "New"
msgstr "Uusi"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Tuo"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Vie"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Saatavilla olevat profiilit"
+msgstr "Saatavilla olevat profiilit:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1692,7 +1706,7 @@ msgstr "Näytä tiedostonhallinnassa"
msgid "New Folder..."
msgstr "Uusi kansio..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Päivitä"
@@ -1743,7 +1757,7 @@ msgstr "Mene eteenpäin"
msgid "Go Up"
msgstr "Mene ylös"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Näytä piilotiedostot"
@@ -1768,23 +1782,27 @@ msgid "Move Favorite Down"
msgstr "Siirrä suosikkia alas"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Edellinen kansio"
+msgid "Go to previous folder."
+msgstr "Siirry edelliseen kansioon."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Seuraava kansio"
+msgid "Go to next folder."
+msgstr "Siirry seuraavaan kansioon."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Siirry yläkansioon."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Lataa uudelleen tiedostot."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Kansio suosikkeihin."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Aseta piilotiedostojen näyttäminen."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2025,6 +2043,11 @@ msgstr "Tyhjennä"
msgid "Clear Output"
msgstr "Tyhjennä tuloste"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Ikkuna"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Projektin vienti epäonnistui virhekoodilla %d."
@@ -2347,6 +2370,15 @@ msgid "Pick a Main Scene"
msgstr "Valitse pääskene"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Sulje skene"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Sulje skene"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "Lisäosan '%s' aktivointi epäonnistui, virheellinen asetustiedosto."
@@ -2453,6 +2485,11 @@ msgstr "Pelaa tätä skeneä"
msgid "Close Tab"
msgstr "Sulje välilehti"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Sulje välilehti"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Sulje muut välilehdet"
@@ -2506,6 +2543,10 @@ msgid "Go to previously opened scene."
msgstr "Mene aiemmin avattuun skeneen."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Kopioi teksti"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Seuraava välilehti"
@@ -2533,6 +2574,10 @@ msgstr "Uusi peritty skene..."
msgid "Open Scene..."
msgstr "Avaa skene..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Avaa viimeaikainen"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Tallenna skene"
@@ -2542,14 +2587,6 @@ msgid "Save All Scenes"
msgstr "Tallenna kaikki skenet"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Sulje skene"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Avaa viimeaikainen"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Muunna..."
@@ -2579,25 +2616,37 @@ msgstr "Palauta skene"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Sekalaiset projekti- tai skenetyökalut."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekti"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projektin asetukset"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Työkalut"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Vie"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Asenna Androidin käännösmalli"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Avaa projektin datakansio"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Työkalut"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Asenna Androidin käännösmalli"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Irrallisten resurssien hallinta"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2694,12 +2743,13 @@ msgstr ""
"käynnistyessä.\n"
"Mikäli peliä ajetaan etälaitteella, on tehokkaampaa käyttää verkkolevyä."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editori"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Editorin asetukset"
#: editor/editor_node.cpp
@@ -2707,32 +2757,20 @@ msgid "Editor Layout"
msgstr "Editorin ulkoasu"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Tee skenen juuri"
+msgstr "Ota kuvakaappaus"
#: 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"
+msgstr "Kuvakaappaukset tallennetaan editorin data/asetuskansioon."
#: 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"
+msgstr "Aseta järjestelmäkonsolin näkyvyys päälle/pois"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2747,14 +2785,16 @@ msgid "Open Editor Settings Folder"
msgstr "Avaa editorin asetuskansio"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Hallinnoi editorin ominaisuuksia"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Hallinnoi vientimalleja"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ohje"
@@ -2762,12 +2802,13 @@ msgstr "Ohje"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Hae"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentaatio"
@@ -2841,19 +2882,16 @@ msgid "Spins when the editor window redraws."
msgstr "Pyörii kun editorin ikkuna päivittyy."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Jatkuva"
+msgstr "Päivitä jatkuvasti"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Päivitä muutokset"
+msgstr "Päivitä kun muuttuu"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Poista päivitysanimaatio"
+msgstr "Piilota päivitysanimaatio"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -3048,6 +3086,10 @@ msgstr "Aika"
msgid "Calls"
msgstr "Kutsuja"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Muokkaa tekstiä:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Päällä"
@@ -3220,7 +3262,8 @@ msgid "Import From Node:"
msgstr "Tuo solmusta:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Lataa uudelleen"
#: editor/export_template_manager.cpp
@@ -3237,6 +3280,10 @@ msgid "Download"
msgstr "Lataa"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Puuttuva)"
@@ -3300,12 +3347,10 @@ msgid "No response."
msgstr "Ei vastausta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Pyyntö epäonnistui."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Loputon uudelleenohjaus."
@@ -3319,15 +3364,22 @@ msgid "Download Complete."
msgstr "Lataus valmis."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Teemaa ei voi tallentaa tiedostoon:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Vientimallien asennus epäonnistui. Ongelmallisten vientimallien arkisto "
"löytyy kohteesta '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Virhe pyydettäessä osoitetta: "
#: editor/export_template_manager.cpp
@@ -3412,23 +3464,11 @@ msgstr "Lataa mallit"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Valitse peilipalvelin listasta: (Shift+napsautus: Avaa selaimessa)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Tiedostoa file_type_cache.cch ei voitu avata kirjoittamista varten. "
-"Välimuistia ei tallenneta!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Suosikit"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Tiedostoa '%s' ei voida avata, koska sitä ei näytä löytyvän "
-"tiedostojärjestelmästäsi!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Tila: Tuonti epäonnistui. Ole hyvä, korjaa tiedosto ja tuo se uudelleen."
@@ -3462,14 +3502,14 @@ msgid "Provided name contains invalid characters."
msgstr "Annettu nimi sisältää virheellisiä kirjainmerkkejä."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Nimi sisältää virheellisiä kirjainmerkkejä."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Tällä nimellä löytyy jo kansio tai tiedosto."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Nimi sisältää virheellisiä kirjainmerkkejä."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Nimetään tiedosto uudelleen:"
@@ -3525,6 +3565,11 @@ msgstr "Kahdenna..."
msgid "Move To..."
msgstr "Siirrä..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Uusi skene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Uusi skripti..."
@@ -3590,6 +3635,11 @@ msgstr "Tästä sijainnista löytyy jo samanniminen tiedosto tai kansio."
msgid "Overwrite"
msgstr "Ylikirjoita"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Luo skenestä"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Luo skripti"
@@ -3652,6 +3702,14 @@ msgid "Search complete"
msgstr "Haku valmis"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Lisää ryhmään"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Poista ryhmästä"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Ryhmän nimi on jo olemassa."
@@ -3659,12 +3717,23 @@ msgstr "Ryhmän nimi on jo olemassa."
msgid "Invalid group name."
msgstr "Virheellinen ryhmän nimi."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Hallinnoi ryhmiä"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Poista asettelu"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Ryhmät"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Ryhmään kuulumattomat solmut"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3677,12 +3746,13 @@ msgid "Nodes in Group"
msgstr "Ryhmään kuuluvat solmut"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Lisää ryhmään"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Poista ryhmästä"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Skriptieditori"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3893,7 +3963,8 @@ msgid "MultiNode Set"
msgstr "Aseta usealle solmulle"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Valitse solmu, jonka signaaleja ja ryhmiä haluat muokata."
#: editor/plugin_config_dialog.cpp
@@ -4652,10 +4723,6 @@ msgid "View Files"
msgstr "Näytä tiedostot"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Palvelinta ei löytynyt:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Yhteysvirhe, ole hyvä ja yritä uudelleen."
@@ -4668,14 +4735,47 @@ msgid "No response from host:"
msgstr "Ei vastausta isännältä:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Palvelinta ei löytynyt:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Pyyntö epäonnistui, virhekoodi:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Pyyntö epäonnistui."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Teemaa ei voi tallentaa tiedostoon:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Pyyntö epäonnistui, liikaa uudelleenohjauksia"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Loputon uudelleenohjaus."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Pyyntö epäonnistui, virhekoodi:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Aika"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
"Latauksessa väärä hajautuskoodi, oletetaan että tiedostoa on näpelöity."
@@ -4717,6 +4817,10 @@ msgid "Idle"
msgstr "Toimeton"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Asenna..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Yritä uudelleen"
@@ -4745,13 +4849,17 @@ msgid "Last"
msgstr "Viimeinen"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Kaikki"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Tuo uudelleen..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Liitännäiset"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4759,8 +4867,8 @@ msgid "Sort:"
msgstr "Lajittele:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Käänteinen"
+msgid "Reverse sorting."
+msgstr "Käännä lajittelu."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4772,7 +4880,8 @@ msgid "Site:"
msgstr "Sivu:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Tuki..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4784,6 +4893,11 @@ msgid "Testing"
msgstr "Testaus"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Lataa..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Assettien zip-tiedosto"
@@ -4841,32 +4955,32 @@ msgid "Rotation Step:"
msgstr "Kierron välistys:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr "Siirrä pystysuoraa apuviivaa"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Luo uusi pystysuora apuviiva"
+msgid "Create Vertical Guide"
+msgstr "Luo pystysuora apuviiva"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Poista pystysuora apuviiva"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "Siirrä vaakasuoraa apuviivaa"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Luo uusi vaakasuora apuviiva"
+msgid "Create Horizontal Guide"
+msgstr "Luo vaakasuora apuviiva"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Poista vaakasuora apuviiva"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Luo uudet vaaka- ja pystysuorat apuviivat"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Luo vaaka- ja pystysuorat apuviivat"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4949,6 +5063,11 @@ msgid "Paste Pose"
msgstr "Liitä asento"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Poista luut"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Luo mukautetut luut solmuista"
@@ -4979,6 +5098,7 @@ msgid "Zoom Reset"
msgstr "Palauta oletuslähennystaso"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Valitse tila"
@@ -5001,14 +5121,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + Hiiren oikea painike: Syvyyslistan valinta"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Siirtotila"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Kääntötila"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Skaalaustila"
@@ -5034,6 +5157,7 @@ msgid "Toggle snapping."
msgstr "Aseta tarttuminen."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Käytä tarttumista"
@@ -5050,11 +5174,6 @@ msgid "Use Rotation Snap"
msgstr "Tartu käännettäessä"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Määrittele tarttuminen..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Suhteellinen tarttuminen"
@@ -5067,6 +5186,11 @@ msgid "Smart Snapping"
msgstr "Älykäs tarttuminen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Määrittele tarttuminen..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Tartu isäntään"
@@ -5281,16 +5405,6 @@ msgstr "Aseta kahva"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Virhe ladattaessa kuvaa:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Kuvassa ei ole pikseleitä, joiden läpinäkyvyys on enemmän kuin 128…"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Lataa emissiomaski"
@@ -5298,9 +5412,8 @@ msgstr "Lataa emissiomaski"
#: 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"
+msgstr "Käynnistä uudelleen"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5321,7 +5434,7 @@ msgstr "Luotujen pisteiden määrä:"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Mask"
-msgstr "Emission maski"
+msgstr "Emissiomaski"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5331,7 +5444,7 @@ msgstr "Nappaa pikselistä"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Colors"
-msgstr "Emission väri"
+msgstr "Emissiovärit"
#: editor/plugins/cpu_particles_editor_plugin.cpp
msgid "CPUParticles"
@@ -5604,14 +5717,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Pinnan lähde on virheellinen (tahkot puuttuvat)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Lähteellä ei ole kiinteitä tahkoja täytettäväksi."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Aluetta ei voitu kartoittaa."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Valitse lähdemesh:"
@@ -5696,20 +5801,27 @@ msgid "Generation Time (sec):"
msgstr "Luontiaika (s):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Pinnat eivät sisällä aluetta!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Solmulta puuttuu geometria (tahkot)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Ei pintoja!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Solmu ei sisällä geometriaa."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Solmulta puuttuu geometria (tahkot)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Solmu ei sisällä geometriaa."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6042,7 +6154,6 @@ msgid "Grid Settings"
msgstr "Ruudukon asetukset"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Tartu"
@@ -6148,12 +6259,9 @@ msgid "Error writing TextFile:"
msgstr "Virhe kirjoitettaessa teksitiedostoa:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Virhe: ei voitu ladata tiedostoa."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Virhe - Ei voitu ladata tiedostoa."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Ruutua ei löytynyt:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6176,7 +6284,8 @@ msgid "Error Importing"
msgstr "Virhe tuonnissa"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Uusi tekstitiedosto..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6213,18 +6322,16 @@ msgid "Find Next"
msgstr "Etsi seuraava"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Suodata ominaisuuksia"
+msgstr "Suodata skriptejä"
#: 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:"
+msgstr "Suodata metodeja"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6259,6 +6366,11 @@ msgid "Open..."
msgstr "Avaa..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Avaa skripti"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Tallenna kaikki"
@@ -6296,13 +6408,13 @@ msgid "Save Theme"
msgstr "Tallenna teema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Sulje dokumentaatio"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Sulje kaikki"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Sulje dokumentaatio"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Suorita"
@@ -6390,6 +6502,11 @@ msgstr "Debuggeri"
msgid "Search Results"
msgstr "Haun tulokset"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Tyhjennä viimeisimmät skenet"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Yhteydet metodiin:"
@@ -6457,8 +6574,9 @@ msgid "Syntax Highlighter"
msgstr "Syntaksin korostaja"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Mene"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6466,9 +6584,8 @@ msgid "Bookmarks"
msgstr "Kirjanmerkit"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Luo pisteitä."
+msgstr "Keskeytyskohdat"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6492,22 +6609,6 @@ msgid "Toggle Comment"
msgstr "Lisää tai poista kommentit"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Aseta kirjanmerkki"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Mene seuraavaan kirjanmerkkiin"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Mene edelliseen kirjanmerkkiin"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Poista kaikki kirjanmerkit"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Laskosta tai avaa rivi"
@@ -6528,6 +6629,11 @@ msgid "Complete Symbol"
msgstr "Täydennä symboli"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skaalaa valintaa"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Poista välilyönnit lopusta"
@@ -6544,29 +6650,32 @@ msgid "Auto Indent"
msgstr "Automaattinen sisennys"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Aseta tai poista keskeytyskohta"
+msgid "Find Previous"
+msgstr "Etsi edellinen"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Poista kaikki keskeytyskohdat"
+msgid "Find in Files..."
+msgstr "Etsi tiedostoista..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Mene seuraavaan keskeytyskohtaan"
+msgid "Contextual Help"
+msgstr "Asiayhteydellinen ohje"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Mene edelliseen keskeytyskohtaan"
+msgid "Toggle Bookmark"
+msgstr "Aseta kirjanmerkki"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Etsi edellinen"
+msgid "Go to Next Bookmark"
+msgstr "Mene seuraavaan kirjanmerkkiin"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Etsi tiedostoista..."
+msgid "Go to Previous Bookmark"
+msgstr "Mene edelliseen kirjanmerkkiin"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Poista kaikki kirjanmerkit"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6577,8 +6686,21 @@ msgid "Go to Line..."
msgstr "Mene riville..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Asiayhteydellinen ohje"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Aseta tai poista keskeytyskohta"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Poista kaikki keskeytyskohdat"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Mene seuraavaan keskeytyskohtaan"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Mene edelliseen keskeytyskohtaan"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6757,8 +6879,12 @@ msgid "Rear"
msgstr "Taka"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Kohdista näkymään"
+msgid "Align Transform with View"
+msgstr "Kohdista muunnos näkymään"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Kohdista kierto näkymään"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6813,8 +6939,9 @@ msgid "Audio Listener"
msgstr "Äänikuuntelija"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Doppler käytössä"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Kytke suodatus"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6869,8 +6996,8 @@ msgid "Snap Nodes To Floor"
msgstr "Tarraa solmut lattiaan"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Valintatila (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6883,30 +7010,11 @@ msgstr ""
"Alt + Hiiren oikea painike: Syvyyslistan valinta"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Siirtotila (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Kääntötila (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Skaalaustila (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Paikalliset koordinaatit"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Paikallisavaruuden tila (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Tarttumisen tila (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Alanäkymä"
@@ -6947,26 +7055,6 @@ msgid "Focus Selection"
msgstr "Kohdista valintaan"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Kohdista valinta näkymään"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Valintatyökalu"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Siirtotyökalu"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Kiertotyökalu"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Skaalaustyökalu"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Kytke liikkuminen päälle/pois"
@@ -7021,7 +7109,8 @@ msgstr "Näytä ruudukko"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Asetukset"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7314,10 +7403,6 @@ msgid "TextureRegion"
msgstr "Tekstuurialue"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Teemaa ei voi tallentaa tiedostoon:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Lisää kaikki"
@@ -7402,11 +7487,13 @@ msgid "Submenu"
msgstr "Alivalikko"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Osanen 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Osanen 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7511,14 +7598,6 @@ msgid "Transpose"
msgstr "Transponoi"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Peilaa X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Peilaa Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Poista automaattiruudutus käytöstä"
@@ -7531,9 +7610,10 @@ msgid "Paint Tile"
msgstr "Maalaa ruutu"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+Hiiren oikea: Piirrä viiva\n"
"Shift+Ctrl+Hiiren oikea: Suorakaidemaalaus"
@@ -7830,6 +7910,10 @@ msgid "TileSet"
msgstr "Ruutuvalikoima"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Vain GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Lisää tulo +"
@@ -7895,7 +7979,7 @@ msgstr "Aseta uniformin nimi"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Input Default Port"
-msgstr "Aseta syötteen oletusportti"
+msgstr "Aseta oletustuloportti"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node to Visual Shader"
@@ -7906,6 +7990,11 @@ msgid "Duplicate Nodes"
msgstr "Kahdenna solmut"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Liitä solmut"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Poista solmut"
@@ -7926,6 +8015,11 @@ msgid "Light"
msgstr "Valo"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Luo Shader solmu"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Luo Shader solmu"
@@ -7970,9 +8064,8 @@ msgid "Dodge operator."
msgstr "Värinväistöoperaattori."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "HardLight operator"
-msgstr "HardLight-operaattori."
+msgstr "Kovavalo-operaattori"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
@@ -7999,64 +8092,109 @@ msgid "Color uniform."
msgstr "Väri-uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Palauttaa kahden parametrin %s vertailun totuusarvon."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Yhtä suuri (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Suurempi kuin (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Yhtä suuri tai suurempi kuin (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
msgstr ""
+"Palauttaa liitetyn vektorin, jos annetut skalaarit ovat yhtä suuria, "
+"suurempia tai pienempiä."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "Palauttaa INF ja skalaarin parametrien vertailun totuusarvon."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr "Palauttaa NaN- ja skalaariparametrien vertailun totuusarvon."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Pienempi kuin (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Yhtä suuri tai pienempi kuin (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Erisuuri (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
+"Palauttaa liitetyn vektorin, jos annettu totuusarvo on tosi tai epätosi."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Palauttaa kahden parametrin vertailun totuusarvon."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Palauttaa INF- (tai NaN-) ja skalaariparametrien vertailun totuusarvon."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Boolean constant."
-msgstr "Muuta vektorivakiota"
+msgstr "Totuusarvovakio."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "Totuusarvo-uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for all shader modes."
-msgstr "'normal' syöteparametri valosävytintilaan."
+msgstr "'%s' syöteparametri kaikille sävytintiloille."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Tartu isäntään"
+msgstr "Syöteparametri."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr "'custom' syöteparametri kärkipistesävytintilaan."
+msgstr "'%s' syöteparametri kärkipiste- ja kuvapistesävytintiloille."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr "'normal' syöteparametri valosävytintilaan."
+msgstr "'%s' syöteparametri kuvapiste- ja valosävytintiloille."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for fragment shader mode."
-msgstr "'custom' syöteparametri kärkipistesävytintilaan."
+msgstr "'%s' syöteparametri kuvapistesävytintilaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for light shader mode."
-msgstr "'normal' syöteparametri valosävytintilaan."
+msgstr "'%s' syöteparametri valosävytintilaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex shader mode."
-msgstr "'custom' syöteparametri kärkipistesävytintilaan."
+msgstr "'%s' syöteparametri kärkipistesävytintilaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr "'custom' syöteparametri kärkipistesävytintilaan."
+msgstr "'%s' syöteparametri kärkipiste- ja kuvapistesävytintilaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar function."
@@ -8100,23 +8238,23 @@ msgstr "Sqrt2-vakio (1.414214). Kahden neliöjuuri."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr "Palauttaa parametrin absoluuttisen arvon."
+msgstr "Palauttaa parametrin itseisarvon."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
msgstr "Palauttaa parametrin arkuskosinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen kosinin."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Palauttaa parametrin käänteisen hyperbolisen kosinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "Palauttaa parametrin arkussinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen sinin."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Palauttaa parametrin käänteisen hyperbolisen sinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8127,8 +8265,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "Palauttaa parametrien arkustangentin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen tangentin."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Palauttaa parametrin käänteisen hyperbolisen tangentin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8145,8 +8283,8 @@ msgid "Returns the cosine of the parameter."
msgstr "Palauttaa parametrin kosinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(Vain GLES3) Palauttaa parametrin hyperbolisen kosinin."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Palauttaa parametrin hyperbolisen kosinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8217,12 +8355,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / skalaari"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Vain GLES3) Etsii parametria lähinnä olevan kokonaisluvun."
+msgid "Finds the nearest integer to the parameter."
+msgstr "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 "(Vain GLES3) Etsii parametria lähinnä olevan parillisen kokonaisluvun."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Etsii parametria lähinnä olevan parillisen kokonaisluvun."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -8237,97 +8375,106 @@ msgid "Returns the sine of the parameter."
msgstr "Palauttaa parametrin sinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(Vain GLES3) Palauttaa parametrin hyperbolisen sinin."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Palauttaa parametrin hyperbolisen sinin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Palauttaa parametrin neliöjuuren."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep-funktio( skalaari(edge0), skalaari(edge1), skalaari(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge0', ja 1.0, jos 'x' on suurempi "
+"kuin 'edge1'. Muutoin paluuarvo interpoloidaan 0.0 ja 1.0 väliltä Hermiten "
+"polynomeilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge', ja muuten 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "Palauttaa parametrin tangentin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Palauttaa parametrin hyperbolisen tangentin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr ""
+msgid "Finds the truncated value of the parameter."
+msgstr "Hakee parametrin katkaistun arvon."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Lisää skalaarin skalaariin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "Jakaa skalaarin skalaarilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "Kertoo skalaarin skalaarilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "Palauttaa kahden skalaarin jäännöksen."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "Vähentää skalaarin skalaarista."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar constant."
-msgstr "Muuta skalaarivakiota"
+msgstr "Skalaarivakio."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Muuta skalaariuniformia"
+msgstr "Skalaariuniformi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "Suorittaa kuutiollisen tekstuurin haun."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "Suorittaa tekstuurin haun."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "Cubic texture uniform."
-msgstr "Muuta tekstuuriuniformia"
+msgid "Cubic texture uniform lookup."
+msgstr "Kuutiollisen tekstuuriuniformin haku."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "2D texture uniform."
-msgstr "Muuta tekstuuriuniformia"
+msgid "2D texture uniform lookup."
+msgstr "2D-tekstuuriuniformin haku."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "2D-tekstuuriuniformin haku kolmitasolla."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Muunnosikkuna..."
+msgstr "Muunnosfunktio."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8335,174 +8482,206 @@ 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 ""
+"Laskee vektoriparin ulkotulon.\n"
+"\n"
+"Ulkotulo ottaa ensimmäisen parametrin 'c' sarakevektorina (matriisi, jolla "
+"on yksi sarake) ja toisen parametrin 'r' rivivektorina (matriisi, jolla on "
+"yksi rivi) ja suorittaa lineaarialgebrallisen matriisitulon 'c * r', antaen "
+"tulokseksi matriisin, jolla on 'c' vektorin komponenttien verran rivejä ja "
+"'r' vektorin komponenttien verran sarakkeita."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
-msgstr ""
+msgstr "Muodostaa muunnoksen neljästä vektorista."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Hajoittaa muunnoksen neljään vektoriin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr ""
+msgid "Calculates the determinant of a transform."
+msgstr "Laskee muunnoksen determinantin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Laskee muunnoksen käänteismatriisin."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Laskee muunnoksen transpoosin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Kertoo muunnoksen muunnoksella."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Kertoo vektorin muunnoksella."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Muunnos keskeytetty."
+msgstr "Muunnosvakio."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Muunnos keskeytetty."
+msgstr "Muunnosuniformi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Sijoitus funktiolle."
+msgstr "Vektorifunktio."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector operator."
-msgstr "Muuta vektorioperaattoria"
+msgstr "Vektorioperaattori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "Koostaa vektorin kolmesta skalaarista."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "Purkaa vektorin kolmeksi skalaariksi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "Laskee kahden vektorin ristitulon."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "Palauttaa kahden pisteen välisen etäisyyden."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "Laskee kahden vektorin pistetulon."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Palauttaa vektorin, joka osoittaa samaan suuntaan kuin viitevektori. Funktio "
+"ottaa kolme vektoriparametria: N eli suunnattava vektori, I eli tulovektori, "
+"ja Nref eli viitevektori. Jos I ja Nref pistetulo on pienempi kuin nolla, "
+"paluuarvo on N. Muutoin palautetaan -N."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "Laskee vektorin pituuden."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "Kahden vektorin välinen lineaari-interpolaatio."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Kahden vektorin välinen lineaari-interpolaatio."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
-msgstr ""
+msgstr "Laskee ja palauttaa vektorin normaalin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - vector"
-msgstr ""
+msgstr "1.0 - vektori"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / vector"
-msgstr ""
+msgstr "1.0 / vektori"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Palauttaa vektorin, joka osoittaa heijastuksen suuntaan ( a : tulovektori, "
+"b : normaalivektori )."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
-msgstr ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Palauttaa vektorin, joka osoittaa taittumisen suuntaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep-funktio( vektori(edge0), vektori(edge1), vektori(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge0', ja 1.0, jos 'x' on suurempi "
+"kuin 'edge1'. Muutoin paluuarvo interpoloidaan 0.0 ja 1.0 väliltä Hermiten "
+"polynomeilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep-funktio( skalaari(edge0), skalaari(edge1), vektori(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge0', ja 1.0, jos 'x' on suurempi "
+"kuin 'edge1'. Muutoin paluuarvo interpoloidaan 0.0 ja 1.0 väliltä Hermiten "
+"polynomeilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Askelfunktio( vektori(edge), vektori(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge', ja muutoin 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Askelfunktio( skalaari(edge), vektori(x) ).\n"
+"\n"
+"Palauttaa 0.0, jos 'x' on pienempi kuin 'edge', ja muutoin 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "Lisää vektorin vektoriin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "Jakaa vektorin vektorilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "Kertoo vektorin vektorilla."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two vectors."
-msgstr ""
+msgstr "Palauttaa kahden vektorin jäännöksen."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts vector from vector."
-msgstr ""
+msgstr "Vähentää vektorin vektorista."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector constant."
-msgstr "Muuta vektorivakiota"
+msgstr "Vektorivakio."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "Sijoitus uniformille."
+msgstr "Vektoriuniformi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8510,56 +8689,80 @@ 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 ""
+"Mukautettu Godot Shader Language lauseke, jolla on haluttu määrä tulo- ja "
+"lähtöportteja. Tämä tarkoittaa koodin lisäämistä suoraan vertex/fragment/"
+"light funktioiden sisään, älä käytä sitä kirjoittaaksesi funktioesittelyitä."
#: 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 ""
+"Palauttaa valovähentymän perustuen pinnan normaalivektorin ja kameran "
+"suuntavektorin pistetuloon (välitä nämä syötteinä)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Vain Fragment/Light tilat) Skalaariderivaattafunktio."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Vain Fragment/Light tilat) Vektoriderivaattafunktio."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Vain Fragment/Light tilat) (Vektori) 'x' derivaatta käyttäen "
+"paikallisdifferentiaalia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Vain Fragment/Light tilat) (Skalaari) 'x' derivaatta käyttäen "
+"paikallisdifferentiaalia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Vain Fragment/Light tilat) (Vektori) 'y' derivaatta käyttäen "
+"paikallisdifferentiaalia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Vain Fragment/Light tilat) (Skalaari) 'y' derivaatta käyttäen "
+"paikallisdifferentiaalia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Vain Fragment/Light tilat) (Vektori) 'x' ja 'y' derivaattojen itseisarvojen "
+"summa."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Vain Fragment/Light tilat) (Skalaari) 'x' ja 'y' derivaattojen "
+"itseisarvojen summa."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8734,6 +8937,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Tälle alustalle ei löytynyt vientipohjia:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Hallinnoi vientimalleja"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Vie debugaten"
@@ -8893,6 +9100,15 @@ msgid "Unnamed Project"
msgstr "Nimetön projekti"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Tuo olemassaoleva projekti"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Ei voida avata projektia kohteesta '%s'."
@@ -8901,7 +9117,6 @@ msgid "Are you sure to open more than one project?"
msgstr "Haluatko varmasti avata useamman kuin yhden projektin?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"The following project settings file does not specify the version of Godot "
"through which it was created.\n"
@@ -8918,12 +9133,11 @@ msgstr ""
"\n"
"%s\n"
"\n"
-"Jos haluat jatkaa sen avaamista, se muunnetaan nykyiseen Godotin "
+"Jos jatkat sen avaamista, se muunnetaan nykyiseen Godotin "
"asetustiedostomuotoon.\n"
"Varoitus: et voi avata projektia tämän jälkeen enää vanhemmilla versioilla."
#: 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"
@@ -8951,7 +9165,6 @@ msgstr ""
"yhteensopivia tämän version kanssa."
#: 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 "
@@ -8970,55 +9183,59 @@ msgstr ""
"Muokkaa projektia käynnistääksesi uudelleentuonnin."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "Haluatko varmasti suorittaa usemman projektin?"
+msgstr "Haluatko varmasti suorittaa %d projektia yhdenaikaisesti?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
-msgstr "Poista projekti listalta? (Kansion sisältöä ei muuteta)"
+msgstr ""
+"Poista %d projektia listalta?\n"
+"Projektikansioiden sisältöjä ei muuteta."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
-msgstr "Poista projekti listalta? (Kansion sisältöä ei muuteta)"
+msgstr ""
+"Poista tämä projekti listalta?\n"
+"Projektikansion sisältöä ei muuteta."
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
-msgstr "Poista projekti listalta? (Kansion sisältöä ei muuteta)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+"Poista %d projektia listalta?\n"
+"Projektikansioiden sisältöjä ei muuteta."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
"Kieli vaihdettu.\n"
-"Muutokset astuvat voimaan kun editori tai projektinhallinta käynnistetään "
+"Käyttöliittymä päivittyy, kun editori tai projektinhallinta käynnistetään "
"uudelleen."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
-msgstr "Olet aikeissa etsiä hakemistosta %s Godot projekteja. Oletko varma?"
+msgstr ""
+"Haluatko varmasti etsiä %s kansiosta olemassa olevia Godot-projekteja?\n"
+"Tämä saattaa kestää hetken."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Projektinhallinta"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Projektiluettelo"
+#, fuzzy
+msgid "Projects"
+msgstr "Projekti"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9033,19 +9250,14 @@ msgid "New Project"
msgstr "Uusi projekti"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Poista piste"
+msgstr "Poista puuttuva"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "Mallit"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Poistu"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Käynnistä uudelleen nyt"
@@ -9054,13 +9266,12 @@ msgid "Can't run project"
msgstr "Projektia ei voida käynnistää"
#: 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 ""
"Sinulla ei ole tällä hetkellä yhtään projekteja.\n"
-"Haluaisitko selata virallisia malliprojekteja Asset-kirjastosta?"
+"Haluaisitko selata virallisia esimerkkiprojekteja Asset-kirjastosta?"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9087,9 +9298,8 @@ msgstr ""
"'/', ':', '=', '\\' tai '\"'"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "Tapahtuma '%s' on jo olemassa!"
+msgstr "Toiminto nimellä '%s' on jo olemassa."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -9308,9 +9518,8 @@ msgid "Override For..."
msgstr "Ohita alustalle..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-#, fuzzy
msgid "The editor must be restarted for changes to take effect."
-msgstr "Editori täytyy käynnistää uudelleen, jotta muutokset tulevat voimaan"
+msgstr "Editori täytyy käynnistää uudelleen, jotta muutokset tulevat voimaan."
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -9369,14 +9578,12 @@ msgid "Locales Filter"
msgstr "Kielten suodatus"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "Näytä kaikki kielet"
+msgstr "Näytä kaikki kielialueet"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "Näytä vain valitut kielet"
+msgstr "Näytä vain valitut kielialueet"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
@@ -9390,6 +9597,10 @@ msgstr "Kielet:"
msgid "AutoLoad"
msgstr "Automaattilataus"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Liitännäiset"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Nolla"
@@ -9442,14 +9653,6 @@ msgstr "Valitse virtuaalinen metodi"
msgid "Select Method"
msgstr "Valitse metodi"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "PVRTC-työkalun suoritus ei onnistunut:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "Muunnettua kuva ei voitu ladata takaisin PVRTC-työkalulla:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Niputettu uudelleennimeäminen"
@@ -9463,7 +9666,6 @@ msgid "Suffix"
msgstr "Pääte"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
msgstr "Edistyneet asetukset"
@@ -9728,9 +9930,8 @@ msgid "User Interface"
msgstr "Käyttöliittymä"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "Poista solmu"
+msgstr "Toinen solmu"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -9749,6 +9950,11 @@ msgid "Remove Node(s)"
msgstr "Poista solmu(t)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Vaihda lähtöportin nimi"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9773,7 +9979,6 @@ msgid "Clear Inheritance"
msgstr "Poista perintä"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "Avaa dokumentaatio"
@@ -9782,9 +9987,8 @@ msgid "Add Child Node"
msgstr "Lisää alisolmu"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Tiivistä kaikki"
+msgstr "Laajenna/tiivistä kaikki"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -9795,6 +9999,10 @@ msgid "Extend Script"
msgstr "Laajenna skriptiä"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Vaihda solmulle uusi isäntä"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Tee skenen juuri"
@@ -9815,9 +10023,8 @@ msgid "Delete (No Confirm)"
msgstr "Poista (ei varmistusta)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Lisää/Luo uusi solmu"
+msgstr "Lisää/Luo uusi solmu."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -9852,52 +10059,51 @@ msgid "Toggle Visible"
msgstr "Aseta näkyvyys"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "Valitse solmu"
+msgstr "Poista solmun lukitus"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Button Group"
-msgstr "Painike 7"
+msgstr "Painikeryhmä"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "Yhteysvirhe"
+msgstr "(Yhdistetään paikasta)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
msgstr "Solmun konfiguroinnin varoitus:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Solmulla on yhteyksiä ja ryhmiä.\n"
"Napsauta näyttääksesi signaalitelakan."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Solmulla on liitäntöjä.\n"
"Napsauta näyttääksesi signaalitelakan."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Solmu kuuluu ryhmään.\n"
"Napsauta näyttääksesi ryhmätelakan."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Avaa skripti"
+msgstr "Avaa skripti:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -9948,39 +10154,32 @@ msgid "Select a Node"
msgstr "Valitse solmu"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "Polku on tyhjä"
+msgstr "Polku on tyhjä."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Tiedostonimi on tyhjä"
+msgstr "Tiedostonimi on tyhjä."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is not local."
-msgstr "Polku ei ole paikallinen"
+msgstr "Polku ei ole paikallinen."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid base path."
-msgstr "Virheellinen kantapolku"
+msgstr "Virheellinen kantapolku."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Samanniminen hakemisto on jo olemassa"
+msgstr "Samanniminen hakemisto on jo olemassa."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Virheellinen laajennus"
+msgstr "Virheellinen tiedostopääte."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Wrong extension chosen."
-msgstr "Valittu väärä tiedostopääte"
+msgstr "Valittu väärä tiedostopääte."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
@@ -9995,11 +10194,15 @@ msgid "Error loading script from %s"
msgstr "Virhe ladattaessa skripti %s:stä"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Ylikirjoita"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Ei mitään"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
msgstr "Avaa skripti / Valitse sijainti"
@@ -10008,43 +10211,36 @@ msgid "Open Script"
msgstr "Avaa skripti"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "File exists, it will be reused."
-msgstr "Tiedosto on jo olemassa, käytetään uudelleen"
+msgstr "Tiedosto on jo olemassa, se käytetään uudelleen."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Virheellinen luokan nimi"
+msgstr "Virheellinen luokan nimi."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid inherited parent name or path."
-msgstr "Virheellinen peritty isännän nimi tai polku"
+msgstr "Virheellinen peritty isännän nimi tai polku."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script is valid."
-msgstr "Skripti kelpaa"
+msgstr "Skripti kelpaa."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
-msgstr "Sallittu: a-z, A-Z, 0-9 ja _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Sallittu: a-z, A-Z, 0-9, _ ja ."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in script (into scene file)."
-msgstr "Sisäänrakennettu skripti (skenetiedostoon)"
+msgstr "Sisäänrakennettu skripti (skenetiedostoon)."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Luo uusi skriptitiedosto"
+msgstr "Luo uuden skriptitiedoston."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Lataa olemassaoleva skriptitiedosto"
+msgstr "Lataa olemassaolevan skriptitiedoston."
#: editor/script_create_dialog.cpp
msgid "Language"
@@ -10176,7 +10372,7 @@ msgstr "Aseta puusta"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Vie mittaustulokset CSV-tiedostoon"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10191,6 +10387,10 @@ msgid "Change Shortcut"
msgstr "Muuta pikanäppäintä"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Editorin asetukset"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Pikanäppäimet"
@@ -10308,12 +10508,11 @@ msgstr "GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr ""
+msgstr "GDNative singleton on otettu käyttöön"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "Poista päivitysanimaatio"
+msgstr "GDNative singleton on poistettu käytöstä"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -10404,9 +10603,8 @@ msgid "GridMap Fill Selection"
msgstr "Täytä valinta"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "Poista valinta"
+msgstr "Liitä valinta"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -10613,10 +10811,32 @@ msgid "Set Variable Type"
msgstr "Aseta muuttujan tyyppi"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ei saa mennä päällekkäin olemassa olevan sisäänrakennetun tyypin nimen "
+"kanssa."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Luo uusi suorakulmio."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Muuttujat:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Luo uusi suorakulmio."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Luo uusi polygoni."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Nimi ei ole kelvollinen tunniste:"
@@ -10786,9 +11006,8 @@ msgid "Available Nodes:"
msgstr "Saatavilla olevat solmut:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Select or create a function to edit its graph."
-msgstr "Valitse tai luo funktio graafin muokkaamiseksi"
+msgstr "Valitse tai luo funktio graafin muokkaamiseksi."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
@@ -10807,10 +11026,6 @@ msgid "Cut Nodes"
msgstr "Leikkaa solmut"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Liitä solmut"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Muokkaa jäsentä"
@@ -10923,15 +11138,21 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"Mukautettu käännös edellyttää kelvollista Android SDK -polkua editorin "
+"asetuksissa."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"Virheellinen Android SDK -polku mukautettu käännöstä varten editorin "
+"asetuksissa."
#: platform/android/export/export.cpp
msgid ""
"Android project is not installed for compiling. Install from Editor menu."
msgstr ""
+"Android-projektia ei ole asennettu kääntämistä varten. Asenna se Editori-"
+"valikosta."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -10946,6 +11167,8 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Yritetään kääntää mukautetulla käännösmallilla, mutta sillä ei ole "
+"versiotietoa. Ole hyvä ja uudelleenasenna se 'Projekti'-valikosta."
#: platform/android/export/export.cpp
msgid ""
@@ -10954,20 +11177,27 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"Androidin käännösversion epäyhteensopivuus:\n"
+" Malli asennettu: %s\n"
+" Godotin versio: %s\n"
+"Ole hyvä ja uudelleenasenna Androidin käännösmalli 'Projekti'-valikosta."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "Käännetään Android-projektia (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-projektin käännös epäonnistui, tarkista virhe tulosteesta.\n"
+"Vaihtoehtoisesti, lue docs.godotengine.org sivustolta Androidin "
+"käännösdokumentaatio."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "Käännöksen apk:ta ei generoitu: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -11085,12 +11315,11 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
-"SpriteFrames resurssi on luotava tai asetettava 'Frames' ominaisuudelle, "
+"SpriteFrames resurssi on luotava tai asetettava \"Frames\" ominaisuudelle, "
"jotta AnimatedSprite voi näyttää ruutuja."
#: scene/2d/canvas_modulate.cpp
@@ -11153,12 +11382,11 @@ 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\" "
"property."
msgstr ""
-"Tekstuuri, jolta löytyy valon muoto, täytyy antaa 'texture' ominaisuudella."
+"Tekstuuri, jolta löytyy valon muoto, täytyy antaa \"texture\" ominaisuudelle."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11168,9 +11396,8 @@ msgstr ""
"peittopolygoni."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+msgstr "Tämän peittäjän peittopolygoni on tyhjä. Ole hyvä ja piirrä polygoni."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11258,62 +11485,55 @@ msgstr ""
"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."
+"TileMap, jolla on \"Use Parent on\", tarvitsee CollisionObject2D "
+"isäntäsolmun, jolle voi antaa muotoja. Käytä sitä ainoastaan Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, jne. alla antaaksesi niille "
+"muodon."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
-"VisibilityEnable2D toimii parhaiten, kun sitä käytetään suoraan muokatun "
+"VisibilityEnabler2D toimii parhaiten, kun sitä käytetään suoraan muokatun "
"skenen juuren isäntänä."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera solmun isännän täytyy olla ARVROrigin solmu"
+msgstr "ARVRCamera solmun isännän täytyy olla ARVROrigin solmu."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr "ARVRController solmun isännän täytyy olla ARVROrigin solmu"
+msgstr "ARVRController solmun isännän täytyy olla ARVROrigin solmu."
#: 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 ""
"Ohjaimen tunnus ei saa olla 0, tai tämä ohjain ei ole sidottu oikeaan "
-"ohjaimeen"
+"ohjaimeen."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ARVRAnchor solmun isännän täytyy olla ARVROrigin solmu"
+msgstr "ARVRAnchor solmun isännän täytyy olla ARVROrigin solmu."
#: 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 ""
"Ankkurin tunnus ei saa olla 0, tai tämä ankkuri ei ole sidottu oikeaan "
-"ankkuriin"
+"ankkuriin."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin solmu tarvitsee ARVRCamera alisolmun"
+msgstr "ARVROrigin solmu tarvitsee ARVRCamera alisolmun."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -11375,13 +11595,12 @@ 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."
msgstr ""
"CollisionShape solmulle täytyy antaa muoto, jotta se toimisi. Ole hyvä ja "
-"luo sille muotoresurssi!"
+"luo sille muotoresurssi."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11396,13 +11615,12 @@ msgid "Nothing is visible because no mesh has been assigned."
msgstr "Mitään ei näy, koska meshiä ei ole asetettu."
#: 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 animaatio edellyttää SpatialMaterial käyttöä niin että "
-"\"Billboard Particles\" on kytketty päälle."
+"CPUParticles animaatio edellyttää SpatialMaterial käyttöä niin, että "
+"Billboard Mode tilaksi on asetettu \"Particle Billboard\"."
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
@@ -11419,6 +11637,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"SpotLight, jonka kulma on suurempi kuin 90 astetta, ei voi heittää varjoja."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11452,20 +11671,18 @@ msgstr ""
"passes)."
#: scene/3d/particles.cpp
-#, fuzzy
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
-"Particles animaatio edellyttää SpatialMaterial käyttöä niin että \"Billboard "
-"Particles\" on kytketty päälle."
+"Particles animaatio edellyttää SpatialMaterial käyttöä niin, että Billboard "
+"Mode tilaksi on asetettu \"Particle Billboard\"."
#: scene/3d/path.cpp
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's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
@@ -11484,16 +11701,16 @@ msgstr ""
"Muuta sen sijaan solmun alla olevia törmäysmuotoja."
#: scene/3d/remote_transform.cpp
-#, 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."
+msgstr ""
+"\"Remote Path\" etäpolkuominaisuuden täytyy osoittaa kelvolliseen Spatial "
+"tai Spatial-perittyyn solmuun toimiakseen."
#: scene/3d/soft_body.cpp
-#, fuzzy
msgid "This body will be ignored until you set a mesh."
-msgstr "Tämä kappale sivuutetaan, kunnes asetat meshin"
+msgstr "Tämä kappale sivuutetaan, kunnes asetat meshin."
#: scene/3d/soft_body.cpp
msgid ""
@@ -11505,12 +11722,11 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"AnimatedSprite3D solmulle täytyy luoda tai asettaa 'Frames' ominaisuudeksi "
+"AnimatedSprite3D solmulle täytyy luoda tai asettaa \"Frames\" ominaisuudeksi "
"SpriteFrames resurssi ruutujen näyttämiseksi."
#: scene/3d/vehicle_body.cpp
@@ -11526,6 +11742,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment solmun \"Environment\" ominaisuuden tulee sisältää "
+"Environment, jotta sillä olisi näkyviä vaikutuksia."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11564,7 +11782,6 @@ 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
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
msgstr "Graafille ei ole asetettu AnimationNode juurisolmua."
@@ -11577,9 +11794,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
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "AnimationPlayer juuri ei ole kelvollinen solmu."
+msgstr "AnimationPlayer solmun juurisolmu ei ole kelvollinen."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11592,12 +11808,11 @@ msgstr "Valitse väri ruudulta."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "Käännös (yaw)"
+msgstr "Raaka"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11608,22 +11823,24 @@ msgid "Add current color as a preset."
msgstr "Lisää nykyinen väri esiasetukseksi."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
-"Säilöllä ei ole itsessään mitään merkitystä ellei jokin skripti säädä sen "
+"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."
+"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 ""
+"Työkaluvihjettä ei näytettä, sillä ohjaimen Mouse Filter asetus on \"Ignore"
+"\". Ratkaistaksesi tämän, laita Mouse Filter asetukseksi \"Stop\" tai \"Pass"
+"\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
@@ -11634,31 +11851,28 @@ 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, 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."
+"Ponnahdusikkunat piilotetaan oletusarvoisesti ellet kutsu popup()-funktiota "
+"tai jotain muuta popup*() -funktiota. Ne saadaan näkyville muokattaessa, "
+"mutta eivät näy suoritettaessa."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Jos \"Exp Edit\" on päällä, \"Min Value\" täytyy olla suurempi kuin 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer on tarkoitettu toimimaan yhdellä lapsikontrollilla.\n"
-"Käytä containeria lapsena (VBox, HBox, jne), tai Control:ia ja aseta haluttu "
-"minimikoko manuaalisesti."
+"ScrollContainer on tarkoitettu toimimaan yhdellä alikontrollilla.\n"
+"Käytä alisolmuna jotakin säilöä (VBox, HBox, jne), tai Control solmua ja "
+"aseta haluttu minimikoko käsin."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11684,35 +11898,22 @@ msgstr ""
"saada koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri "
"johonkin solmuun näkyväksi."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Virhe FreeType:n alustamisessa."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Tuntematon fonttimuoto."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Virhe fontin latauksessa."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Virheellinen fonttikoko."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Syöte"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Virheellinen lähde sävyttimelle."
+msgstr "Virheellinen lähde esikatselulle."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Virheellinen lähde sävyttimelle."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Virheellinen vertailufunktio tälle tyypille."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Sijoitus funktiolle."
@@ -11727,7 +11928,130 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa."
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Vakioita ei voi muokata."
+
+#~ msgid "No Matches"
+#~ msgstr "Ei osumia"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Tiedostoa file_type_cache.cch ei voitu avata kirjoittamista varten. "
+#~ "Välimuistia ei tallenneta!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Tiedostoa '%s' ei voida avata, koska sitä ei näytä löytyvän "
+#~ "tiedostojärjestelmästäsi!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Virhe ladattaessa kuvaa:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Kuvassa ei ole pikseleitä, joiden läpinäkyvyys on enemmän kuin 128…"
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Lähteellä ei ole kiinteitä tahkoja täytettäväksi."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Aluetta ei voitu kartoittaa."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Pinnat eivät sisällä aluetta!"
+
+#~ msgid "No faces!"
+#~ msgstr "Ei pintoja!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Virhe: ei voitu ladata tiedostoa."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Virhe - Ei voitu ladata tiedostoa."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Doppler käytössä"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Valintatila (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Siirtotila (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Kääntötila (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Skaalaustila (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Paikalliset koordinaatit"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Tarttumisen tila (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Valintatyökalu"
+
+#~ msgid "Tool Move"
+#~ msgstr "Siirtotyökalu"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Kiertotyökalu"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Skaalaustyökalu"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Poista kaikki puuttuvat projektit listalta? (Kansioiden sisältöjä ei "
+#~ "muuteta)"
+
+#~ msgid "Project List"
+#~ msgstr "Projektiluettelo"
+
+#~ msgid "Exit"
+#~ msgstr "Poistu"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "PVRTC-työkalun suoritus ei onnistunut:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "Muunnettua kuva ei voitu ladata takaisin PVRTC-työkalulla:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Virhe FreeType:n alustamisessa."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Tuntematon fonttimuoto."
+
+#~ msgid "Error loading font."
+#~ msgstr "Virhe fontin latauksessa."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Virheellinen fonttikoko."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Edellinen kansio"
+
+#~ msgid "Next Folder"
+#~ msgstr "Seuraava kansio"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Avaa kuvakaappaukset automaattisesti"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Avaa ulkoisessa kuvankäsittelyohjelmassa."
+
+#~ msgid "Reverse"
+#~ msgstr "Käänteinen"
+
+#~ msgid "Mirror X"
+#~ msgstr "Peilaa X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Peilaa Y"
#~ msgid "Generating solution..."
#~ msgstr "Luodaan ratkaisua..."
@@ -12358,9 +12682,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Tyhjennä valinta"
-#~ msgid "Could not find tile:"
-#~ msgstr "Ruutua ei löytynyt:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nimi tai ID:"
@@ -12572,9 +12893,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "Tietoja"
-#~ msgid "Re-Import..."
-#~ msgstr "Tuo uudelleen..."
-
#~ msgid "Target path is empty."
#~ msgstr "Kohdepolku on tyhjä."
@@ -12823,9 +13141,6 @@ msgstr ""
#~ msgid "8 Bits"
#~ msgstr "8 bittiä"
-#~ msgid "Window"
-#~ msgstr "Ikkuna"
-
#~ msgid "Up"
#~ msgstr "Ylös"
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 81f6a159a4..c089099228 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -7,8 +7,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-04-07 08:04+0000\n"
-"Last-Translator: Amado Wilkins <epicalert68@gmail.com>\n"
+"PO-Revision-Date: 2019-08-11 10:23+0000\n"
+"Last-Translator: Marco Santos <enum.scima@gmail.com>\n"
"Language-Team: Filipino <https://hosted.weblate.org/projects/godot-engine/"
"godot/fil/>\n"
"Language: fil\n"
@@ -16,103 +16,107 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1 && n != 2 && n != 3 && (n % 10 == 4 "
"|| n % 10 == 6 || n % 10 == 9);\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 ""
+"Invalid na type argument para sa convert(), gamitin ang mga TYPE_* na "
+"constant."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr ""
+"Kulang ang mga byte para sa pag-decode ng mga byte, o kaya naman invalid na "
+"format."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "Invalid na input %i (hindi pinasa) sa ekspresyon"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
msgstr ""
+"Hindi magagamit ang self dahil ang instance ay naka-null (hindi pinasa)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "Invalid na mga operand para sa operator na %s, %s, at %s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr ""
+msgstr "Invalid na index ng type na %s para sa base type na %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "Invalid na pinangalang index '%s' para sa base type na %s"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
-msgstr ""
+msgstr "Mga invalid na argument para i-construct ang '%s'"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "On call sa '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
-msgstr ""
+msgstr "Malaya"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Balanse"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr ""
+msgstr "Salamin"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
-msgstr ""
+msgstr "Oras:"
#: editor/animation_bezier_editor.cpp
msgid "Value:"
-msgstr ""
+msgstr "Halaga:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
-msgstr ""
+msgstr "Mag-insert ng Key Rito"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
-msgstr ""
+msgstr "I-duplicate ang (mga) Napiling Key"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
-msgstr ""
+msgstr "Burahin ang (mga) Napiling Key"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr "Idagdag Ang Bezier Point"
+msgstr "Magdagdag ng Bezier Point"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr "Ilipat Ang Mga Bezier Points"
+msgstr "Maglipat ng (mga) Bezier Point"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
-msgstr ""
+msgstr "I-anim ang (mga) Duplicate Key"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr ""
+msgstr "I-anim ang (mga) Delete Key"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr ""
+msgstr "I-anim ang Oras ng Pagbago ng Keyframe"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transition"
-msgstr ""
+msgstr "I-anim ang Transisyon ng Pagbago"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
@@ -127,6 +131,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -611,15 +635,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -843,8 +867,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -938,7 +961,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -974,7 +997,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1063,14 +1086,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1087,7 +1110,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1104,7 +1127,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1571,12 +1593,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1637,7 +1658,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1688,7 +1709,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1713,23 +1734,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1962,6 +1987,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2258,6 +2287,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2351,6 +2388,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2404,6 +2445,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2431,20 +2476,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2477,24 +2518,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2574,12 +2623,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2595,14 +2644,6 @@ 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 ""
@@ -2623,14 +2664,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2638,12 +2679,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2916,6 +2958,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3077,7 +3123,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3094,6 +3140,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3155,12 +3205,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3174,13 +3222,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3265,19 +3317,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3310,11 +3354,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3373,6 +3417,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3436,6 +3484,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3496,6 +3548,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3503,12 +3563,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3521,11 +3589,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3732,7 +3800,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4474,10 +4542,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4490,14 +4554,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Oras:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4538,6 +4631,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4566,13 +4663,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4580,7 +4679,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4593,7 +4692,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4605,6 +4704,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4655,31 +4758,32 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Ilipat Ang Mga Bezier Points"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4759,6 +4863,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4787,6 +4895,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4807,14 +4916,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4838,6 +4950,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4854,11 +4967,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4871,6 +4979,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5078,16 +5191,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5400,14 +5503,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5491,19 +5586,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5831,7 +5930,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5937,11 +6035,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5965,7 +6059,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6046,6 +6140,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6083,11 +6181,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6175,6 +6273,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6241,6 +6343,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6275,92 +6378,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6538,7 +6645,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6594,7 +6705,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6648,7 +6759,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6659,27 +6770,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6723,26 +6814,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6797,7 +6868,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7090,10 +7161,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7178,11 +7245,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7287,14 +7354,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7308,8 +7367,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7589,6 +7648,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7665,6 +7728,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7685,6 +7753,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7757,6 +7829,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7764,10 +7852,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7856,7 +7978,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7864,7 +7986,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7876,7 +7998,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7893,7 +8015,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7962,11 +8084,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7982,7 +8104,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7993,7 +8115,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8002,7 +8124,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8010,11 +8132,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8054,11 +8176,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8067,7 +8193,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8085,15 +8211,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8143,7 +8269,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8158,6 +8284,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8171,19 +8301,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8192,7 +8322,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8201,14 +8331,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8253,47 +8383,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8460,6 +8597,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8606,6 +8747,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8675,8 +8824,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8696,7 +8845,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8720,10 +8869,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9057,6 +9202,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9109,14 +9258,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9402,6 +9543,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9444,6 +9589,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9515,19 +9664,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9618,6 +9767,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9646,7 +9799,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9806,6 +9959,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10216,10 +10373,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10404,10 +10577,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11137,22 +11306,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11165,6 +11318,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 587a8b078a..efa3da542a 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -56,12 +56,17 @@
# Peter Kent <0.peter.kent@gmail.com>, 2019.
# jef dered <themen098s@vivaldi.net>, 2019.
# Patrick Zoch Alves <patrickzochalves@gmail.com>, 2019.
+# Alexis Comte <comtealexis@gmail.com>, 2019.
+# Julian Murgia <the.straton@gmail.com>, 2019.
+# Ducoté <Raphalielle@gmail.com>, 2019.
+# Corentin Pacaud Boehm <corentin.pacaudboehm@gmail.com>, 2019.
+# Kentarosan <jacquin.yannis@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:50+0000\n"
-"Last-Translator: Chenebel Dorian <LoubiTek54@gmail.com>\n"
+"PO-Revision-Date: 2019-08-21 15:57+0000\n"
+"Last-Translator: Kentarosan <jacquin.yannis@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -69,7 +74,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -112,7 +117,6 @@ msgid "On call to '%s':"
msgstr "Sur appel à '%s' :"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Libre"
@@ -181,6 +185,27 @@ msgid "Anim Change Call"
msgstr "Changer l'appel de l'animation"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Modification du temps de l'image-clé"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Changer la transition de l'animation"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Changer le Transform"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Changer la valeur de l'image-clé de l'animation"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Changer l'appel de l'animation"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Modifier la longueur de l'animation"
@@ -509,9 +534,8 @@ msgid "Select All"
msgstr "Tout sélectionner"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Sélectionner un nœud"
+msgstr "Tout désélectionner"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -690,16 +714,18 @@ msgid "Line Number:"
msgstr "Numéro de ligne :"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d occurrence(s) remplacée(s)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Pas de correspondances"
+#, fuzzy
+msgid "%d match."
+msgstr "%d correspondance(s) trouvée(s)."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d occurrence(s) remplacée(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "%d correspondance(s) trouvée(s)."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -849,9 +875,8 @@ msgid "Connect"
msgstr "Connecter"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Signaux :"
+msgstr "Signal :"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -927,8 +952,7 @@ msgstr "Favoris :"
msgid "Recent:"
msgstr "Récents :"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1016,10 +1040,9 @@ msgid "Owners Of:"
msgstr "Propriétaires de :"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
msgstr ""
-"Supprimer les fichiers sélectionnés de ce projet ? (annulation impossible)"
+"Supprimer les fichiers sélectionnés du projet ? (restauration impossible)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1031,7 +1054,7 @@ msgstr ""
"pour leur fonctionnement.\n"
"Les supprimer tout de même ? (annulation impossible)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Impossible à enlever :"
@@ -1067,7 +1090,7 @@ msgstr "Supprimer de manière permanente %d objet(s) ? (Annulation impossible!)"
msgid "Show Dependencies"
msgstr "Afficher les dépendances"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorateur de ressources orphelines"
@@ -1156,14 +1179,16 @@ msgid "License"
msgstr "Licence"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
-msgstr "Licence tierce partie"
+#, fuzzy
+msgid "Third-party Licenses"
+msgstr "Licences tierce partie"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Le moteur Godot s'appuie sur un certain nombre de bibliothèques libres et "
@@ -1184,7 +1209,8 @@ msgid "Licenses"
msgstr "Licences"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Erreur d'ouverture de paquetage, pas au format zip."
#: editor/editor_asset_installer.cpp
@@ -1201,7 +1227,6 @@ msgid "Success!"
msgstr "Succès !"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installer"
@@ -1390,11 +1415,9 @@ msgstr ""
"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 built-in type name."
msgstr ""
-"Ne doit pas entrer en collision avec un nom de type intégré au moteur "
-"existant."
+"Ne doit pas entrer en conflit avec un nom de type existant intégré au moteur."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing global constant name."
@@ -1574,7 +1597,7 @@ msgstr "Fichier modèle introuvable :"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "Le PCK inclus dans un export 32-bits ne peut dépasser 4 Go."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1601,9 +1624,8 @@ msgid "Node Dock"
msgstr "Dock nœud"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "Dock système de fichiers"
+msgstr "Module d'importation et système de fichiers"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1659,6 +1681,8 @@ msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
+"Le profil '%s' existe déjà. Veuillez le supprimer avant d'importer. Import "
+"interrompu."
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
@@ -1666,17 +1690,15 @@ msgstr "Erreur lors de l'enregistrement du profil au chemin: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "Désassigner"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Profil actuel"
+msgstr "Profil actuel :"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "Actuel :"
+msgstr "Rendre actuel"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1684,19 +1706,17 @@ msgid "New"
msgstr "Nouveau"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importer"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exporter"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Profils disponibles"
+msgstr "Profils disponibles :"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1719,9 +1739,8 @@ msgid "Export Profile"
msgstr "Profil d'exportation"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Manage Editor Feature Profiles"
-msgstr "Gérer les modèles d'exportation"
+msgstr "Gérer les profils de fonctionnalités de l'éditeur"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1752,7 +1771,7 @@ msgstr "Montrer dans le gestionnaire de fichiers"
msgid "New Folder..."
msgstr "Nouveau dossier..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Rafraîchir"
@@ -1803,7 +1822,7 @@ msgstr "Avancer"
msgid "Go Up"
msgstr "Monter"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Basculer les fichiers cachés"
@@ -1828,23 +1847,27 @@ msgid "Move Favorite Down"
msgstr "Déplacer le favori vers le bas"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Dossier précédent"
+msgid "Go to previous folder."
+msgstr "Aller au dossier précédent."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Dossier suivant"
+msgid "Go to next folder."
+msgstr "Aller au dossier suivant."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Aller au dossier parent."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Rafraîchir les fichiers."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Ajouter ou supprimer des favoris le dossier courant."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Activer / désactiver la visibilité des fichiers cachés."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1882,6 +1905,8 @@ msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Il y a plusieurs importateurs pour différents types pointant vers le fichier "
+"%s, importation avortée"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -2012,7 +2037,7 @@ msgstr ""
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Chercher dans l'aide"
+msgstr "Rechercher dans l'aide"
#: editor/editor_help_search.cpp
msgid "Display All"
@@ -2084,6 +2109,10 @@ msgstr "Effacer"
msgid "Clear Output"
msgstr "Effacer la sortie"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "L'export du projet a échoué avec le code erreur %d."
@@ -2242,7 +2271,6 @@ msgstr ""
"paramètres dans le panneau d'importation et réimportez-la ensuite."
#: 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,7 +2279,8 @@ msgid ""
msgstr ""
"Cette scène a été importée, les modifications ne seront donc pas "
"conservées.\n"
-"L'instancier ou l'hériter permettra de conserver les modifications.\n"
+"L'instancier ou le faire hériter permettra de lui apporter des "
+"modifications.\n"
"Veuillez lire la documentation concernant l'importation des scènes afin de "
"mieux comprendre ce processus."
@@ -2415,6 +2444,15 @@ msgid "Pick a Main Scene"
msgstr "Choisir une scène principale"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Fermer la scène"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Fermer la scène"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Impossible d'activer le greffon depuis : « %s », l’analyse syntaxique de la "
@@ -2535,13 +2573,18 @@ msgstr "Jouer Cette Scène"
msgid "Close Tab"
msgstr "Fermer l'onglet"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Fermer l'onglet"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Fermer les autres onglets"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Fermer les onglets à droite"
#: editor/editor_node.cpp
msgid "Close All Tabs"
@@ -2588,6 +2631,10 @@ msgid "Go to previously opened scene."
msgstr "Aller à la scène ouverte précédemment."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copier le texte"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Onglet suivant"
@@ -2615,6 +2662,10 @@ msgstr "Nouvelle scène héritée…"
msgid "Open Scene..."
msgstr "Ouvrir une scène…"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Fichiers récents"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Enregistrer la scène"
@@ -2624,14 +2675,6 @@ msgid "Save All Scenes"
msgstr "Enregistrer toutes les scènes"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Fermer la scène"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Fichiers récents"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Convertir vers…"
@@ -2661,25 +2704,37 @@ msgstr "Réinitialiser la scène"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Outils divers liés au projet ou à la scène."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projet"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Paramètres du projet"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Outils"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exporter"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Installer un modèle de compilation Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Ouvrir le dossier de données du projets"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Outils"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorateur de ressources orphelines"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2779,12 +2834,13 @@ msgstr ""
"Quand elle est utilisée à distance sur un périphérique, cette option est "
"plus efficace avec le système de fichiers réseau."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Éditeur"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Paramètres de l'éditeur"
#: editor/editor_node.cpp
@@ -2792,32 +2848,21 @@ msgid "Editor Layout"
msgstr "Disposition de l'éditeur"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Choisir comme racine de scène"
+msgstr "Prendre une capture d'écran"
#: 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"
+"Les captures d'écran sont sauvegardées dans le dossier Editor Data/Settings."
#: 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é"
+msgstr "Activer/désactiver la console système"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2832,14 +2877,16 @@ msgid "Open Editor Settings Folder"
msgstr "Ouvrir le dossier des paramètres de l'éditeur"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Gérer les fonctionnalités de l'éditeur"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gérer les modèles d'exportation"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Aide"
@@ -2847,18 +2894,19 @@ msgstr "Aide"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Rechercher"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentation en ligne"
#: editor/editor_node.cpp
msgid "Q&A"
-msgstr "Q & R"
+msgstr "Questions et réponses"
#: editor/editor_node.cpp
msgid "Issue Tracker"
@@ -2926,19 +2974,16 @@ msgid "Spins when the editor window redraws."
msgstr "Tourne lorsque la fenêtre de l'éditeur est redessinée."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Continu"
+msgstr "Mettre à jour en continu"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Repeindre quand modifié"
+msgstr "Mettre à jour quand modifié"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Désactiver l'indicateur d'activité"
+msgstr "Cacher l'indicateur d'activité"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -2967,6 +3012,8 @@ msgstr "Ne pas enregistrer"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
msgstr ""
+"Le modèle de compilation Android est manquant, veuillez installer les "
+"modèles appropriés."
#: editor/editor_node.cpp
msgid "Manage Templates"
@@ -2977,6 +3024,9 @@ 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 ""
+"Ceci va installer le projet Android pour des compilations personnalisées.\n"
+"Notez que pour l'utiliser, vous devez l'activer pour chaque préréglage "
+"d'exportation."
#: editor/editor_node.cpp
msgid ""
@@ -2984,6 +3034,9 @@ msgid ""
"Remove the \"build\" directory manually before attempting this operation "
"again."
msgstr ""
+"Le modèle de build Android est déjà installé et ne va pas être remplacé.\n"
+"Supprimez le répertoire « build » manuellement avant de retenter cette "
+"opération."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
@@ -3127,6 +3180,10 @@ msgstr "Temps"
msgid "Calls"
msgstr "Appels"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Modifier le texte :"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Activé"
@@ -3299,7 +3356,8 @@ msgid "Import From Node:"
msgstr "Importer à partir d'un nœud :"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Télécharger à nouveau"
#: editor/export_template_manager.cpp
@@ -3316,6 +3374,10 @@ msgid "Download"
msgstr "Télécharger"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Manquant)"
@@ -3380,12 +3442,10 @@ msgid "No response."
msgstr "Pas de réponse."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Échec de la requête."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Boucle de Redirection."
@@ -3399,15 +3459,22 @@ msgid "Download Complete."
msgstr "Téléchargement terminé."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Impossible d'enregistrer le thème dans le fichier :"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"L'installation des modèles a échoué. Les archives des modèles posant "
"problème peuvent être trouvées à « %s »."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Erreur lors de la requête de l’URL : "
#: editor/export_template_manager.cpp
@@ -3457,7 +3524,6 @@ msgid "SSL Handshake Error"
msgstr "Erreurs de la négociation SSL"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
msgstr "Décompresser les sources de compilation Android"
@@ -3495,23 +3561,11 @@ msgstr ""
"Sélectionner un miroir depuis la liste : (Maj+Click : Ouvrir dans le "
"navigateur)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Impossible d'ouvrir file_type_cache.cch en écriture, le fichier de cache ne "
-"sera pas sauvé !"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoris"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Impossible d'accéder à « %s » car celui-ci n'existe pas dans le système de "
-"fichiers !"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Statut : L'importation du fichier a échoué. Veuillez corriger le fichier et "
@@ -3546,14 +3600,14 @@ msgid "Provided name contains invalid characters."
msgstr "Le nom renseigné contient des caractères invalides."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Le nom contient des caractères invalides."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Un fichier ou un dossier avec ce nom existe déjà."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Le nom contient des caractères invalides."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Renommer le fichier :"
@@ -3574,9 +3628,8 @@ msgid "New Inherited Scene"
msgstr "Nouvelle scène héritée"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open Scenes"
-msgstr "Ouvrir une scène"
+msgstr "Ouvrir des scènes"
#: editor/filesystem_dock.cpp
msgid "Instance"
@@ -3610,6 +3663,11 @@ msgstr "Dupliquer…"
msgid "Move To..."
msgstr "Déplacer vers…"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nouvelle scène"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nouveau script…"
@@ -3676,6 +3734,11 @@ msgstr ""
msgid "Overwrite"
msgstr "Écraser"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Créer depuis la scène"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Créer un script"
@@ -3701,6 +3764,8 @@ msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
msgstr ""
+"Inclure les fichiers avec les extensions suivantes. Ajoutez ou supprimez les "
+"dans les paramètres du projet."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -3736,6 +3801,14 @@ msgid "Search complete"
msgstr "Recherche terminée"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Ajouter au groupe"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Supprimer du groupe"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Le nom du groupe existe déjà."
@@ -3743,12 +3816,23 @@ msgstr "Le nom du groupe existe déjà."
msgid "Invalid group name."
msgstr "Nom de groupe invalide."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gérer les groupes"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Supprimer la disposition"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Groupes"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nœuds non groupés"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3761,12 +3845,13 @@ msgid "Nodes in Group"
msgstr "Nœuds groupés"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Ajouter au groupe"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Supprimer du groupe"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Éditeur de Script"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3976,7 +4061,8 @@ msgid "MultiNode Set"
msgstr "Ensemble multi-nœud"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Sélectionnez un nœud pour modifier les signaux et groupes."
#: editor/plugin_config_dialog.cpp
@@ -4743,10 +4829,6 @@ msgid "View Files"
msgstr "Voir Fichiers"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Impossible de résoudre le nom de l'hôte :"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Erreur de connection, veuillez essayer à nouveau."
@@ -4759,14 +4841,47 @@ msgid "No response from host:"
msgstr "Pas de réponse de l'hôte :"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Impossible de résoudre le nom de l'hôte :"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "La requête a échoué, code retourné :"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Échec de la requête."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Impossible d'enregistrer le thème dans le fichier :"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "La requête a échoué, trop de redirections"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Boucle de Redirection."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "La requête a échoué, code retourné :"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Temps"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Vérification du téléchargement échouée, le fichier a été altéré."
@@ -4807,6 +4922,10 @@ msgid "Idle"
msgstr "Inactif"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Installer..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Réessayer"
@@ -4835,13 +4954,17 @@ msgid "Last"
msgstr "Dernier"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Tout"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Extensions"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4849,8 +4972,8 @@ msgid "Sort:"
msgstr "Trier :"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Inverser"
+msgid "Reverse sorting."
+msgstr "Tri inverse."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4862,7 +4985,8 @@ msgid "Site:"
msgstr "Site :"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Support…"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4871,7 +4995,12 @@ msgstr "Officiel"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Testing"
-msgstr "Tester"
+msgstr "En période de test"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Charger..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -4932,31 +5061,31 @@ msgid "Rotation Step:"
msgstr "Pas de la rotation :"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr "Déplacer le guide vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Créer un nouveau guide vertical"
+msgid "Create Vertical Guide"
+msgstr "Créer un guide vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Supprimer le guide vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "Déplacer le guide horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Créer un nouveau guide horizontal"
+msgid "Create Horizontal Guide"
+msgstr "Créer un guide horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Supprimer le guide horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr "Créer de nouveaux guides horizontaux et verticaux"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5000,6 +5129,8 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
+"Lorsqu'ils sont actifs, les nœuds Control en mouvement changent leur ancrage "
+"au lieu de leur marges."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5038,6 +5169,11 @@ msgid "Paste Pose"
msgstr "Coller la pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Effacer les os"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Créer des os personnalisés à partir d'un ou de plusieurs nœuds"
@@ -5068,6 +5204,7 @@ msgid "Zoom Reset"
msgstr "Réinitialiser le facteur d'agrandissement"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Sélectionner le mode"
@@ -5090,14 +5227,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Bouton droit : Sélection détaillée par liste"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Mode déplacement"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Mode rotation"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Mode de mise à l'échelle"
@@ -5123,6 +5263,7 @@ msgid "Toggle snapping."
msgstr "Activer/Désactiver le magnétisme."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Aligner sur la grille"
@@ -5139,11 +5280,6 @@ msgid "Use Rotation Snap"
msgstr "Rotation alignée"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurer le magnétisme…"
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Alignement relatif"
@@ -5156,6 +5292,11 @@ msgid "Smart Snapping"
msgstr "Magnétisme intelligent"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurer le magnétisme…"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Aimanter au parent"
@@ -5259,7 +5400,7 @@ msgstr "Cadrer la sélection"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
-msgstr ""
+msgstr "Prévisualiser l'échelle du Canvas"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
@@ -5315,9 +5456,8 @@ msgid "Divide grid step by 2"
msgstr "Diviser le pas de la grille par 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Vue arrière"
+msgstr "Vue panoramique"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -5371,16 +5511,6 @@ msgstr "Définir la poignée"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Erreur de chargement d'image :"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Pas de pixels avec transparence > 128 dans l'image..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Charger Masque d'Émission"
@@ -5388,9 +5518,8 @@ msgstr "Charger Masque d'Émission"
#: 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"
+msgstr "Redémarrer"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5547,7 +5676,7 @@ msgstr "Créer une forme Trimesh statique"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Failed creating shapes!"
-msgstr ""
+msgstr "Échec de la création de formes !"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Convex Shape(s)"
@@ -5700,14 +5829,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "La surface source est invalide (pas de faces)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Le parent n'a pas de faces solides à peupler."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Impossible de cartographier la zone."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Sélectionnez un maillage source :"
@@ -5792,20 +5913,27 @@ msgid "Generation Time (sec):"
msgstr "Temps de Génération (sec) :"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Des faces ne contiennent pas de zone !"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Le nœud ne contient pas de géométrie (faces)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Pas de faces !"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Le nœud ne contient pas de géométrie."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Le nœud ne contient pas de géométrie (faces)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Le nœud ne contient pas de géométrie."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6139,7 +6267,6 @@ msgid "Grid Settings"
msgstr "Paramètres de la grille"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Aligner"
@@ -6245,11 +6372,8 @@ msgid "Error writing TextFile:"
msgstr "Erreur lors de l'écriture du fichier texte :"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Erreur de chargement de fichier."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+#, fuzzy
+msgid "Could not load file at:"
msgstr "Erreur de chargement de fichier."
#: editor/plugins/script_editor_plugin.cpp
@@ -6273,7 +6397,8 @@ msgid "Error Importing"
msgstr "Erreur d'importation"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nouveau fichier texte..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6310,18 +6435,16 @@ msgid "Find Next"
msgstr "Correspondance suivante"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Filtrer les propriétés"
+msgstr "Filtrer les scripts"
#: 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 :"
+msgstr "Méthodes de filtrage"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6356,6 +6479,11 @@ msgid "Open..."
msgstr "Ouvrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Ouvrir un script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Tout enregistrer"
@@ -6393,13 +6521,13 @@ msgid "Save Theme"
msgstr "Enregistrer le thème"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Fermer les documentations"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Fermer tout"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Fermer les documentations"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Lancer"
@@ -6447,7 +6575,7 @@ msgstr "Aider à améliorer la documentation de Godot en donnant vos réactions.
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
-msgstr "Chercher dans la documentation de référence."
+msgstr "Rechercher dans la documentation de référence."
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to previous edited document."
@@ -6487,6 +6615,11 @@ msgstr "Débogueur"
msgid "Search Results"
msgstr "Résultats de recherche"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Effacer la liste des scènes récentes"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Connexions à la méthode :"
@@ -6501,13 +6634,14 @@ msgstr "Signaux"
#: editor/plugins/script_text_editor.cpp
msgid "Target"
-msgstr ""
+msgstr "Cible"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
-msgstr "Rien n'est connecté à l'entrée « %s » du nœud « %s »."
+msgstr ""
+"Méthode connectée '%s' manquante pour le signal '%s' du nœud '%s' vers le "
+"nœud '%s'."
#: editor/plugins/script_text_editor.cpp
msgid "Line"
@@ -6554,18 +6688,18 @@ msgid "Syntax Highlighter"
msgstr "Coloration syntaxique"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Atteindre"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "Signets"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Créer des points."
+msgstr "Point d'arrêts"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6589,26 +6723,6 @@ msgid "Toggle Comment"
msgstr "Commenter/décommenter"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Basculer en vue libre"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Aller au point d'arrêt suivant"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Aller au point d'arrêt précédent"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Supprimer tous"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Réduire/Développer la ligne"
@@ -6629,6 +6743,11 @@ msgid "Complete Symbol"
msgstr "Compléter le symbole"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Mettre à l'échelle la sélection"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Supprimer les espaces de fin de ligne"
@@ -6645,29 +6764,32 @@ msgid "Auto Indent"
msgstr "Indentation automatique"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Placer un point d'arrêt"
+msgid "Find Previous"
+msgstr "Correspondance précédente"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Supprimer tous les points d'arrêt"
+msgid "Find in Files..."
+msgstr "Rechercher dans les fichiers…"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Aller au point d'arrêt suivant"
+msgid "Contextual Help"
+msgstr "Aide contextuelle"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Aller au point d'arrêt précédent"
+msgid "Toggle Bookmark"
+msgstr "Activer / Désactiver signet"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Correspondance précédente"
+msgid "Go to Next Bookmark"
+msgstr "Aller au signet suivant"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Rechercher dans les fichiers…"
+msgid "Go to Previous Bookmark"
+msgstr "Aller au signet précédent"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Supprimer tous les signets"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6678,8 +6800,21 @@ msgid "Go to Line..."
msgstr "Aller à la ligne…"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Aide contextuelle"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Placer un point d'arrêt"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Supprimer tous les points d'arrêt"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Aller au point d'arrêt suivant"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Aller au point d'arrêt précédent"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6858,8 +6993,12 @@ msgid "Rear"
msgstr "Arrière"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Aligner avec la vue"
+msgid "Align Transform with View"
+msgstr "Aligner le Transform avec la vue"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Aligner la rotation avec la vue"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6916,8 +7055,9 @@ msgid "Audio Listener"
msgstr "Écouteur audio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Activer Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Activer le filtrage"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6973,8 +7113,8 @@ msgid "Snap Nodes To Floor"
msgstr "Aligner les nœuds au sol"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Sélectionner le mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6987,30 +7127,11 @@ msgstr ""
"Alt+Bouton droit : Sélection détaillée par liste"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Move déplacement (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Mode rotation (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Mode de mise à l'échelle (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordonnées locales"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Mode d'échelle local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Mode d'aimantation (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vue de dessous"
@@ -7051,26 +7172,6 @@ msgid "Focus Selection"
msgstr "Focaliser la sélection"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Aligner la sélection avec la vue"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Outil sélection"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Outil déplacement"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Outil rotation"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Outil échelle"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Basculer en vue libre"
@@ -7125,7 +7226,8 @@ msgstr "Afficher la grille"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Paramètres"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7271,14 +7373,12 @@ msgid "Settings:"
msgstr "Paramètres :"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "Cadrer la sélection"
+msgstr "Aucune trame sélectionnée"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add %d Frame(s)"
-msgstr "Ajouter une image"
+msgstr "Ajouter %d Trame(s)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
@@ -7334,7 +7434,7 @@ msgstr "Ajouter une texture à partir d'un fichier"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr ""
+msgstr "Ajouter des trames depuis une feuille de Sprite"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -7353,9 +7453,8 @@ msgid "Move (After)"
msgstr "Déplacer (après)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "Pile des appels"
+msgstr "Sélectionner des Trames"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
@@ -7366,14 +7465,12 @@ msgid "Vertical:"
msgstr "Vertical :"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select/Clear All Frames"
-msgstr "Tout sélectionner"
+msgstr "Sélectionner/Effacer toutes les trames"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Create Frames from Sprite Sheet"
-msgstr "Créer depuis la scène"
+msgstr "Créer des trames depuis une feuille de Sprite"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
@@ -7425,10 +7522,6 @@ msgid "TextureRegion"
msgstr "RegionDeTexture"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Impossible d'enregistrer le thème dans le fichier :"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Ajouter tous les items"
@@ -7473,9 +7566,8 @@ msgid "Create From Current Editor Theme"
msgstr "Créer à partir du thème actuel de l'éditeur"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Button"
-msgstr "Bouton de souris"
+msgstr "Activer / Désactiver bouton"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Disabled Button"
@@ -7511,14 +7603,16 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Sous-menu"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Élément 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Élément 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7530,9 +7624,8 @@ msgid "Many"
msgstr "Plusieurs"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled LineEdit"
-msgstr "Désactiver l'indicateur d'activité"
+msgstr "LineEdit désactivé"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -7552,7 +7645,7 @@ msgstr "Élément modifiable"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Sous-arbre"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
@@ -7624,16 +7717,8 @@ msgid "Transpose"
msgstr "Transposer"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Miroir X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Miroir Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
-msgstr ""
+msgstr "Désactiver Autotile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Enable Priority"
@@ -7644,10 +7729,13 @@ msgid "Paint Tile"
msgstr "Peindre la case"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift + Clic droit : Dessiner une ligne\n"
+"Shift + Ctrl + Clic droit : Dessiner un rectangle"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
@@ -7726,9 +7814,8 @@ msgid "Bitmask Mode"
msgstr "Mode Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "Mode d'exportation :"
+msgstr "Mode prioritaire"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon Mode"
@@ -7944,19 +8031,20 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
+msgid "(GLES3 only)"
+msgstr "(GLES3 seulement)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
-msgstr "Ajouter une entrée"
+msgstr "Ajouter une entrée +"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add output +"
-msgstr "Ajouter une entrée"
+msgstr "Ajouter une sortie +"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "Échelle :"
+msgstr "Scalaire"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector"
@@ -7964,56 +8052,47 @@ msgstr "Vecteur"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "Booléen"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input port"
-msgstr "Ajouter une entrée"
+msgstr "Ajouter un port d'entrée"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "Ajouter un port de sortie"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port type"
-msgstr "Changer le type par défaut"
+msgstr "Changer le type de port d'entrée"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "Changer le type par défaut"
+msgstr "Changer le type de port de sortie"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "Changer nom de l'entrée"
+msgstr "Changer le nom du port d'entrée"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port name"
-msgstr "Changer nom d'argument"
+msgstr "Changer le nom du port de sortie"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove input port"
-msgstr "Supprimer point"
+msgstr "Supprimer le port d'entrée"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove output port"
-msgstr "Supprimer point"
+msgstr "Supprimer le port de sortie"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set expression"
-msgstr "Changer l'expression"
+msgstr "Définir l'expression"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Resize VisualShader node"
-msgstr "VisualShader"
+msgstr "Redimensionner le nœud VisualShader"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Uniform Name"
@@ -8032,6 +8111,11 @@ msgid "Duplicate Nodes"
msgstr "Dupliquer le(s) nœud(s)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Coller les nœuds"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Supprimer des nœuds"
@@ -8053,35 +8137,36 @@ msgstr "Lumière"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Créer un nœud Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
-msgstr "Créer un nœud"
+msgstr "Créer un nœud Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "Aller à la fonction"
+msgstr "Fonction de coloration."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "Opérateur de couleur."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "Créer une fonction"
+msgstr "Fonction niveau de gris."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
-msgstr ""
+msgstr "Convertit le vecteur HSV en équivalent RGB."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts RGB vector to HSV equivalent."
-msgstr ""
+msgstr "Convertit le vecteur RGB en équivalent HSV."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Renommer la fonction"
+msgstr "Fonction Sepia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
@@ -8089,193 +8174,249 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Opérateur d'obscurcissement ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Différences seules"
+msgstr "Opérateur de différence."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Opérateur d'évitement."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "HardLight operator"
-msgstr ""
+msgstr "Opérateur HardLight"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "Opérateur d'éclaircissement."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Opérateur de superposition."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Opérateur d'écran."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "Opérateur SoftLight."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
-msgstr "Constante"
+msgstr "Constante de couleur."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Supprimer la transformation"
+msgstr "Couleur uniforme."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Renvoi le résultat booléen de la comparaison %s de deux paramètres."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Égal (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Supérieur à (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Supérieur ou égal à (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
msgstr ""
+"Renvoie un vecteur associé si le scalaire associé est égal, supérieur ou "
+"inférieur."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Renvoie le résultat booléen de la comparaison entre INF et un scalaire en "
+"paramètre."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Renvoie le résultat booléen de la comparaison entre NaN et un scalaire en "
+"paramètre."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Inférieur à (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Inférieur ou égal à (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Différent de (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
+"Renvoi un vecteur associé si la valeur booléen fournie est vrai ou fausse."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Boolean constant."
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Renvoie le résultat booléen de la comparaison de deux paramètres."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
msgstr ""
+"Renvoie le résultat booléen de la comparaison entre INF (ou NaN) et un "
+"scalaire en paramètre."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr "Constante booléenne."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "Booléen uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour tous les modes de shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Aimanter au parent"
+msgstr "Paramètre d'entrée."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour les modes de shader fragment et vertex."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour les modes de shader fragment et light."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour le mode de shader fragment."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour le mode de shader light."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour le mode de shader vertex."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "'%s' paramètre d'entrée pour les modes de shader fragment et vertex."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Mettre à l'échelle la sélection"
+msgstr "Fonction scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "Échelle (ratio) :"
+msgstr "Opérateur scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
msgstr ""
+"Constante E (2.718282). Représente la base de tous les logarithmes naturels."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "Constante Espilon (0.00001). Plus petit nombre scalaire possible."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "Constante Phi (1.618034). Nombre d'or."
#: 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 degrés."
#: 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 degrés."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "Constante Pi (3.141593) ou 180 degrés."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "Constante Tau (6.283185) ou 360 degrés."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "Constante Sqrt2 (1.414214). Racine carrée de 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "Renvoie la valeur absolue du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "Renvoie l'arc cosinus du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Renvoie le cosinus hyperbolique inverse du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "Renvoie l'arc sinus du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Renvoie le sinus hyperbolique inverse du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+msgstr "Renvoie l'arc tangente du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "Renvoie l'arc tangente des paramètres."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Renvoie la tangente hyperbolique inverse du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
msgstr ""
+"Recherche l'entier le plus proche qui est plus supérieur ou égal au "
+"paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
-msgstr ""
+msgstr "Limite une valeur entre deux autres valeurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "Renvoie le cosinus du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Renvoie le cosinus hyperbolique du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "Convertit une quantité de radians en degrés."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
@@ -8287,90 +8428,91 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
-msgstr ""
+msgstr "Recherche l'entier le plus proche inférieur ou égal au paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "Calcule la partie décimale de l'argument."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
-msgstr ""
+msgstr "Renvoie l'inverse de la racine carrée du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "Logarithme naturel."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "Logarithme base-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "Renvoie la plus grande des deux valeurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "Renvoie la plus petite des deux valeurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
-msgstr ""
+msgstr "Interpolation linéaire entre deux scalaires."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "Renvoie la valeur opposée du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - scalar"
-msgstr ""
+msgstr "1.0 - scalaire"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the value of the first parameter raised to the power of the second."
msgstr ""
+"Renvoie la valeur du premier paramètre à la puissance du second paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "Convertit une quantité de degrés en radians."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / scalar"
-msgstr ""
+msgstr "1.0 / scalaire"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "Renvoie l'entier le plus proche de celui du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Renvoie l'entier pair le plus proche de celui du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "Limite la valeur entre 0.0 et 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "Extrait le signe du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "Renvoie le sinus du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Renvoie le sinus hyperbolique du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "Renvoie la racine carrée du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8379,49 +8521,48 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "Renvoie la tangente du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Renvoie la tangente hyperbolique du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr ""
+msgid "Finds the truncated value of the parameter."
+msgstr "Recherche la valeur tronquée du paramètre."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Additionne un scalaire par un scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "Divise un scalaire par un scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "Multiplie un scalaire par un scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "Renvoie le reste de deux scalaires."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "Soustrait un scalaire d'un scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar constant."
-msgstr ""
+msgstr "Constante scalaire."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Supprimer la transformation"
+msgstr "Scalaire uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
@@ -8432,21 +8573,24 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Dialogue de transformation…"
+msgstr "Fonction Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8457,114 +8601,123 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
-msgstr ""
+msgstr "Créer un Transform à partir de quatre vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Décompose un Transform en quatre vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr ""
+msgid "Calculates the determinant of a transform."
+msgstr "Calcule le déterminant d'un Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Calcule l'inverse d'un Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Calcule la transposition d'une transformation."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Multiplie un Transform par un Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Multiplie un vecteur par un Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Transformation annulée."
+msgstr "Constante Transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Transformation annulée."
+msgstr "Transform uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Affectation à la fonction."
+msgstr "Fonction vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
-msgstr ""
+msgstr "Opérateur vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "Créer un vecteur à partir de trois scalaires."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "Décompose un vecteur en trois scalaires."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "Calcule le produit vectoriel de deux vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "Renvoie la distance entre deux points."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "Calcule le produit scalaire de deux vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Retourne le vecteur qui pointe dans la même direction qu'un vecteur de "
+"référence. La fonction a trois paramètres vectoriels : N, le vecteur à "
+"orienter, I, le vecteur incident, et Nref, le vecteur de référence. Si le "
+"produit scalaire de I et Nref est inférieur à zéro, la valeur de retour est "
+"N. Sinon, -N est renvoyé."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "Calcule la magnitude d'un vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "Interpolation linéaire de deux vecteurs."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolation linéaire de deux vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
-msgstr ""
+msgstr "Calcule le produit normalisé du vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - vector"
-msgstr ""
+msgstr "1.0 - vecteur"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / vector"
-msgstr ""
+msgstr "1.0 / vecteur"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Renvoie le vecteur qui pointe dans la direction de la réflexion ( a : "
+"vecteur incident, b : vecteur normal )."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
-msgstr ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Renvoie le vecteur qui pointe dans la direction de la réfraction."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8573,7 +8726,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8582,44 +8735,43 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "Additionne un vecteur avec un vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "Divise un vecteur par un vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "Multiplie un vecteur par un vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two vectors."
-msgstr ""
+msgstr "Renvoie le reste de deux vecteurs."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts vector from vector."
-msgstr ""
+msgstr "Soustrait un vecteur d'un vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector constant."
-msgstr ""
+msgstr "Constante de vecteur."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "Affectation à l'uniforme."
+msgstr "Vecteur uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8627,6 +8779,10 @@ 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 ""
+"Expression en langage Godot Shader personnalisé, avec un nombre personnalisé "
+"de ports d'entrée et de sortie. C'est une injection directe de code dans la "
+"fonction vertex/fragment/lumière, ne l'utilisez pas pour écrire les "
+"déclarations de fonction à l'intérieur."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8635,48 +8791,67 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Mode Fragment/Light uniquement) Fonction dérivée Scalaire."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Mode Fragment/Lumière uniquement) Fonction dérivée vectorielle."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Mode Fragment/Light uniquement) (Vecteur) Dérivée en 'x' utilisant la "
+"différenciation locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Mode Fragment/Light uniquement) (Scalaire) Dérivée en 'x' utilisant la "
+"différenciation locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Mode Fragment/Light uniquement) (Vecteur) Dérivée en 'y' utilisant la "
+"différenciation locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Mode Fragment/Light uniquement) (Scalaire) Dérivée en 'y' utilisant la "
+"différenciation locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Mode Fragment/Light uniquement) (Vecteur) Somme des dérivées absolues en "
+"'x' et 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Mode Fragment/Light uniquement) (Scalaire) Somme des dérivées absolues en "
+"'x' et 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8851,6 +9026,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Modèles d'exportation manquants pour cette plateforme :"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gérer les modèles d'exportation"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exporter avec debug"
@@ -9012,6 +9191,15 @@ msgid "Unnamed Project"
msgstr "Projet sans titre"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importer un projet existant"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Impossible d'ouvrir le projet à \"%s\"."
@@ -9020,7 +9208,6 @@ msgid "Are you sure to open more than one project?"
msgstr "Voulez-vous vraiment ouvrir plus d'un projet à la fois ?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"The following project settings file does not specify the version of Godot "
"through which it was created.\n"
@@ -9043,7 +9230,6 @@ msgstr ""
"versions du moteur."
#: 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"
@@ -9073,7 +9259,6 @@ msgstr ""
"du moteur, dont les paramètres ne sont pas compatibles avec cette 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 "
@@ -9092,36 +9277,35 @@ msgstr ""
"Veuillez cliquer sur « Édition » pour déclencher l'importation initiale."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "Voulez-vous vraiment lancer plus d'un projet à la fois ?"
+msgstr "Voulez-vous vraiment lancer %d projets à la fois ?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
msgstr ""
-"Supprimer le projet de la liste ? (Le contenu du dossier ne sera pas modifié)"
+"Supprimer %d projets de la liste ?\n"
+"Le contenu des dossiers de projet ne sera pas modifié."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
msgstr ""
-"Supprimer le projet de la liste ? (Le contenu du dossier ne sera pas modifié)"
+"Supprimer le projet de la liste ? \n"
+"Le contenu du dossier de projet ne sera pas modifié."
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Supprimer le projet de la liste ? (Le contenu du dossier ne sera pas modifié)"
+"Supprimer %d projets de la liste ?\n"
+"Le contenu des dossiers de projet ne sera pas modifié."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
@@ -9131,21 +9315,22 @@ msgstr ""
"ou du gestionnaire de projets."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
msgstr ""
-"Vous êtes sur le point de scanner les %s de dossiers pour les projets Godot "
-"existants. Est-ce que vous confirmez ?"
+"Êtes vous certain de vouloir scanner %s dossiers à la recherche de projets "
+"Godot existants ?\n"
+"Cela pourrait prendre prendre un moment."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestionnaire de projets"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Liste des projets"
+#, fuzzy
+msgid "Projects"
+msgstr "Projet"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9160,19 +9345,14 @@ msgid "New Project"
msgstr "Nouveau projet"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Supprimer point"
+msgstr "Nettoyer la liste"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "Modèles"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Quitter"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Redémarrer maintenant"
@@ -9181,13 +9361,12 @@ msgid "Can't run project"
msgstr "Impossible de lancer le projet"
#: 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 ""
-"Vous n'avez pour l'instant aucun projet.\n"
-"Voulez-vous explorer les exemples de projets officiels dans l'Asset Library ?"
+"Vous n'avez pour l'instant aucun projets.\n"
+"Voulez-vous explorer des exemples de projets officiels dans l'Asset Library ?"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9214,9 +9393,8 @@ msgstr ""
"« \\ » ou « \" »"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "L'action « %s » existe déjà !"
+msgstr "Une action avec le nom « %s » existe déjà."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -9435,9 +9613,8 @@ msgid "Override For..."
msgstr "Écraser pour…"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-#, fuzzy
msgid "The editor must be restarted for changes to take effect."
-msgstr "L'éditeur doit être redémarré pour que les changements prennent effet"
+msgstr "L'éditeur doit être redémarré pour que les changements prennent effet."
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -9496,14 +9673,12 @@ msgid "Locales Filter"
msgstr "Filtre de langues"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "Montrer toutes les langues"
+msgstr "Afficher toutes les langues"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "Montrer uniquement les langues sélectionnées"
+msgstr "Afficher uniquement les langues sélectionnées"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
@@ -9517,6 +9692,10 @@ msgstr "Langues :"
msgid "AutoLoad"
msgstr "AutoLoad"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Extensions"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zéro"
@@ -9569,15 +9748,6 @@ msgstr "Sélectionner une méthode virtuelle"
msgid "Select Method"
msgstr "Sélectionner une méthode"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Impossible d'exécuter l'outil PVRTC :"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"L'image convertie n'a pas pu être rechargée en utilisant l'outil PVRTC :"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Renommer par lot"
@@ -9591,7 +9761,6 @@ msgid "Suffix"
msgstr "Suffixe"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
msgstr "Options avancées"
@@ -9854,9 +10023,8 @@ msgid "User Interface"
msgstr "Interface utilisateur"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "Supprimer un nœud"
+msgstr "Autre nœud"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -9875,6 +10043,11 @@ msgid "Remove Node(s)"
msgstr "Supprimer le(s) nœud(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Changer le nom du port de sortie"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9899,7 +10072,6 @@ msgid "Clear Inheritance"
msgstr "Effacer l'héritage"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "Ouvrir la documentation"
@@ -9908,9 +10080,8 @@ msgid "Add Child Node"
msgstr "Ajouter un nœud enfant"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Réduire tout"
+msgstr "Développer/Réduire tout"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -9921,6 +10092,10 @@ msgid "Extend Script"
msgstr "Hériter d'un script"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Re-parenter le nœud"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Choisir comme racine de scène"
@@ -9941,9 +10116,8 @@ msgid "Delete (No Confirm)"
msgstr "Effacer (pas de confirmation)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Ajouter/Créer un nouveau nœud"
+msgstr "Ajouter/Créer un nouveau nœud."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -9979,52 +10153,51 @@ msgid "Toggle Visible"
msgstr "Rendre visible"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "Sélectionner un nœud"
+msgstr "Déverrouiller le nœud"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Button Group"
-msgstr "Ajouter au groupe"
+msgstr "Bouton de groupe"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "Erreur de connexion"
+msgstr "(Connexion à partir de)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
msgstr "Avertissement de configuration de nœud :"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Le nœud possède des connexions et/ou des groupes.\n"
"Cliquez pour afficher le panneau de connexion des signaux."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Le nœud possède des connections.\n"
"Cliquez pour afficher le panneau de connexion des signaux."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Le nœud fait partie de groupes.\n"
"Cliquez pour afficher le panneau de gestion des groupes."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Ouvrir un script"
+msgstr "Ouvrir le script :"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -10075,39 +10248,32 @@ msgid "Select a Node"
msgstr "Sélectionner un nœud"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "Le chemin est vide"
+msgstr "Le chemin est vide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Le nom de fichier est vide"
+msgstr "Le nom de fichier est vide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is not local."
-msgstr "Le chemin n'est pas local"
+msgstr "Le chemin n'est pas local."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid base path."
-msgstr "Chemin de base invalide"
+msgstr "Chemin de base invalide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Un dossier du même nom existe déjà"
+msgstr "Un dossier du même nom existe déjà."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Extension invalide"
+msgstr "Extension invalide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Wrong extension chosen."
-msgstr "Choix d'extension erroné"
+msgstr "Choix d'extension erroné."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
@@ -10122,11 +10288,15 @@ msgid "Error loading script from %s"
msgstr "Erreur de chargement de script depuis %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Écraser"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
msgstr "Ouvrir le script / Choisir l'emplacement"
@@ -10135,43 +10305,36 @@ msgid "Open Script"
msgstr "Ouvrir un script"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "File exists, it will be reused."
-msgstr "Le fichier existe, il sera réutilisé"
+msgstr "Le fichier existe, il sera réutilisé."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Nom de classe invalide"
+msgstr "Nom de classe invalide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid inherited parent name or path."
-msgstr "Nom ou chemin parent hérité invalide"
+msgstr "Nom ou chemin parent hérité invalide."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script is valid."
-msgstr "Script valide"
+msgstr "Script valide."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
-msgstr "Autorisé : a-z, A-Z, 0-9 et _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Autorisé : a-z, A-Z, 0-9, _ et ."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in script (into scene file)."
-msgstr "Script intégré (dans le fichier scène)"
+msgstr "Script intégré (dans le fichier scène)."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Créer nouveau fichier de script"
+msgstr "Va créer un nouveau fichier de script."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Charger fichier de script existant"
+msgstr "Va charger un fichier de script existant."
#: editor/script_create_dialog.cpp
msgid "Language"
@@ -10304,7 +10467,7 @@ msgstr "Définir depuis l'arbre"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Exporter les mesures en CSV"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10319,6 +10482,10 @@ msgid "Change Shortcut"
msgstr "Modifier le raccourci"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Paramètres de l'éditeur"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Raccourcis"
@@ -10436,12 +10603,11 @@ msgstr "GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr ""
+msgstr "Activé le Singleton GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "Désactiver l'indicateur d'activité"
+msgstr "Désactiver le Singleton GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -10532,9 +10698,8 @@ msgid "GridMap Fill Selection"
msgstr "Remplissage de la sélection de GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "Suppression de la sélection de GridMap"
+msgstr "GridMap Coller la sélection"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -10743,10 +10908,31 @@ msgid "Set Variable Type"
msgstr "Définir type de variable"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ne doit pas entrer en conflit avec un nom de type existant intégré au moteur."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Créer un nouveau rectangle."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variables :"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Créer un nouveau rectangle."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Créer un nouveau polygone."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Le nom n'est pas un identifiant valide :"
@@ -10915,9 +11101,8 @@ msgid "Available Nodes:"
msgstr "NÅ“uds disponibles :"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Select or create a function to edit its graph."
-msgstr "Sélectionnez ou créez une fonction pour modifier le graphe"
+msgstr "Sélectionnez ou créez une fonction pour modifier son graphe."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
@@ -10936,10 +11121,6 @@ msgid "Cut Nodes"
msgstr "Couper les nœuds"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Coller les nœuds"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Modifier le membre"
@@ -11060,15 +11241,21 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"La création d'une version personnalisée nécessite un chemin d'accès Android "
+"SDK valide dans les paramètres de l'éditeur."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"Chemin d'accès invalide au SDK Android pour le build custom dans les "
+"paramètres de l'éditeur."
#: platform/android/export/export.cpp
msgid ""
"Android project is not installed for compiling. Install from Editor menu."
msgstr ""
+"Le projet Android n'est pas installé et ne peut donc pas être compilé. "
+"Installez-le depuis le menu Éditeur."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -11083,6 +11270,9 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"A essayé de construire à partir d'un modèle personnalisé, mais aucune "
+"information de version n'existe pour lui. Veuillez réinstaller à partir du "
+"menu 'Projet'."
#: platform/android/export/export.cpp
msgid ""
@@ -11094,17 +11284,21 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "Construire le Project 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 construction du projet Android a échoué, vérifiez la sortie pour "
+"l'erreur.\n"
+"Sinon, visitez docs.godotengine.org pour la documentation de construction "
+"Android."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "Aucune build apk générée à : "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -11237,13 +11431,12 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
"Une ressource SpriteFrames doit être créée ou assignée à la propriété « "
-"Frames » afin qu'AnimatedSprite affiche les images."
+"Frames » afin qu'AnimatedSprite affiche les frames."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11305,13 +11498,12 @@ 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\" "
"property."
msgstr ""
"Une texture avec la forme de la lumière doit être fournie dans la propriété "
-"« texture »."
+"« Texture »."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11321,11 +11513,10 @@ msgstr ""
"occulteur ait un effet."
#: scene/2d/light_occluder_2d.cpp
-#, 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 !"
+"polygone."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11429,51 +11620,44 @@ msgstr ""
"etc."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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."
+"Un VisibilityEnabler2D fonctionne mieux lorsqu'il est directement enfant du "
+"nœud racine de la scène éditée."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera doit avoir un nœud ARVROrigin comme parent"
+msgstr "ARVRCamera doit avoir un nœud ARVROrigin comme parent."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr "ARVRController doit avoir un nœud ARVROrigin comme parent"
+msgstr "ARVRController doit avoir un nœud ARVROrigin comme parent."
#: 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 ""
-"L'identifiant contrôleur ne doit pas être 0 ou ce contrôleur ne sera pas lié "
-"à un contrôleur valide"
+"L'identifiant contrôleur ne doit pas être 0 ou ce contrôleur ne sera lié à "
+"aucun contrôleur."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ARVRAnchor doit avoir un nœud ARVROrigin comme parent"
+msgstr "ARVRAnchor doit avoir un nœud ARVROrigin comme parent."
#: 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 ""
"L'identifiant d'ancrage ne doit pas être 0 ou cette ancre ne sera pas liée à "
-"une ancre valide"
+"une ancre valide."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin requiert un nœud enfant ARVRCamera"
+msgstr "ARVROrigin requiert un nœud enfant ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -11533,13 +11717,12 @@ 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."
msgstr ""
-"Une CollisionShape nécessite une forme pour fonctionner. Créez une ressource "
-"de forme pour cette CollisionShape !"
+"Une CollisionShape nécessite une forme pour fonctionner. Veuillez créer une "
+"ressource de forme pour cette CollisionShape."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11554,7 +11737,6 @@ msgid "Nothing is visible because no mesh has been assigned."
msgstr "Rien n'est visible car aucun maillage n'a été assigné."
#: scene/3d/cpu_particles.cpp
-#, fuzzy
msgid ""
"CPUParticles animation requires the usage of a SpatialMaterial whose "
"Billboard Mode is set to \"Particle Billboard\"."
@@ -11577,6 +11759,8 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Une SpotLight avec un angle supérieur à 90 degrés ne peut pas projeter "
+"d'ombres."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11611,12 +11795,11 @@ msgstr ""
"passes."
#: scene/3d/particles.cpp
-#, fuzzy
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
-"L'animation de Particles a besoin d'un SpatialMaterial avec « Billboard "
+"L'animation de particules a besoin d'un SpatialMaterial avec « Billboard "
"Particles » activé."
#: scene/3d/path.cpp
@@ -11626,7 +11809,6 @@ msgstr ""
"nœud de type Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
@@ -11645,17 +11827,16 @@ msgstr ""
"Modifiez la taille dans les formes de collision enfants à la place."
#: scene/3d/remote_transform.cpp
-#, 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."
+"La propriété \"Remote Path\" doit pointer vers un nœud valide Spatial ou "
+"dérivé de Spatial pour fonctionner."
#: scene/3d/soft_body.cpp
-#, fuzzy
msgid "This body will be ignored until you set a mesh."
-msgstr "Ce corps sera ignoré jusqu'à ce que vous définissiez un maillage"
+msgstr "Ce corps sera ignoré jusqu'à ce que vous définissiez un maillage."
#: scene/3d/soft_body.cpp
msgid ""
@@ -11668,12 +11849,11 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Une ressource de type SampleFrames doit être créée ou définie dans la "
+"Une ressource de type SpriteFrames doit être créée ou définie dans la "
"propriété « Frames » afin qu'une AnimatedSprite3D fonctionne."
#: scene/3d/vehicle_body.cpp
@@ -11689,6 +11869,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment exige que sa propriété \"Environment\" contienne un "
+"Environment pour avoir un effet visible."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11727,9 +11909,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
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "Un AnimationNode racine pour le graphique n'est pas défini."
+msgstr "Aucun AnimationNode racine pour le graphique n'est défini."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11743,7 +11924,6 @@ msgstr ""
"Le chemin défini pour AnimationPlayer ne mène pas à un nœud AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
msgstr "La racine AnimationPlayer n'est pas un nœud valide."
@@ -11757,12 +11937,11 @@ msgstr "Échantillonner une couleur depuis l'écran."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "Lacet (hauteur)"
+msgstr "Brut"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11773,7 +11952,6 @@ msgid "Add current color as a preset."
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 its "
"children placement behavior.\n"
@@ -11782,13 +11960,16 @@ 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'."
+"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 ""
+"L'outil d'aide ne s'affiche pas car le filtre de contrôle de la souris est "
+"réglé sur \"Ignorer\". Pour résoudre ce problème, réglez le filtre de la "
+"souris sur \"Stop\" ou \"Pass\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
@@ -11799,31 +11980,28 @@ 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, but they will hide upon "
"running."
msgstr ""
-"Les pop-ups seront cachés par défaut jusqu'à ce que vous appelez une "
+"Les pop-ups seront cachées par défaut jusqu'à ce que vous appeliez une "
"fonction popup() ou une des fonctions popup*(). Les rendre visibles pour "
"l'édition ne pose pas de problème, mais elles seront cachées lors de "
"l'exécution."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Si « Exp Edit » est vrai, « Min Value » doit être supérieur à 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 "
"minimum size manually."
msgstr ""
"ScrollContainer est conçu pour fonctionner avec un unique nœud enfant de "
-"type contrôle.\n"
+"type Control.\n"
"Utilisez un conteneur comme enfant (VBox, HBox, etc.) ou un Control et "
"définissez manuellement la taille minimale personnalisée."
@@ -11851,35 +12029,22 @@ msgstr ""
"nœud de type Control afin qu'il en obtienne une taille. Sinon, faites-en une "
"RenderTarget et assignez sa texture à un nœud pouvant l'afficher."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Erreur à l'initialisation de Freetype."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Format de police inconnu."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Erreur lors du chargement de la police."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Taille de police invalide."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrée"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Source invalide pour la forme."
+msgstr "Source invalide pour la prévisualisation."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Source invalide pour la forme."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Fonction de comparaison invalide pour ce type."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Affectation à la fonction."
@@ -11894,7 +12059,126 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex."
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Les constantes ne peuvent être modifiées."
+
+#~ msgid "No Matches"
+#~ msgstr "Pas de correspondances"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Impossible d'ouvrir file_type_cache.cch en écriture, le fichier de cache "
+#~ "ne sera pas sauvé !"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Impossible d'accéder à « %s » car celui-ci n'existe pas dans le système "
+#~ "de fichiers !"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Erreur de chargement d'image :"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Pas de pixels avec transparence > 128 dans l'image..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Le parent n'a pas de faces solides à peupler."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Impossible de cartographier la zone."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Des faces ne contiennent pas de zone !"
+
+#~ msgid "No faces!"
+#~ msgstr "Pas de faces !"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Erreur de chargement de fichier."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Activer Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Sélectionner le mode (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Move déplacement (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Mode rotation (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Mode de mise à l'échelle (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordonnées locales"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Mode d'aimantation (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Outil sélection"
+
+#~ msgid "Tool Move"
+#~ msgstr "Outil déplacement"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Outil rotation"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Outil échelle"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Supprimer tous les projets manquants de la liste ? (Le contenu des "
+#~ "dossiers ne sera pas modifié)"
+
+#~ msgid "Project List"
+#~ msgstr "Liste des projets"
+
+#~ msgid "Exit"
+#~ msgstr "Quitter"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Impossible d'exécuter l'outil PVRTC :"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "L'image convertie n'a pas pu être rechargée en utilisant l'outil PVRTC :"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Erreur à l'initialisation de Freetype."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Format de police inconnu."
+
+#~ msgid "Error loading font."
+#~ msgstr "Erreur lors du chargement de la police."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Taille de police invalide."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Dossier précédent"
+
+#~ msgid "Next Folder"
+#~ msgstr "Dossier suivant"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Ouvrir l'éditeur suivant"
+
+#~ msgid "Reverse"
+#~ msgstr "Inverser"
+
+#~ msgid "Mirror X"
+#~ msgstr "Miroir X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Miroir Y"
#~ msgid "Generating solution..."
#~ msgstr "Génération de la solution en cours..."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
new file mode 100644
index 0000000000..9f7166b719
--- /dev/null
+++ b/editor/translations/ga.po
@@ -0,0 +1,11327 @@
+# Irish translation of the Godot Engine editor
+# Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
+# This file is distributed under the same license as the Godot source code.
+# Rónán Quill <ronan085@gmail.com>, 2019.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2019-08-04 14:22+0000\n"
+"Last-Translator: Rónán Quill <ronan085@gmail.com>\n"
+"Language-Team: Irish <https://hosted.weblate.org/projects/godot-engine/godot/"
+"ga/>\n"
+"Language: ga\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :"
+"(n>6 && n<11) ? 3 : 4;\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 ""
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+msgid "Create"
+msgstr "Cruthaigh"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp 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 ""
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "FPS"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+#: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr ""
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select tracks to copy:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replaced %d occurrence(s)."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr ""
+
+#: editor/code_editor.cpp editor/rename_dialog.cpp
+msgid "Replace"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr "Cuardach:"
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr "Cuntas:"
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr "Acmhainn"
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_settings_editor.cpp editor/script_create_dialog.cpp
+msgid "Path"
+msgstr "Cosán"
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr "Oscailte"
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Remove selected files from the project? (Can't be restored)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio Bus, Drag and Drop to rearrange."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Enable"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Not in resource path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr ""
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem and Import Docks"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "New Folder..."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Refresh"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/inspector_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Hidden Files"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Preview:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr ""
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr ""
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+msgid "Inherits:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Brief Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "enum "
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There are currently no tutorials for this class, you can [color=$color][url="
+"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
+"url][/color]."
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr ""
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr ""
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr ""
+
+#: editor/editor_log.cpp editor/editor_profiler.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project export failed with error code %d."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error trying to save layout!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Default editor layout overridden."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Restored default layout to base settings."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene was never saved, please save it prior to running."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr ""
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "No"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This scene has never been saved. Save before running?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This action cannot be undone. Revert anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr ""
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When exporting or deploying, the resulting executable will attempt to "
+"connect to the IP of this computer in order to be debugged."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network FS"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, export or deploy will produce a minimal "
+"executable.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploy will use the USB cable for faster performance. This "
+"option speeds up testing for games with a large footprint."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: 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 ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Navigation meshes and polygons will be visible on the running game if this "
+"option is turned on."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Scene Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any changes made to the scene in the editor "
+"will be replicated in the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Script Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any script that is saved will be reloaded on "
+"the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle Fullscreen"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle System Console"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data/Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
+msgid "Search"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Issue Tracker"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause the scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_profiler.cpp
+msgid "Stop"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Node"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr ""
+
+#: editor/editor_node.cpp scene/resources/visual_shader.cpp
+msgid "Output"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will install the Android project for custom builds.\n"
+"Note that, in order to use it, it needs to be enabled per export preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+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 ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_export.cpp
+msgid "Export Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Password:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr ""
+
+#: editor/editor_profiler.cpp editor/plugins/animation_state_machine_editor.cpp
+#: editor/rename_dialog.cpp
+msgid "Start"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr ""
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the export menu."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "There is already file or folder with the same name in this location."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Cruthaigh"
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Search complete"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Scrios ionchur"
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid " Files"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr ""
+
+#: editor/import_dock.cpp editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Save scenes, re-import and restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr ""
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Language:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node Moved"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Error!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr "Athrú: "
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr "CrannBeochan"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr "Ainm nua:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr "Scála:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr "Cumaisc"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr "Measc"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr "Tosaigh!"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr "Méid:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr "Cumaisc 0:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr "Cumaisc 1:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Add Input"
+msgstr "Cuir ionchur leis"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr "Scrios ionchur"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr "Tá crann beochana bailí."
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr "Tá an crann beochana neamhbhailí."
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr "Nód Beochana"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr "Nód UrcharAmháin"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr "Nód Measc"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr "Nód Cumaisc2"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr "Nód Cumaisc3"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr "Nód Cumaisc4"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr "Scagairí..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr "Ãbhar:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr "Amharc ar Chomhaid"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed sha256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Reverse sorting."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/project_settings_editor.cpp
+msgid "Category:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene (for images to be saved in the same dir), or pick a save "
+"path from the BakedLightmap properties."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move pivot"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated 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 ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr ""
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Convex Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Failed creating shapes!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Shape(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Collision Sibling(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr ""
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon->UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV->Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Type:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Request Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Help improve the Godot documentation by giving feedback."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Source"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "(ignore)"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "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
+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
+msgid "Delete Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed (FPS):"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Icon"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete patch '%s' from list?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files from project (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Patches"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Make Patch"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path does not exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a 'project.godot' or '.zip' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Directory already contains a Godot project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr "OpenGL ES 3.0"
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr "OpenGL ES 2.0"
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Shift+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Alt+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Control+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per Level counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set the counter restarts for each group of child nodes"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "CamelCase to under_scored"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "under_scored to CamelCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Error"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear a script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script is valid."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Language"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Inherits"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Template"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Child Process Connected"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video Mem"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr ""
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Base Type:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Available Nodes:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "ADB executable not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgstr ""
+
+#: 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."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "No build apk generated at: "
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr "Tá aitheantóir ar iarraidh."
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier segments must be of non-zero length."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "A digit cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid ""
+"The character '%s' cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The Identifier must have at least one '.' separator."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "%d%%"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "(Time Left: %d:%02d s)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Meshes: "
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Lights:"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Lighting Meshes: "
+msgstr ""
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"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 ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the screen."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr ""
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+
+#: scene/resources/visual_shader.cpp
+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 ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr "Ní féidir tairisigh a athrú."
diff --git a/editor/translations/he.po b/editor/translations/he.po
index eadb7cad94..4847730e69 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -9,12 +9,13 @@
# RaikaRakka <shaiyatta@gmail.com>, 2018.
# Ido Dana <idodana01@gmail.com>, 2019.
# Daniel Dovgun <daniel.dovgun@gmail.com>, 2019.
+# MordechaiHadad <Mordechai.hadad01@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:49+0000\n"
-"Last-Translator: Daniel Dovgun <daniel.dovgun@gmail.com>\n"
+"PO-Revision-Date: 2019-08-11 10:23+0000\n"
+"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/"
"godot/he/>\n"
"Language: he\n"
@@ -28,7 +29,7 @@ msgstr ""
#: 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 ""
+msgstr "משתנה סוג ×œ× ×—×•×§×™ לפונקציית convert()‎, יש להשתמש בקבועי TYPE_*‎."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -67,7 +68,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Free"
msgstr "×—×™× ×"
@@ -142,6 +142,31 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "שינוי זמן פריי×-מפתח ×נימציה"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "שינוי ×ž×™×§×•× ×נימציה"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "שינוי ×ž×™×§×•× ×נימציה"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "שינוי ערך ×§×™×¤×¨×™×™× ×נימציה"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "שינוי ×ž×™×§×•× ×נימציה"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "שנה ×ורך ×נימציה"
@@ -661,17 +686,18 @@ msgid "Line Number:"
msgstr "מספר השורה:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "×ין תוצ×ות"
-
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+msgid "%d match."
msgstr ""
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "×ין תוצ×ות"
+
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "הת×מת רישיות"
@@ -903,8 +929,7 @@ msgstr "מועדפי×:"
msgid "Recent:"
msgstr "×חרוני×:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -999,7 +1024,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "×œ× × ×™×ª×Ÿ להסיר:"
@@ -1037,7 +1062,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr "תלויות"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "דפדפן מש××‘×™× ×™×ª×•×ž×™×"
@@ -1126,14 +1151,15 @@ msgid "License"
msgstr "רישיון"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "רישיון צד שלישי"
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1150,7 +1176,8 @@ msgid "Licenses"
msgstr "רישיונות"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "פתיחת קובץ החבילה נכשלה, המבנה ×ינו zip."
#: editor/editor_asset_installer.cpp
@@ -1168,7 +1195,6 @@ msgid "Success!"
msgstr "הצלחה!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "התקנה"
@@ -1659,12 +1685,11 @@ msgid "New"
msgstr "חדש"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "ייבו×"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "ייצו×"
@@ -1734,7 +1759,7 @@ msgstr "הצגה במנהל הקבצי×"
msgid "New Folder..."
msgstr "תיקייה חדשה…"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "רענון"
@@ -1785,7 +1810,7 @@ msgstr "התקדמות קדימה"
msgid "Go Up"
msgstr "עלייה למעלה"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "החלפת מצב תצוגה ×œ×§×‘×¦×™× ×ž×•×¡×ª×¨×™×"
@@ -1811,27 +1836,32 @@ msgstr "העברת מועדף למטה"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "המישור הקוד×"
+msgid "Go to previous folder."
+msgstr "מעבר לתיקייה שמעל"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "יצירת תיקייה"
+msgid "Go to next folder."
+msgstr "מעבר לתיקייה שמעל"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "מעבר לתיקייה שמעל"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "חיפוש במחלקות"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "×œ× × ×™×ª×Ÿ ליצור תיקייה."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "החלפת מצב תצוגה ×œ×§×‘×¦×™× ×ž×•×¡×ª×¨×™×"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2085,6 +2115,10 @@ msgstr "מחיקה"
msgid "Clear Output"
msgstr "מחיקת הפלט"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2389,6 +2423,15 @@ msgid "Pick a Main Scene"
msgstr "× × ×œ×‘×—×•×¨ סצנה ר×שית"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "סגירת סצנה"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "סגירת סצנה"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "×œ× × ×™×ª×Ÿ לפתוח ×ת תוסף ההרחבות תחת: ‚%s’ פענוח ההגדרות נכשל."
@@ -2485,6 +2528,11 @@ msgstr "נגינת הסצנה"
msgid "Close Tab"
msgstr "לסגור לשוניות ×חרות"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "לסגור לשוניות ×חרות"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "לסגור לשוניות ×חרות"
@@ -2539,6 +2587,11 @@ msgid "Go to previously opened scene."
msgstr "מעבר לסצנה שנפתחה ×§×•×“× ×œ×›×Ÿ."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "העתקת נתיב"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "הלשונית הב××”"
@@ -2566,6 +2619,10 @@ msgstr "סצנה חדשה בירושה…"
msgid "Open Scene..."
msgstr "פתיחת סצנה…"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "פתיחה מה×חרוני×"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "שמירת סצנה"
@@ -2576,14 +2633,6 @@ msgid "Save All Scenes"
msgstr "שמירת כל הסצנות"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "סגירת סצנה"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "פתיחה מה×חרוני×"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "המרה ×ל…"
@@ -2613,26 +2662,37 @@ msgstr "שחזור סצנה"
msgid "Miscellaneous project or scene-wide tools."
msgstr "×›×œ×™× ×©×•× ×™× ×œ×ž×™×–× ×ו למגוון סצנות."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "מיז×"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "הגדרות מיז×"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "כלי×"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "ייצו×"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "לפתוח ×ת מנהל המיזמי×?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "כלי×"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "דפדפן מש××‘×™× ×™×ª×•×ž×™×"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2713,12 +2773,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "עורך"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "הגדרות עורך"
#: editor/editor_node.cpp
@@ -2736,15 +2797,6 @@ 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 "כניסה ×ל/יצי××” ממסך מל×"
@@ -2769,14 +2821,15 @@ msgstr "הגדרות עורך"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "ניהול תבניות ייצו×"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "ניהול תבניות ייצו×"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "עזרה"
@@ -2784,12 +2837,13 @@ msgstr "עזרה"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "חיפוש"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "×ž×¡×ž×›×™× ×ž×§×•×•× ×™×"
@@ -3070,6 +3124,11 @@ msgstr "זמן"
msgid "Calls"
msgstr "קרי×ות"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "חברי×"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3233,7 +3292,8 @@ msgid "Import From Node:"
msgstr "×™×™×‘×•× ×ž×ž×¤×¨×§:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "הורדה מחדש"
#: editor/export_template_manager.cpp
@@ -3250,6 +3310,10 @@ msgid "Download"
msgstr "הורדה"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(חסר)"
@@ -3312,12 +3376,10 @@ msgid "No response."
msgstr "×ין תגובה."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "הבקשה נכשלה."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "לול×ת הפניות."
@@ -3331,13 +3393,19 @@ msgid "Download Complete."
msgstr "ההורדה הושלמה."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "×œ× × ×™×ª×Ÿ להסיר:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "שגי××” בבקשת כתובת: "
#: editor/export_template_manager.cpp
@@ -3424,21 +3492,12 @@ msgstr "הורדת תבניות"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "בחירת ×תר מר××” מהרשימה: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"×œ× × ×™×ª×Ÿ לפתוח ×ת file_type_cache.cch לכתיבה, מטמון סוג ×”×§×‘×¦×™× ×œ× ×™×™×©×ž×¨!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "מועדפי×:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "×œ× × ×™×ª×Ÿ לנווט ×ל ‚%s’ כיוון ×©×œ× × ×ž×¦× ×‘×ž×¢×¨×›×ª הקבצי×!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "מצב: ×™×™×‘×•× ×”×§×•×‘×¥ נכשל. × × ×œ×ª×§×Ÿ ×ת הקובץ ×•×œ×™×™×‘× ×ž×—×“×© ידנית."
@@ -3472,14 +3531,14 @@ msgid "Provided name contains invalid characters."
msgstr "×”×©× ×©×¡×•×¤×§ מכיל ×ª×•×•×™× ×©×’×•×™×™×"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "×”×©× ×ž×›×™×œ ×ª×•×•×™× ×©×’×•×™×™×."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "כבר ×§×™×™×ž×™× ×§×•×‘×¥ ×ו תיקייה ×‘×©× ×”×–×”."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "×”×©× ×ž×›×™×œ ×ª×•×•×™× ×©×’×•×™×™×."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "שינוי ×©× ×”×§×•×‘×¥:"
@@ -3539,6 +3598,11 @@ msgstr "שכפול…"
msgid "Move To..."
msgstr "העברה ×ל…"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "סצנה חדשה"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3613,6 +3677,11 @@ msgstr "כבר ×§×™×™×ž×™× ×§×•×‘×¥ ×ו תיקייה ×‘×©× ×”×–×”."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "שמירת סצנה"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "יצירת סקריפט"
@@ -3681,6 +3750,14 @@ msgid "Search complete"
msgstr "חיפוש טקסט"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "הוספה לקבוצה"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "הסרה מקבוצה"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "הפעולה ‚%s’ כבר קיימת!"
@@ -3690,13 +3767,23 @@ msgstr "הפעולה ‚%s’ כבר קיימת!"
msgid "Invalid group name."
msgstr "×©× ×©×’×•×™."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "קבוצות"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "מחיקת שורה"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "קבוצות"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "הוספה לקבוצה"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3710,12 +3797,13 @@ msgid "Nodes in Group"
msgstr "הוספה לקבוצה"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "הוספה לקבוצה"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "הסרה מקבוצה"
+#, fuzzy
+msgid "Group Editor"
+msgstr "פתיחת עורך סקריפטי×"
#: editor/groups_editor.cpp
#, fuzzy
@@ -3926,7 +4014,8 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "יש לבחור מפרק כדי לערוך ×ותות וקבוצות."
#: editor/plugin_config_dialog.cpp
@@ -4715,10 +4804,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4731,14 +4816,47 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "הבקשה נכשלה."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "×œ× × ×™×ª×Ÿ להסיר:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "לול×ת הפניות."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "הבקשה נכשלה."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "זמן"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4781,6 +4899,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "התקנה"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4810,13 +4933,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "ייבו×"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4824,8 +4950,9 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr ""
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "מוגשת בקשה…"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4837,8 +4964,9 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
-msgstr ""
+#, fuzzy
+msgid "Support"
+msgstr "ייבו×"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -4849,6 +4977,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "טעינה"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4899,31 +5032,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "יצירת תיקייה"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "הסרת מפתחות שגויי×"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "יצירת תיקייה"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "הסרת מפתחות שגויי×"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5010,6 +5147,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "נגינת סצנה בהת×מה ×ישית"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "נגינת סצנה בהת×מה ×ישית"
@@ -5040,6 +5182,7 @@ msgid "Zoom Reset"
msgstr "להתרחק"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5060,14 +5203,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "מצב שינוי קנה מידה (R)"
@@ -5093,6 +5239,7 @@ msgid "Toggle snapping."
msgstr "החלפת מצב נקודת עצירה"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5110,11 +5257,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "הגדרת הצמדה…"
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5127,6 +5269,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "הגדרת הצמדה…"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5343,16 +5490,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5672,14 +5809,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5765,19 +5894,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6115,7 +6248,6 @@ msgid "Grid Settings"
msgstr "הגדרות"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "הצמדה"
@@ -6225,12 +6357,7 @@ msgstr "שגי××” ×‘×™×™×‘×•× ×¢×¨×›×ª הנוש×"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "×œ× × ×™×ª×Ÿ ליצור תיקייה."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "×œ× × ×™×ª×Ÿ ליצור תיקייה."
#: editor/plugins/script_editor_plugin.cpp
@@ -6260,7 +6387,7 @@ msgstr "שגי××” בייבו×"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "תיקייה חדשה…"
#: editor/plugins/script_editor_plugin.cpp
@@ -6346,6 +6473,11 @@ msgid "Open..."
msgstr "פתיחה"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "הרצת סקריפט"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "לשמור הכול"
@@ -6385,13 +6517,13 @@ msgid "Save Theme"
msgstr "שמירת ערכת העיצוב"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "סגירת מסמכי×"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "לסגור הכול"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "סגירת מסמכי×"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "הרצה"
@@ -6482,6 +6614,11 @@ msgstr "ניפוי שגי×ות"
msgid "Search Results"
msgstr "חיפוש בעזרה"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "מחיקת ×§×‘×¦×™× ×חרוני×"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6553,6 +6690,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6588,26 +6726,6 @@ msgid "Toggle Comment"
msgstr "החלפת מצב הערה"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "החלפת מצב מבט חופשי"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "מעבר לנקודת העצירה הב××”"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "מעבר לנקודת העצירה הקודמת"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "הסרת כל נקודות העצירה"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "צמצו×/הרחבה של שורה"
@@ -6628,6 +6746,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "בחירת מיקוד"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6646,32 +6769,37 @@ msgid "Auto Indent"
msgstr "×”×–×—×” ×וטומטית"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "החלפת מצב נקודת עצירה"
+msgid "Find Previous"
+msgstr "×יתור הקוד×"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "הסרת כל נקודות העצירה"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "×יתור…"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "עזרה תלוית הקשר"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "מעבר לנקודת העצירה הב××”"
+msgid "Toggle Bookmark"
+msgstr "החלפת מצב מבט חופשי"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "מעבר לנקודת העצירה הקודמת"
+msgid "Go to Next Bookmark"
+msgstr "מעבר לנקודת העצירה הב××”"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "×יתור הקוד×"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "מעבר לנקודת העצירה הקודמת"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "×יתור…"
+msgid "Remove All Bookmarks"
+msgstr "הסרת כל נקודות העצירה"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6684,8 +6812,23 @@ msgid "Go to Line..."
msgstr "מעבר לשורה…"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "עזרה תלוית הקשר"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "החלפת מצב נקודת עצירה"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "הסרת כל נקודות העצירה"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "מעבר לנקודת העצירה הב××”"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "מעבר לנקודת העצירה הקודמת"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6871,7 +7014,12 @@ msgstr "×חורי"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr "יישור ×¢× ×”×ª×¦×•×’×”"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr "יישור ×¢× ×”×ª×¦×•×’×”"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6928,8 +7076,9 @@ msgid "Audio Listener"
msgstr "מ×זין לשמע"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "שינוי"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6983,8 +7132,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "בחירת מצב (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6997,30 +7146,11 @@ msgstr ""
"Alt+כפתור ימני: בחירת רשימת עומק"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "מצב הזזה (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "מצב הטיה (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "מצב שינוי קנה מידה (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "נקודות ציון מקומיות"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "מצב מרחב מקומי (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "מצב הצמדה (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "מבט תחתי"
@@ -7062,26 +7192,6 @@ msgid "Focus Selection"
msgstr "בחירת מיקוד"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "החלפת מצב מבט חופשי"
@@ -7136,7 +7246,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "הגדרות"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7446,10 +7557,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7538,11 +7645,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7651,14 +7758,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7672,8 +7771,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7987,6 +8086,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "הוספת ×ירוע"
@@ -8075,6 +8178,11 @@ msgid "Duplicate Nodes"
msgstr "שכפול"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "הדבקת מפרקי×"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "מחיקת שורה"
@@ -8099,6 +8207,11 @@ msgstr "ימין"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "יצירת תיקייה"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "יצירת תיקייה"
@@ -8174,6 +8287,22 @@ msgid "Color uniform."
msgstr "התמרה"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8181,10 +8310,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8274,7 +8437,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8282,7 +8445,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8294,7 +8457,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8311,7 +8474,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8380,11 +8543,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8400,7 +8563,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8411,7 +8574,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8420,7 +8583,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8428,11 +8591,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8473,11 +8636,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8487,7 +8654,7 @@ msgstr "התמרה"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8505,15 +8672,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8565,7 +8732,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8580,6 +8747,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8593,19 +8764,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8614,7 +8785,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8623,14 +8794,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8675,47 +8846,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8889,6 +9067,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "ניהול תבניות ייצו×"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9037,6 +9219,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "מיז×"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "×œ× × ×™×ª×Ÿ לפתוח ×ת ‚%s’."
@@ -9106,8 +9297,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9130,8 +9321,9 @@ msgid "Project Manager"
msgstr "מנהל המיזמי×"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "רשימת המיזמי×"
+#, fuzzy
+msgid "Projects"
+msgstr "מיז×"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9155,10 +9347,6 @@ msgid "Templates"
msgstr "תבניות"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "יצי××”"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "להפעיל מחדש כעת"
@@ -9502,6 +9690,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9554,14 +9746,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9863,6 +10047,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "שינוי ×©× ×§×œ×˜"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9909,6 +10098,11 @@ msgstr "הרצת סקריפט"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "יצירת %s חדש"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "שמירת סצנה"
@@ -9985,19 +10179,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10095,6 +10289,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10127,7 +10325,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10291,6 +10489,10 @@ msgid "Change Shortcut"
msgstr "שינוי הערה"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "הגדרות עורך"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10705,10 +10907,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "×©× ×©×’×•×™. ×œ× ×™×›×•×œ לחפוף ×œ×©× ×¡×•×’ מובנה קיי×."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "יצירת %s חדש"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "יצירת %s חדש"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "יצירת מצולע"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10896,10 +11118,6 @@ msgid "Cut Nodes"
msgstr "גזירת מפרקי×"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "הדבקת מפרקי×"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "חברי×"
@@ -11646,22 +11864,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "מבנה הגופן ×œ× ×™×“×•×¢."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "שגי××” בטעינת הגופן."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "גודל הגופן שגוי."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11676,6 +11878,11 @@ msgstr "גודל הגופן שגוי."
msgid "Invalid source for shader."
msgstr "גודל הגופן שגוי."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "גודל הגופן שגוי."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11692,6 +11899,63 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "×œ× × ×™×ª×Ÿ לפתוח ×ת file_type_cache.cch לכתיבה, מטמון סוג ×”×§×‘×¦×™× ×œ× ×™×™×©×ž×¨!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "×œ× × ×™×ª×Ÿ לנווט ×ל ‚%s’ כיוון ×©×œ× × ×ž×¦× ×‘×ž×¢×¨×›×ª הקבצי×!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "×œ× × ×™×ª×Ÿ ליצור תיקייה."
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "בחירת מצב (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "מצב הזזה (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "מצב הטיה (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "מצב שינוי קנה מידה (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "נקודות ציון מקומיות"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "מצב הצמדה (%s)"
+
+#~ msgid "Project List"
+#~ msgstr "רשימת המיזמי×"
+
+#~ msgid "Exit"
+#~ msgstr "יצי××”"
+
+#~ msgid "Unknown font format."
+#~ msgstr "מבנה הגופן ×œ× ×™×“×•×¢."
+
+#~ msgid "Error loading font."
+#~ msgstr "שגי××” בטעינת הגופן."
+
+#~ msgid "Invalid font size."
+#~ msgstr "גודל הגופן שגוי."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "המישור הקוד×"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "יצירת תיקייה"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "פתיחת העורך הב×"
+
#~ msgid "Generating solution..."
#~ msgstr "הפתרון נוצר…"
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 7fa0ae91a0..d4030266c5 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -61,7 +61,6 @@ msgid "On call to '%s':"
msgstr "'%s ' को कॉल करने पर:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "मà¥à¤«à¥à¤¤"
@@ -136,6 +135,31 @@ msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ बà¥à¤²à¤¾à¤µà¤¾"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ निधि"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ बà¥à¤²à¤¾à¤µà¤¾"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ परिणत"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ मà¥à¤–à¥à¤¯-फ़à¥à¤°à¥‡à¤® मूलà¥à¤¯(Value) बदलें"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ बà¥à¤²à¤¾à¤µà¤¾"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "शबà¥à¤¦ बदलें मूलà¥à¤¯"
@@ -637,16 +661,17 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr ""
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "à¤à¤• जैसा:"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -889,8 +914,7 @@ msgstr "पसंदीदा:"
msgid "Recent:"
msgstr "हाल ही में किया:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
@@ -997,7 +1021,7 @@ msgstr ""
"निकाली गई फ़ाइलों को दूसरे संसाधनों दà¥à¤µà¤¾à¤°à¤¾ उनके लिठकाम करने के लिठआवशà¥à¤¯à¤• है\n"
"वैसे भी उनà¥à¤¹à¥‡à¤‚ निकालें? (कोई पूरà¥à¤µà¤µà¤¤ नहीं)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "निकाला नहीं जा सकता:\n"
@@ -1036,7 +1060,7 @@ msgstr "%d आइटम को सà¥à¤¥à¤¾à¤¯à¥€ रूप से हटाà¤à
msgid "Show Dependencies"
msgstr "निरà¥à¤­à¤°à¤¤à¤¾"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Orphan Resource Explorer"
msgstr "Orphan Resource Explorer"
@@ -1129,14 +1153,15 @@ msgstr "License"
#: editor/editor_about.cpp
#, fuzzy
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr "Thirdparty License"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"गोडोट इंजन तीसरे पकà¥à¤· के सà¥à¤µà¤¤à¤‚तà¥à¤° और खà¥à¤²à¥‡ सà¥à¤°à¥‹à¤¤ पà¥à¤¸à¥à¤¤à¤•à¤¾à¤²à¤¯à¥‹à¤‚ पर निरà¥à¤­à¤° करता है, जो कि इसके "
@@ -1157,7 +1182,8 @@ msgid "Licenses"
msgstr "Licenses"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "पैकेज फ़ाइल खोलने में तà¥à¤°à¥à¤Ÿà¤¿, zip पà¥à¤°à¤¾à¤°à¥‚प में नहीं |"
#: editor/editor_asset_installer.cpp
@@ -1175,7 +1201,6 @@ msgid "Success!"
msgstr "सफलता!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "इंसà¥à¤Ÿà¥‰à¤²"
@@ -1653,12 +1678,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1721,7 +1745,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1772,7 +1796,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1797,23 +1821,28 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "खोज कर:"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2054,6 +2083,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2351,6 +2384,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "खोलो इसे"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2445,6 +2487,11 @@ msgstr ""
msgid "Close Tab"
msgstr "बंद करे"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "बंद करे"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2499,6 +2546,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "सभी खंड"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2526,20 +2578,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2572,16 +2620,20 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2589,11 +2641,16 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•"
-#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Orphan Resource Explorer"
+
+#: editor/editor_node.cpp
msgid "Quit to Project List"
msgstr ""
@@ -2670,13 +2727,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "अनà¥à¤µà¤¾à¤¦ में बदलाव करें:"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2691,14 +2749,6 @@ 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 ""
@@ -2719,14 +2769,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2734,12 +2784,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3011,6 +3062,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "परिवरà¥à¤¤à¤¨ वकà¥à¤° चयन"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3174,7 +3230,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3191,6 +3247,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3252,12 +3312,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3271,14 +3329,20 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "निकाला नहीं जा सकता:\n"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
-msgstr ""
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "लोड होने मे तà¥à¤°à¥à¤Ÿà¤¿:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3365,20 +3429,12 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "पसंदीदा:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3414,11 +3470,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3483,6 +3539,11 @@ msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "संसाधन"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3548,6 +3609,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "à¤à¤• नया बनाà¤à¤‚"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3609,6 +3675,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3617,12 +3691,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "ऑडियो बस का नाम बदलें"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "को हटा दें"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3635,12 +3719,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "निरà¥à¤­à¤°à¤¤à¤¾ संपादक"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3847,7 +3932,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4609,10 +4694,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4625,14 +4706,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "निकाला नहीं जा सकता:\n"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4673,6 +4783,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "इंसà¥à¤Ÿà¥‰à¤²"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4701,13 +4816,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4715,7 +4832,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4728,7 +4845,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4740,6 +4857,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "खोज कर:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4790,31 +4912,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "à¤à¤• नया बनाà¤à¤‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "मिटाना"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "à¤à¤• नया बनाà¤à¤‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "मिटाना"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4896,6 +5022,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ परिणत"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4926,6 +5057,7 @@ msgid "Zoom Reset"
msgstr "छोटा करो"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4946,14 +5078,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4977,6 +5112,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4993,11 +5129,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5010,6 +5141,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5219,16 +5355,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5543,14 +5669,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5634,19 +5752,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5978,7 +6100,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6085,11 +6206,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6118,7 +6235,7 @@ msgid "Error Importing"
msgstr "लोड होने मे तà¥à¤°à¥à¤Ÿà¤¿:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6201,6 +6318,11 @@ msgid "Open..."
msgstr "खोलो इसे"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "निरà¥à¤­à¤°à¤¤à¤¾ संपादक"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6238,11 +6360,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6331,6 +6453,10 @@ msgstr ""
msgid "Search Results"
msgstr "खोज कर:"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6402,6 +6528,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6437,92 +6564,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "डà¥à¤ªà¥à¤²à¤¿à¤•à¥‡à¤Ÿ चयन"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6701,7 +6833,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6757,7 +6893,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6811,7 +6947,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6822,27 +6958,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6886,26 +7002,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6960,7 +7056,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7263,10 +7359,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7353,11 +7445,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7464,14 +7556,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7485,8 +7569,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7784,6 +7868,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7866,6 +7954,11 @@ msgid "Duplicate Nodes"
msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "को हटा दें"
@@ -7888,6 +7981,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "à¤à¤• नया बनाà¤à¤‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "à¤à¤• नया बनाà¤à¤‚"
@@ -7962,6 +8060,22 @@ msgid "Color uniform."
msgstr "à¤à¤¨à¥€à¤®à¥‡à¤¶à¤¨ परिवरà¥à¤¤à¤¨ परिणत"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7969,10 +8083,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8061,7 +8209,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8069,7 +8217,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8081,7 +8229,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8098,7 +8246,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8167,11 +8315,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8187,7 +8335,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8198,7 +8346,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8207,7 +8355,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8215,11 +8363,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8260,11 +8408,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8274,7 +8426,7 @@ msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8292,15 +8444,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8352,7 +8504,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8367,6 +8519,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8380,19 +8536,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8401,7 +8557,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8410,14 +8566,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8462,47 +8618,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8669,6 +8832,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8818,6 +8985,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8887,8 +9062,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8908,8 +9083,9 @@ msgid "Project Manager"
msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ मैनेजर"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8933,10 +9109,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9272,6 +9444,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9324,14 +9500,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9620,6 +9788,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9663,6 +9835,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "à¤à¤• नया बनाà¤à¤‚"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9736,19 +9913,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9842,6 +10019,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9871,7 +10052,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10032,6 +10213,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10445,10 +10630,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "à¤à¤• नया बनाà¤à¤‚"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "à¤à¤• नया बनाà¤à¤‚"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10633,10 +10837,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11373,22 +11573,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11403,6 +11587,11 @@ msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
msgid "Invalid source for shader."
msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11419,6 +11608,9 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Invalid font size."
+#~ msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
+
#, fuzzy
#~ msgid "Create C# solution"
#~ msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚"
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index 4f05208f9b..b9d3494ea2 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -58,7 +58,6 @@ msgid "On call to '%s':"
msgstr "Pri pozivu '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -127,6 +126,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -614,15 +633,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -847,8 +866,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -942,7 +960,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -978,7 +996,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1067,14 +1085,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1091,7 +1109,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1108,7 +1126,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1575,12 +1592,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1641,7 +1657,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1692,7 +1708,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1717,23 +1733,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1966,6 +1986,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2262,6 +2286,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2355,6 +2387,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2408,6 +2444,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2435,20 +2475,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2481,24 +2517,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2578,12 +2622,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2599,14 +2643,6 @@ 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 ""
@@ -2627,14 +2663,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2642,12 +2678,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2920,6 +2957,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3081,7 +3122,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3098,6 +3139,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3159,12 +3204,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3178,13 +3221,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3269,19 +3316,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3314,11 +3353,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3377,6 +3416,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3440,6 +3483,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Stvori"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3500,6 +3548,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3507,12 +3563,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3525,11 +3589,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3736,7 +3800,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4478,10 +4542,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4494,14 +4554,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4542,6 +4630,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4570,13 +4662,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4584,7 +4678,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4597,7 +4691,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4609,6 +4703,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4659,31 +4757,32 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Pomakni Bezier ToÄke"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4763,6 +4862,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4791,6 +4894,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4811,14 +4915,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4842,6 +4949,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4858,11 +4966,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4875,6 +4978,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5082,16 +5190,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5406,14 +5504,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5497,19 +5587,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5837,7 +5931,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5943,11 +6036,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5971,7 +6060,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6052,6 +6141,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6089,11 +6182,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6181,6 +6274,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6247,6 +6344,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6281,92 +6379,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6544,7 +6646,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6600,7 +6706,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6654,7 +6760,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6665,27 +6771,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6729,26 +6815,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6803,7 +6869,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7096,10 +7162,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7184,11 +7246,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7293,14 +7355,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7314,8 +7368,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7597,6 +7651,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7674,6 +7732,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7694,6 +7757,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7766,6 +7833,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7773,10 +7856,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7865,7 +7982,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7873,7 +7990,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7885,7 +8002,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7902,7 +8019,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7971,11 +8088,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7991,7 +8108,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8002,7 +8119,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8011,7 +8128,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8019,11 +8136,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8063,11 +8180,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8076,7 +8197,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8094,15 +8215,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8151,7 +8272,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8166,6 +8287,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8179,19 +8304,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8200,7 +8325,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8209,14 +8334,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8261,47 +8386,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8468,6 +8600,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8614,6 +8750,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8683,8 +8827,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8704,7 +8848,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8728,10 +8872,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9065,6 +9205,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9117,14 +9261,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9410,6 +9546,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9452,6 +9592,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9523,19 +9667,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9628,6 +9772,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9656,7 +9804,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9816,6 +9964,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10226,10 +10378,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10414,10 +10582,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11147,22 +11311,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11175,6 +11323,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index a7033084d3..4a2ef407d4 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -6,14 +6,15 @@
# Nagy Lajos <neutron9707@gmail.com>, 2017.
# Sandor Domokos <sandor.domokos@gmail.com>, 2017-2018.
# Varga Dániel <danikah.danikah@gmail.com>, 2016-2018.
-# Gabor Csordas <gaborcsordas@yahoo.com>, 2018.
+# Gabor Csordas <gaborcsordas@yahoo.com>, 2018, 2019.
# Tusa Gamer <tusagamer@mailinator.com>, 2018.
+# Máté Lugosi <mate.lugosi@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-12-29 12:09+0000\n"
-"Last-Translator: Tusa Gamer <tusagamer@mailinator.com>\n"
+"PO-Revision-Date: 2019-07-29 19:20+0000\n"
+"Last-Translator: Gabor Csordas <gaborcsordas@yahoo.com>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/hu/>\n"
"Language: hu\n"
@@ -21,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.4-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
@@ -45,15 +46,15 @@ msgstr "self nem használható, mert a példány null (nincs átadva)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr ""
+msgstr "Érvénytelen operandus a %s, %s és %s operátorokhoz."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr ""
+msgstr "Érvénytelen %s típusú index a %s alap típushoz."
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr ""
+msgstr "Érvénytelen nevezett index '%s' %s alaptípushoz"
#: core/math/expression.cpp
#, fuzzy
@@ -63,30 +64,27 @@ msgstr ""
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr ""
+msgstr "'%s' hívásánál:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Ingyenes"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Kiegyensúlyozott"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Mirror"
-msgstr "Hiba!"
+msgstr "Tükör"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
msgstr "Idő:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Value:"
-msgstr "Új név:"
+msgstr "Érték:"
#: editor/animation_bezier_editor.cpp
#, fuzzy
@@ -94,24 +92,20 @@ msgid "Insert Key Here"
msgstr "Kulcs Beszúrása"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Duplicate Selected Key(s)"
-msgstr "Kiválasztás megkettőzés"
+msgstr "Kiválasztott elem(ek) megkettőzése"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Delete Selected Key(s)"
-msgstr "Törli a kiválasztott fájlokat?"
+msgstr "Kiválasztott kulcsok törlése"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Add Bezier Point"
-msgstr "Pont hozzáadása"
+msgstr "Bezier pont hozzáadása"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Move Bezier Points"
-msgstr "Pont Mozgatása"
+msgstr "Bezier pont Mozgatása"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -119,7 +113,7 @@ msgstr "Animáció kulcsok megkettőzése"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr "Animáció kulcs törlés"
+msgstr "Animáció kulcs törlése"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Time"
@@ -143,17 +137,43 @@ msgstr "Animáció hívás változtatás"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animáció kulcsképkocka idő változtatás"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animáció átmenet változtatása"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animáció transzformáció változtatás"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animáció kulcsképkocka érték változtatás"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animáció hívás változtatás"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Animáció Nevének Megváltoztatása:"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Animációs ciklus változtatása"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Property Track"
-msgstr ""
+msgstr "Tulajdonság Követés"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -178,14 +198,12 @@ msgid "Animation Playback Track"
msgstr "Animáció lejátszásának leállítása. (S)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
-msgstr "Animáció hossza (másodpercben)."
+msgstr "Animáció hossza (képkockákban)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
-msgstr "Animáció hossza (másodpercben)."
+msgstr "Animáció hossza (másodpercben)"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -200,7 +218,7 @@ msgstr "Animáció nagyítás."
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Functions:"
-msgstr ""
+msgstr "Funkciók:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
@@ -225,9 +243,8 @@ msgid "Update Mode (How this property is set)"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Interpolation Mode"
-msgstr "Animáció Node"
+msgstr "Interpoláció mód"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
@@ -662,17 +679,18 @@ msgid "Line Number:"
msgstr "Sor Száma:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Lecserélve %d előfordulás."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Nincs Találat"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Lecserélve %d előfordulás."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Pontos Egyezés"
@@ -911,8 +929,7 @@ msgstr "Kedvencek:"
msgid "Recent:"
msgstr "Legutóbbi:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1015,7 +1032,7 @@ msgstr ""
"Az eltávolítandó fájlokat szükségelik más források a működésükhöz.\n"
"Eltávolítja őket ennek ellenére? (nem visszavonható)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nem eltávolítható:"
@@ -1053,7 +1070,7 @@ msgstr "Véglegesen törlöl %d elemet? (Nem visszavonható!)"
msgid "Show Dependencies"
msgstr "Függőségek"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Ãrva Forrás KezelÅ‘"
@@ -1142,14 +1159,16 @@ msgid "License"
msgstr "Licenc"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Harmadik Fél Engedély"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"A Godot Engine több harmadik fél ingyenes és nyílt forráskódú könyvtáraira "
@@ -1170,7 +1189,8 @@ msgid "Licenses"
msgstr "Licencek"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Hiba a csomagfájl megnyitása során, nem zip formátumú."
#: editor/editor_asset_installer.cpp
@@ -1188,7 +1208,6 @@ msgid "Success!"
msgstr "Siker!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Telepítés"
@@ -1680,12 +1699,11 @@ msgid "New"
msgstr "Új"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importálás"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportálás"
@@ -1756,7 +1774,7 @@ msgstr "Mutat Fájlkezelőben"
msgid "New Folder..."
msgstr "Új Mappa..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Frissítés"
@@ -1807,7 +1825,7 @@ msgstr "Ugrás Előre"
msgid "Go Up"
msgstr "Ugrás Fel"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Rejtett Fájlok Megjelenítése"
@@ -1833,27 +1851,32 @@ msgstr "Kedvenc Lefelé Mozgatása"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Előző Sík"
+msgid "Go to previous folder."
+msgstr "Ugrás a szülőmappába"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Mappa Létrehozása"
+msgid "Go to next folder."
+msgstr "Ugrás a szülőmappába"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Ugrás a szülőmappába"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Osztályok Keresése"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Nem sikerült létrehozni a mappát."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Rejtett Fájlok Megjelenítése"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2114,6 +2137,10 @@ msgstr "Töröl"
msgid "Clear Output"
msgstr "Kimenet Törlése"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Projekt export nem sikerült, hibakód %d."
@@ -2441,6 +2468,15 @@ msgid "Pick a Main Scene"
msgstr "Válasszon egy Fő Jelenetet"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Scene bezárás"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Scene bezárás"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Nem sikerült az addon plugin engedélyezése itt: '%s' a konfiguráció elemzése "
@@ -2563,6 +2599,11 @@ msgstr "Scene futtatás"
msgid "Close Tab"
msgstr "A Többi Lap Bezárása"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "A Többi Lap Bezárása"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "A Többi Lap Bezárása"
@@ -2617,6 +2658,11 @@ msgid "Go to previously opened scene."
msgstr "Ugrás az előzőleg megnyitott jelenetre."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Útvonal másolása"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Következő fül"
@@ -2644,6 +2690,10 @@ msgstr "Új örökölt Jelenet..."
msgid "Open Scene..."
msgstr "Jelenet megnyitása..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Legutóbbi Megnyitása"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Scene mentés"
@@ -2654,14 +2704,6 @@ msgid "Save All Scenes"
msgstr "Minden Scene mentés"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Scene bezárás"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Legutóbbi Megnyitása"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Ãtkonvertálás..."
@@ -2691,26 +2733,37 @@ msgstr "Scene visszaállítás"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Egyéb projekt- vagy Scene-szintű eszközök."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projekt Beállítások"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Eszközök"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportálás"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Megnyitja a Projektkezelőt?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Eszközök"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Ãrva Forrás KezelÅ‘"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2809,12 +2862,13 @@ msgstr ""
"Ha egy távoli eszközön használja, sokkal hatékonyabb a hálózati "
"fájlrendszerrel együtt."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Szerkesztő"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Szerkesztő Beállítások"
#: editor/editor_node.cpp
@@ -2832,15 +2886,6 @@ 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ő"
@@ -2865,14 +2910,15 @@ msgstr "Szerkesztő Beállítások"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Export Sablonok Kezelése"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Export Sablonok Kezelése"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Súgó"
@@ -2880,12 +2926,13 @@ msgstr "Súgó"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Keresés"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentáció"
@@ -3167,6 +3214,11 @@ msgstr "Idő"
msgid "Calls"
msgstr "Hívások"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Tagok"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3334,7 +3386,8 @@ msgid "Import From Node:"
msgstr "Importálás Node-ból:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Letöltés Megint"
#: editor/export_template_manager.cpp
@@ -3351,6 +3404,10 @@ msgid "Download"
msgstr "Letöltés"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Hiányzik)"
@@ -3415,12 +3472,10 @@ msgid "No response."
msgstr "Nincs válasz."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Kérés Sikertelen."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Ãtirányítási Hurok."
@@ -3434,13 +3489,19 @@ msgid "Download Complete."
msgstr "A Letöltés Befejeződött."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nem eltávolítható:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Hiba történt az url lekérdezésekor: "
#: editor/export_template_manager.cpp
@@ -3528,22 +3589,12 @@ msgstr "Sablonok Letöltése"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Válasszon tükröt a listából: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Nem lehet megnyitni a file_type_cache.cch fájlt írásra, a fájltípus "
-"gyorsítótár nem lesz mentve!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Kedvencek:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Nem lehet '%s'-t elérni, mivel nem létezik a fájlrendszerben!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Ãllapot: Fájl importálása sikertelen. Javítsa a fájlt majd importálja be "
@@ -3579,14 +3630,14 @@ msgid "Provided name contains invalid characters."
msgstr "A megadott név érvénytelen karaktereket tartalmaz"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "A név érvénytelen karaktereket tartalmaz."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Egy fájl vagy mappa már létezik a megadott névvel."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "A név érvénytelen karaktereket tartalmaz."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Fájl átnevezése:"
@@ -3646,6 +3697,11 @@ msgstr "Megkettőzés..."
msgid "Move To..."
msgstr "Ãthelyezés..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Új Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3720,6 +3776,11 @@ msgstr "Egy fájl vagy mappa már létezik a megadott névvel."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Scene mentés"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Szkript Létrehozása"
@@ -3789,6 +3850,14 @@ msgid "Search complete"
msgstr "Keresés a Szövegben"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Hozzáadás Csoporthoz"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Eltávolítás Csoportból"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "HIBA: Animáció név már létezik!"
@@ -3798,13 +3867,23 @@ msgstr "HIBA: Animáció név már létezik!"
msgid "Invalid group name."
msgstr "Érvénytelen név."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Csoportok"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Elrendezés Törlése"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Csoportok"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Hozzáadás Csoporthoz"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3818,12 +3897,13 @@ msgid "Nodes in Group"
msgstr "Hozzáadás Csoporthoz"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Hozzáadás Csoporthoz"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Eltávolítás Csoportból"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Szkript Szerkesztő Megnyitása"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4035,7 +4115,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Beállítás"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Válasszon ki egy Node-ot a Jelzések és Csoportok módosításához."
#: editor/plugin_config_dialog.cpp
@@ -4836,10 +4917,6 @@ msgid "View Files"
msgstr "Fájlok Megtekintése"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "A gazdagép neve nem oldható meg:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Kapcsolat hiba, kérjük próbálja meg újra."
@@ -4852,14 +4929,47 @@ msgid "No response from host:"
msgstr "Nincs válasz a kiszolgálótól:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "A gazdagép neve nem oldható meg:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Kérés sikertelen, visszatérési kód:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Kérés Sikertelen."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nem eltávolítható:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Kérés sikertelen, túl sok átirányítás"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Ãtirányítási Hurok."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Kérés sikertelen, visszatérési kód:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Idő"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
"Rossz letöltési hash, a program feltételezi, hogy a fájlt rosszindulatilag "
@@ -4904,6 +5014,11 @@ msgid "Idle"
msgstr "Tétlen"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Telepítés"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Újra"
@@ -4934,13 +5049,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Mind"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importálás"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Bővítmények"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4948,8 +5067,9 @@ msgid "Sort:"
msgstr "Rendezés:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Visszafele"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Lekérdezés..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4961,7 +5081,8 @@ msgid "Site:"
msgstr "Oldal:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Támogatás..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4973,6 +5094,11 @@ msgid "Testing"
msgstr "Tesztelés"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Betöltés"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Eszköz ZIP Fájl"
@@ -5032,31 +5158,38 @@ msgid "Rotation Step:"
msgstr "Forgatási Léptetés:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Függőleges vezetővonal mozgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Új függőleges vezetővonal létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Függőleges vezetővonal eltávolítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Vízszintes vezetővonal mozgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Új vízszintes vezetővonal létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Vízszintes vezetővonal eltávolítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Új vízszintes és függőleges vezetővonalak létrehozása"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5146,6 +5279,11 @@ msgstr "Póz Beillesztése"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Póz Törlése"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Kibocsátási Pontok Létrehozása A Mesh Alapján"
@@ -5176,6 +5314,7 @@ msgid "Zoom Reset"
msgstr "Kicsinyítés"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Kiválasztó Mód"
@@ -5198,14 +5337,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + Jobb Egérgomb: Mélységi lista választás"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Mozgás Mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Forgató mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Kiválasztó Mód"
@@ -5233,6 +5375,7 @@ msgid "Toggle snapping."
msgstr "Illesztés be- és kikapcsolása"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Illesztés Használata"
@@ -5251,11 +5394,6 @@ msgid "Use Rotation Snap"
msgstr "Forgatási Illesztés Használata"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Illesztés Beállítása..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Relatív Illesztés"
@@ -5269,6 +5407,11 @@ msgid "Smart Snapping"
msgstr "Intelligens illesztés"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Illesztés Beállítása..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Illesztés szülőhöz"
@@ -5491,16 +5634,6 @@ msgstr "Fogantyú Beállítása"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Hiba a kép betöltésekor:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Nem létezik egyetlen pixel sem >128-as átlátszósággal a képben..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Kibocsátási Maszk Betöltése"
@@ -5825,14 +5958,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Felületi forrás érvénytelen (nincsenek oldalak)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "A szülőnek nincsenek kitölthető szilárd oldalai."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "A területet nem lehetett leképezni."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Válasszon Ki Egy Forrás Mesh-t:"
@@ -5918,20 +6043,27 @@ msgid "Generation Time (sec):"
msgstr "Generálási Idő (mp):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Az oldalak nem tartalmaznak területet!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Nincsenek oldalak!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "A Node nem tartalmaz geometriát (oldalakat)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "A Node nem tartalmaz geometriát."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "A Node nem tartalmaz geometriát (oldalakat)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "A Node nem tartalmaz geometriát."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6273,7 +6405,6 @@ msgid "Grid Settings"
msgstr "Szerkesztő Beállítások"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Illesztés"
@@ -6388,12 +6519,7 @@ msgstr "Hiba TileSet mentésekor!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Nem sikerült létrehozni a mappát."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Nem sikerült létrehozni a mappát."
#: editor/plugins/script_editor_plugin.cpp
@@ -6423,7 +6549,7 @@ msgstr "Hiba importáláskor"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Új Mappa..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6510,6 +6636,11 @@ msgid "Open..."
msgstr "Megnyit"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Szkript Futtatása"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Összes Mentése"
@@ -6549,13 +6680,13 @@ msgid "Save Theme"
msgstr "Téma Mentése"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Dokumentációs Lapok Bezárása"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Mind Bezárása"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Dokumentációs Lapok Bezárása"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Futtatás"
@@ -6646,6 +6777,11 @@ msgstr "Hibakereső"
msgid "Search Results"
msgstr "Keresés Súgóban"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Legutóbbi Jelenetek Törlése"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6719,6 +6855,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6754,26 +6891,6 @@ msgid "Toggle Comment"
msgstr "Ãtváltás Megjegyzésre"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Töréspont Elhelyezése"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Ugrás Következő Töréspontra"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Ugrás Előző Töréspontra"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Összes Töréspont Eltávolítása"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Sor Összezárása / Kibontása"
@@ -6794,6 +6911,11 @@ msgid "Complete Symbol"
msgstr "Szimbólum Befejezése"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Kiválasztás átméretezés"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Sorvégi Szóközök Lenyírása"
@@ -6812,32 +6934,37 @@ msgid "Auto Indent"
msgstr "Automatikus Behúzás"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Töréspont Elhelyezése"
+msgid "Find Previous"
+msgstr "Előző Keresése"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Összes Töréspont Eltávolítása"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Fájlok Szűrése..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "Kontextusérzékeny Súgó"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Ugrás Következő Töréspontra"
+msgid "Toggle Bookmark"
+msgstr "Töréspont Elhelyezése"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Ugrás Előző Töréspontra"
+msgid "Go to Next Bookmark"
+msgstr "Ugrás Következő Töréspontra"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Előző Keresése"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Ugrás Előző Töréspontra"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Fájlok Szűrése..."
+msgid "Remove All Bookmarks"
+msgstr "Összes Töréspont Eltávolítása"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6850,8 +6977,23 @@ msgid "Go to Line..."
msgstr "Ugrás Sorra..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Kontextusérzékeny Súgó"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Töréspont Elhelyezése"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Összes Töréspont Eltávolítása"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Ugrás Következő Töréspontra"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Ugrás Előző Töréspontra"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -7036,7 +7178,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7092,8 +7238,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Doppler engedélyezése"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Animáció hossz változtatás"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7148,7 +7295,7 @@ msgid "Snap Nodes To Floor"
msgstr "Rácshoz illesztés"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7159,27 +7306,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7223,26 +7350,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7298,8 +7405,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Szerkesztő Beállítások"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7610,10 +7718,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7703,12 +7807,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "%d elem"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "%d elem"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7818,14 +7922,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7840,8 +7936,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8159,6 +8255,10 @@ msgid "TileSet"
msgstr "TileSet-re..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Bemenet Hozzáadása"
@@ -8250,6 +8350,11 @@ msgid "Duplicate Nodes"
msgstr "Animáció kulcsok megkettőzése"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Node létrehozás"
@@ -8272,6 +8377,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Node létrehozás"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Node létrehozás"
@@ -8350,6 +8460,22 @@ msgid "Color uniform."
msgstr "Animáció transzformáció változtatás"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8357,10 +8483,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "Vec állandó változtatás"
@@ -8453,7 +8613,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8461,7 +8621,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8473,7 +8633,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8490,7 +8650,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8559,11 +8719,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8579,7 +8739,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8590,7 +8750,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8599,7 +8759,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8607,11 +8767,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8653,11 +8813,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8667,7 +8831,7 @@ msgstr "Sokszög Létrehozása"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8685,15 +8849,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8746,7 +8910,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8761,6 +8925,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8774,19 +8942,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8795,7 +8963,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8804,14 +8972,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8858,47 +9026,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9074,6 +9249,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Export Sablonok Kezelése"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9221,6 +9400,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Meglévő Projekt Importálása"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "'%s' nem nyitható meg."
@@ -9294,8 +9482,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9315,8 +9503,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9340,10 +9529,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9682,6 +9867,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Bővítmények"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9734,14 +9923,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10044,6 +10225,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10090,6 +10275,11 @@ msgstr "Szkript Futtatása"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Új %s Létrehozása"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Scene mentés"
@@ -10166,19 +10356,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10276,6 +10466,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10308,7 +10502,7 @@ msgid "Script is valid."
msgstr "Az animációs fa érvényes."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10473,6 +10667,10 @@ msgid "Change Shortcut"
msgstr "Horgonyok Módosítása"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Szerkesztő Beállítások"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10896,10 +11094,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Érvénytelen név. Nem ütközhet egy már meglévő beépített típusnévvel."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Új %s Létrehozása"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Új %s Létrehozása"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Új sokszög létrehozása a semmiből."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11087,10 +11305,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Tagok"
@@ -11839,22 +12053,6 @@ msgstr ""
"gyermekévé, hogy így kapjon méretet. Ellenkező esetben tegye RenderTarget-"
"té, és állítsa hozzá a belső textúráját valamilyen node-hoz kirajzolásra."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "FreeType inicializálási hiba."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Ismeretlen betűtípus formátum."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Hiba a betűtípus betöltésekor."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Érvénytelen betűtípus méret."
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11870,6 +12068,11 @@ msgstr "Érvénytelen betűtípus méret."
msgid "Invalid source for shader."
msgstr "Érvénytelen betűtípus méret."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Érvénytelen betűtípus méret."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11886,6 +12089,67 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Nem lehet megnyitni a file_type_cache.cch fájlt írásra, a fájltípus "
+#~ "gyorsítótár nem lesz mentve!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Nem lehet '%s'-t elérni, mivel nem létezik a fájlrendszerben!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Hiba a kép betöltésekor:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Nem létezik egyetlen pixel sem >128-as átlátszósággal a képben..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "A szülőnek nincsenek kitölthető szilárd oldalai."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "A területet nem lehetett leképezni."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Az oldalak nem tartalmaznak területet!"
+
+#~ msgid "No faces!"
+#~ msgstr "Nincsenek oldalak!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Nem sikerült létrehozni a mappát."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Doppler engedélyezése"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "FreeType inicializálási hiba."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Ismeretlen betűtípus formátum."
+
+#~ msgid "Error loading font."
+#~ msgstr "Hiba a betűtípus betöltésekor."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Érvénytelen betűtípus méret."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Előző Sík"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Mappa Létrehozása"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Következő Szerkesztő Megnyitása"
+
+#~ msgid "Reverse"
+#~ msgstr "Visszafele"
+
#, fuzzy
#~ msgid "View log"
#~ msgstr "Fájlok Megtekintése"
diff --git a/editor/translations/id.po b/editor/translations/id.po
index f88fff02e5..580631d6bc 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -20,12 +20,13 @@
# Alphin Albukhari <alphinalbukhari5@gmail.com>, 2019.
# I Dewa Agung Adhinata <agungnata2003@gmail.com>, 2019.
# herri siagian <herry.it.2007@gmail.com>, 2019.
+# MonsterGila <fikrirazor@outlook.co.id>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:47+0000\n"
-"Last-Translator: herri siagian <herry.it.2007@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: Sofyan Sugianto <sofyanartem@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -33,7 +34,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -77,7 +78,6 @@ msgid "On call to '%s':"
msgstr "Pada pemanggilan '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Bebaskan"
@@ -146,6 +146,26 @@ msgid "Anim Change Call"
msgstr "Ubah Panggilan Anim"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Ubah Beberapa Waktu Keyframe Animasi"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Ubah Beberapa Transisi Animasi"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Ubah Beberapa Transformasi Animasi"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Ubah Beberapa Nilai Keyframe Animasi"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Ubah Beberapa Panggilan Animasi"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Ubah Panjang Animasi"
@@ -468,9 +488,8 @@ msgid "Select All"
msgstr "Pilih Semua"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Metode Publik:"
+msgstr "Pilih Tidak Ada"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -647,16 +666,18 @@ msgid "Line Number:"
msgstr "Nomor Baris:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "kejadian %d diganti."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Tidak ada yang cocok"
+#, fuzzy
+msgid "%d match."
+msgstr "Ditemukan %d kecocokan."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "kejadian %d diganti."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Ditemukan %d kecocokan."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -805,9 +826,8 @@ msgid "Connect"
msgstr "Menghubungkan"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Sinyal-sinyal:"
+msgstr "Sinyal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -883,8 +903,7 @@ msgstr "Favorit:"
msgid "Recent:"
msgstr "Saat ini:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -972,10 +991,8 @@ msgid "Owners Of:"
msgstr "Pemilik Dari:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr ""
-"Hapus file-file yang dipilih dari proyek? (tidak bisa dibatalkan / undo)"
+msgstr "Hapus berkas yang dipilih dari proyek? (tidak bisa dibatalkan)"
#: editor/dependency_editor.cpp
msgid ""
@@ -987,7 +1004,7 @@ msgstr ""
"bekerja.\n"
"Hapus saja? (tidak bisa dibatalkan/undo)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Tidak bisa menghapus:"
@@ -1023,7 +1040,7 @@ msgstr "Hapus secara permanen %d item? (Tidak dapat dikembalikan!)"
msgid "Show Dependencies"
msgstr "Tampilkan Ketergantungan"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Penjelajah Resource Orphan"
@@ -1112,14 +1129,16 @@ msgid "License"
msgstr "Lisensi"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Lisensi Pihak Ketiga"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine mengandalkan sejumlah perpustakaan bebas dan sumber terbuka "
@@ -1140,7 +1159,8 @@ msgid "Licenses"
msgstr "Lisensi"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Gagal saat membuka paket, tidak dalam bentuk zip."
#: editor/editor_asset_installer.cpp
@@ -1157,7 +1177,6 @@ msgid "Success!"
msgstr "Sukses!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Pasang"
@@ -1345,7 +1364,6 @@ msgid "Must not collide with an existing engine class name."
msgstr "Tidak boleh sama dengan nama kelas engine yang sudah ada."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
msgstr "Tidak boleh sama dengan nama tipe bawaan yang ada."
@@ -1498,7 +1516,6 @@ msgstr ""
"'Impor Lainnya 2' di Pengaturan Proyek."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC' texture compression for the driver fallback "
"to GLES2.\n"
@@ -1506,8 +1523,9 @@ msgid ""
"Enabled'."
msgstr ""
"Platform target membutuhkan kompressi tekstur 'ETC' untuk mengembalikan "
-"driver ke GLES2. Aktifkan 'Impor Lainnya' di Pengaturan Proyek, atau matikan "
-"'Driver Fallback Enabled'."
+"driver ke GLES2. \n"
+"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
@@ -1527,7 +1545,7 @@ msgstr "Templat berkas tidak ditemukan:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "Pada ekspor 32-bit PCK yang ditanamkan tidak boleh lebih dari 4GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1554,9 +1572,8 @@ msgid "Node Dock"
msgstr "Dok Node"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "Dok Berkas Sistem"
+msgstr "Dok Impor dan Berkas Sistem"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1623,9 +1640,8 @@ msgid "Unset"
msgstr "Tidak diatur"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Profil Sekarang"
+msgstr "Profil Sekarang:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1637,19 +1653,17 @@ msgid "New"
msgstr "Baru"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Impor"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Ekspor"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Profil yang Tersedia"
+msgstr "Profil yang Tersedia:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1704,7 +1718,7 @@ msgstr "Tampilkan di Manajer Berkas"
msgid "New Folder..."
msgstr "Buat Direktori..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Segarkan"
@@ -1755,7 +1769,7 @@ msgstr "Maju"
msgid "Go Up"
msgstr "Naik"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Beralih File Tersembunyi"
@@ -1780,23 +1794,27 @@ msgid "Move Favorite Down"
msgstr "Pindahkan Favorit Kebawah"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Direktori Sebelumnya"
+msgid "Go to previous folder."
+msgstr "Pergi ke direktori sebelumnya."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Folder Berikutnya"
+msgid "Go to next folder."
+msgstr "Pergi ke direktori selanjutnya."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Pergi ke direktori atasnya."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Segarkan berkas."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Hapus favorit direktori saat ini."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Beralih visibilitas berkas yang tersembunyi."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2038,6 +2056,10 @@ msgstr "Bersihkan"
msgid "Clear Output"
msgstr "Bersihkan Luaran"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Ekspor proyek gagal dengan kode kesalahan %d."
@@ -2360,6 +2382,15 @@ msgid "Pick a Main Scene"
msgstr "Pilih Skena Utama"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Tutup Skena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Tutup Skena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Tidak dapat mengaktifkan addon plugin pada : '%s' parsing dari pengaturan "
@@ -2474,6 +2505,11 @@ msgstr "Mainkan Skena Ini"
msgid "Close Tab"
msgstr "Tutup Tab"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Tutup Tab"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Tutup Tab Lainnya"
@@ -2527,6 +2563,10 @@ msgid "Go to previously opened scene."
msgstr "Pergi ke skena yang sebelumnya dibuka."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Salin Teks"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Tab selanjutnya"
@@ -2554,6 +2594,10 @@ msgstr "Skena Warisan Baru..."
msgid "Open Scene..."
msgstr "Buka Skena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Buka baru-baru ini"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Simpan Skena"
@@ -2563,14 +2607,6 @@ msgid "Save All Scenes"
msgstr "Simpan Semua Skena"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Tutup Skena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Buka baru-baru ini"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Ubah ke..."
@@ -2600,25 +2636,37 @@ msgstr "Kembalikan Skena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Perkakas macam-macam proyek atau lingkup skena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Proyek"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Pengaturan Proyek"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Alat-alat"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Ekspor"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Pasang Templat Build Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Buka Project Data Manager"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Alat-alat"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Pasang Templat Build Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Penjelajah Resource Orphan"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2716,12 +2764,13 @@ msgstr ""
"Ketika penggunaan remote pada sebuah perngakat, akan lebih efisien jika "
"jaringan filesystem."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Pengaturan Editor"
#: editor/editor_node.cpp
@@ -2729,30 +2778,20 @@ msgid "Editor Layout"
msgstr "Tata Letak Editor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Jadikan Skena Dasar"
+msgstr "Ambil Tangkapan Layar"
#: 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"
+msgstr "Jungkitkan Konsol Sistem"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2767,14 +2806,16 @@ msgid "Open Editor Settings Folder"
msgstr "Buka Penyunting Direktori Pengaturan"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Kelola Penyunting Fitur"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Mengatur Templat Ekspor"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Bantuan"
@@ -2782,12 +2823,13 @@ msgstr "Bantuan"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Cari"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentasi"
@@ -2861,19 +2903,16 @@ msgid "Spins when the editor window redraws."
msgstr "Putar ketika jendela penyunting digambar ulang."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Lanjut"
+msgstr "Perbarui Terus-menerus"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Perbarui Perubahan"
+msgstr "Perbarui Saat Berubah"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Nonaktifkan Perbaruan Spinner"
+msgstr "Sembunyikan Spinner Pembaruan"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -3067,6 +3106,10 @@ msgstr "Waktu"
msgid "Calls"
msgstr "Panggil"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Sunting Teks:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Nyala"
@@ -3239,7 +3282,8 @@ msgid "Import From Node:"
msgstr "Impor dari Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Unduh Ulang"
#: editor/export_template_manager.cpp
@@ -3256,6 +3300,10 @@ msgid "Download"
msgstr "Unduh"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(hilang)"
@@ -3319,12 +3367,10 @@ msgid "No response."
msgstr "Tidak ada respon."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Permintaan Gagal."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Mengalihkan Loop."
@@ -3338,15 +3384,22 @@ msgid "Download Complete."
msgstr "Unduhan Selesai."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Tidak dapat menyimpan tema ke dalam berkas:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Instalasi templat gagal. Arsip templat yang bermasalah dapat ditemukan di "
"'%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Kesalahan saat meminta url: "
#: editor/export_template_manager.cpp
@@ -3432,22 +3485,11 @@ msgstr "Unduh Templat"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
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!"
-msgstr ""
-"Tidak dapat membuka file_type_cache.cch untuk menulis, berkas cache tidak "
-"disimpan!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favorit"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"'%s' tidak bisa ditelusuri karena tidak bisa ditemukan dalam berkas sistem!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Status: Gagal mengimpor berkas. Mohon perbaiki berkas dan impor ulang secara "
@@ -3482,14 +3524,14 @@ msgid "Provided name contains invalid characters."
msgstr "Nama yang dimasukkan mengandung karakter tidak valid."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Nama mengandung karakter tidak valid."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Sudah ada nama berkas atau folder seperti itu."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Nama mengandung karakter tidak valid."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Mengubah nama berkas dengan:"
@@ -3545,6 +3587,11 @@ msgstr "Gandakan..."
msgid "Move To..."
msgstr "Pindahkan ke..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Skena Baru"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Skrip Baru..."
@@ -3584,9 +3631,8 @@ msgid "Re-Scan Filesystem"
msgstr "Pindai Ulang Berkas Sistem"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Toggle Split Mode"
-msgstr "Beralih Mode Split"
+msgstr "Jungkitkan Mode Split"
#: editor/filesystem_dock.cpp
msgid "Search files"
@@ -3612,6 +3658,11 @@ msgstr "Sudah ada nama berkas atau folder seperti itu di lokasi ini."
msgid "Overwrite"
msgstr "Timpa"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Buat dari Skena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Buat Script"
@@ -3633,7 +3684,6 @@ msgid "Filters:"
msgstr "Filter:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
@@ -3655,39 +3705,50 @@ msgid "Cancel"
msgstr "Batal"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find: "
-msgstr "Cari"
+msgstr "Cari: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace: "
-msgstr "Ganti"
+msgstr "Ganti: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace all (no undo)"
-msgstr "Ganti Semua"
+msgstr "Ganti Semua (tidak bisa dikembalikan)"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Searching..."
-msgstr "Menyimpan..."
+msgstr "Mencari..."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Search complete"
-msgstr "Mencari Teks"
+msgstr "Pencarian selesai"
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Tambahkan ke Grup"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Hapus dari Grup"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group name already exists."
-msgstr "KESALAHAN: Nama animasi sudah ada!"
+msgstr "Nama grup sudah ada."
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Invalid group name."
-msgstr "Nama tidak sah."
+msgstr "Nama grup tidak valid."
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Kelola Grup"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Hapus Penampilan"
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
@@ -3695,32 +3756,30 @@ msgstr "Kelompok"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
-msgstr "Tambahkan ke Grup"
+msgid "Nodes Not in Group"
+msgstr "Node tidak dalam Grup"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Filter nodes"
-msgstr "Filter:"
+msgstr "Saring node"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Nodes in Group"
-msgstr "Tambahkan ke Grup"
+msgstr "Node dalam Grup"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Tambahkan ke Grup"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Hapus dari Grup"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Penyunting Skrip"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Manage Groups"
-msgstr "Grup"
+msgstr "Kelola Grup"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -3828,9 +3887,8 @@ msgid "Save scenes, re-import and restart"
msgstr "Simpan skena, impor ulang, dan mulai ulang"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Changing the type of an imported file requires editor restart."
-msgstr "Mengubah driver video harus memulai ulang editor."
+msgstr "Mengubah jenis berkas yang diimpor butuh menyalakan ulang penyunting."
#: editor/import_dock.cpp
msgid ""
@@ -3844,9 +3902,8 @@ msgid "Failed to load resource."
msgstr "Gagal memuat resource."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Expand All Properties"
-msgstr "Perluas semua properti"
+msgstr "Perluas Semua Properti"
#: editor/inspector_dock.cpp
#, fuzzy
@@ -3867,9 +3924,8 @@ msgid "Paste Params"
msgstr "Tempel Parameter"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource Clipboard"
-msgstr "KESALAHAN: Tidak ada aset animasi di clipboard!"
+msgstr "Sunting PapanKlip SumberDaya"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
@@ -3916,9 +3972,8 @@ msgid "Object properties."
msgstr "Properti Objek."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Filter properties"
-msgstr "Filter:"
+msgstr "Saring properti"
#: editor/inspector_dock.cpp
msgid "Changes may be lost!"
@@ -3929,23 +3984,21 @@ msgid "MultiNode Set"
msgstr "Set MultiNode"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Pilih sebuah node untuk menyunting Sinyal dan Grup."
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Edit a Plugin"
-msgstr "Sunting Bidang"
+msgstr "Sunting Plugin"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Create a Plugin"
-msgstr "Buat Subskribsi"
+msgstr "Buat Plugin"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Plugin Name:"
-msgstr "Pengaya"
+msgstr "Nama Plugin:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
@@ -3956,9 +4009,8 @@ msgid "Language:"
msgstr "Bahasa:"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Script Name:"
-msgstr "Nama Projek:"
+msgstr "Nama Skrip:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
@@ -3966,53 +4018,45 @@ msgstr "Aktifkan sekarang?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon"
-msgstr "Buat Bidang"
+msgstr "Buat Poligon"
#: 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 "Hapus Titik"
+msgstr "Buat titik."
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid ""
"Edit points.\n"
"LMB: Move Point\n"
"RMB: Erase Point"
msgstr ""
-"Sunting bidang yang ada:\n"
-"LMB: Pindahkan Titik.\n"
-"Ctrl+LMB: Pecah Segmen.\n"
-"RMB: Hapus Titik."
+"Sunting titik.\n"
+"LMB: Pindahkan Titik\n"
+"RMB: Hapus Titik"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Erase points."
-msgstr "Beri Skala Seleksi"
+msgstr "Hapus titik."
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon"
-msgstr "Sunting Bidang"
+msgstr "Sunting Poligon"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Insert Point"
msgstr "Tambah Titik"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Edit Polygon (Remove Point)"
-msgstr "Sunting Bidang (Hapus Titik)"
+msgstr "Sunting Poligon (Hapus Titik)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid "Remove Polygon And Point"
-msgstr "Hapus Bidang dan Titik"
+msgstr "Hapus Poligon dan Titik"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4026,25 +4070,21 @@ msgstr "Tambah Animasi"
#: 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 "Load..."
-msgstr "Muat"
+msgstr "Muat..."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Move Node Point"
-msgstr "Hapus Sinyal"
+msgstr "Pindahkan Titik Node"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Limits"
-msgstr "Ubah Waktu Blend"
+msgstr "Ubah Batas BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Labels"
-msgstr "Ubah Waktu Blend"
+msgstr "Ubah Label BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4054,20 +4094,17 @@ msgstr "Node tipe ini tidak dapat digunakan. Hanya node utama yang diijinkan."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Node Point"
-msgstr "Tambahkan Node"
+msgstr "Tambah Titik Node"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Animation Point"
-msgstr "Tambah Animasi"
+msgstr "Tambah Titik Animasi"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace1D Point"
-msgstr "Hapus Bidang dan Titik"
+msgstr "Hapus Titik BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
@@ -4109,39 +4146,32 @@ msgstr "Titik"
#: 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 "Nama Animasi Baru:"
+msgstr "Buka Node Animasi"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "KESALAHAN: Nama animasi sudah ada!"
+msgstr "Segitiga sudah ada."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Triangle"
-msgstr "Tambahkan Variabel"
+msgstr "Tambah Segitiga"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Limits"
-msgstr "Ubah Waktu Blend"
+msgstr "Ubah Batas BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Labels"
-msgstr "Ubah Waktu Blend"
+msgstr "Ubah Label BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Point"
-msgstr "Hapus Bidang dan Titik"
+msgstr "Hapus Titik BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Triangle"
-msgstr "Hapus Variabel"
+msgstr "Hapus Segitiga BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "BlendSpace2D does not belong to an AnimationTree node."
@@ -4152,9 +4182,8 @@ msgid "No triangles exist, so no blending can take place."
msgstr "Tidak ada segi tiga, pembauran tidak di terapkan."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Toggle Auto Triangles"
-msgstr "Beralih AutoLoad Globals"
+msgstr "Jungkitkan Segitiga Otomatis"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
@@ -4174,30 +4203,26 @@ msgid "Blend:"
msgstr "Campur:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Parameter Changed"
-msgstr "Menyimpan perubahan-perubahan lokal..."
+msgstr "Parameter Berubah"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filters"
-msgstr "Sunting Filter"
+msgstr "Sunting Penyaring"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
msgstr "Node keluaran tidak bisa ditambahkan ke pohon campur."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Add Node to BlendTree"
-msgstr "Tambahkan Node (Node-node) dari Tree"
+msgstr "Tambah Node ke BlendTree"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node Moved"
-msgstr "Nama Node:"
+msgstr "Node Dipindahkan"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
@@ -4206,26 +4231,22 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Connected"
-msgstr "Terhubung"
+msgstr "Node Terhubung"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Disconnected"
-msgstr "Terputus"
+msgstr "Node Terputus"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "Animasi"
+msgstr "Atur Animasi"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
-msgstr "Metode Publik:"
+msgstr "Hapus Node"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
@@ -4233,14 +4254,12 @@ msgid "Delete Node(s)"
msgstr "Hapus Node"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Filter On/Off"
-msgstr "Alihkan track ini ke nyala/mati."
+msgstr "Jungkitkan Penyaring Nyala/Mati"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Change Filter"
-msgstr "Ganti Ukuran Kamera"
+msgstr "Ganti Penyaring"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4263,31 +4282,26 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "Nama Node:"
+msgstr "Node Telah Diubah Namanya"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Node..."
-msgstr "Tambahkan Node"
+msgstr "Tambah Node..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filtered Tracks:"
-msgstr "Sunting Filter"
+msgstr "Sunting Trek yang Disaring:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
msgstr "Aktifkan penyaringan"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Autoplay"
-msgstr "Kondisikan Putar Otomatis"
+msgstr "Jungkitkan Putar Otomatis"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
@@ -4311,14 +4325,12 @@ msgid "Remove Animation"
msgstr "Hapus Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Invalid animation name!"
-msgstr "KESALAHAN: Nama animasi tidak valid!"
+msgstr "Nama animasi tidak valid!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Animation name already exists!"
-msgstr "KESALAHAN: Nama animasi sudah ada!"
+msgstr "Nama animasi sudah ada!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -4342,37 +4354,30 @@ msgid "Duplicate Animation"
msgstr "Gandakan Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "KESALAHAN: Tidak ada animasi untuk disalin!"
+msgstr "Tidak ada animasi untuk disalin!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "KESALAHAN: Tidak ada aset animasi di clipboard!"
+msgstr "Tidak ada aset animasi di papan klip!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Pasted Animation"
-msgstr "Animasi Ditempel"
+msgstr "Animasi yang Direkatkan"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Paste Animation"
-msgstr "Tempelkan Animasi"
+msgstr "Rekatkan Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "KESALAHAN: Tidak ada animasi untuk disunting!"
+msgstr "Tidak ada animasi untuk disunting!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Play selected animation backwards from current pos. (A)"
msgstr "Mainkan mundur animasi terpilih dari lokasi sekarang. (A)"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Play selected animation backwards from end. (Shift+A)"
msgstr "Mainkan mundur animasi terpilih dari akhir. (Shift+A)"
@@ -4393,9 +4398,8 @@ msgid "Animation position (in seconds)."
msgstr "Posisi Animasi (dalam detik)."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Scale animation playback globally for the node."
-msgstr "Skalakan playback animasi secara global untuk node ini."
+msgstr "Skalakan pemutaran animasi secara global untuk node ini."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
@@ -4407,21 +4411,18 @@ msgid "Animation"
msgstr "Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "Transisi"
+msgstr "Sunting Transisi..."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Open in Inspector"
-msgstr "Buka dalam Penyunting"
+msgstr "Buka dalam Inspektur"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
msgstr "Tampilkan daftar animasi dalam pemutar animasi."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Autoplay on Load"
msgstr "Putar Otomatis saat Dimuat"
@@ -4430,19 +4431,16 @@ msgid "Enable Onion Skinning"
msgstr "Aktifkan Bayang-bayang"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Onion Skinning Options"
-msgstr "Onion Skinning"
+msgstr "Opsi Onion Skinning"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Directions"
-msgstr "Deskripsi:"
+msgstr "Arah"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Past"
-msgstr "Tempel"
+msgstr "Sebelum"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
@@ -4509,14 +4507,12 @@ msgid "Cross-Animation Blend Times"
msgstr "Waktu Berbaur Animasi-silang"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "Salin Resource"
+msgstr "Pindahkan Node"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "Transisi"
+msgstr "Tambah Transisi"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -4548,19 +4544,16 @@ msgid "Start and end nodes are needed for a sub-transition."
msgstr "Node awal dan akhir dibutuhkan untuk sub-transisi."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "No playback resource set at path: %s."
-msgstr "Tidak didalam path resource."
+msgstr "Tidak ada aset playback yang diatur di lokasi: %s."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Removed"
-msgstr "Dihapus:"
+msgstr "Node Dihapus"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "Node Transisi"
+msgstr "Transisi Dihapus"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
@@ -4577,19 +4570,16 @@ msgstr ""
"Shift+LMB untuk membuat sambungan."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Create new nodes."
-msgstr "Buat Baru %s"
+msgstr "Buat node baru."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Connect nodes."
-msgstr "Sambungkan Ke Node:"
+msgstr "Hubungkan node."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Remove selected node or transition."
-msgstr "Hapus track yang dipilih."
+msgstr "Hapus node atau transisi terpilih."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
@@ -4600,9 +4590,8 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr "Terapkan akhir pada animasi. Berguna untuk sub-transisi."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition: "
-msgstr "Transisi"
+msgstr "Transisi: "
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4736,51 +4725,75 @@ msgid "Import Animations..."
msgstr "Impor Animasi..."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Node Filters"
-msgstr "Sunting Filter Node"
+msgstr "Sunting Penyaring Node"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Filters..."
msgstr "Penyaring..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Contents:"
-msgstr "Konstanta:"
+msgstr "Konten:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "View Files"
-msgstr "File:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Tidak dapat menjelaskan hostname:"
+msgstr "Tampilkan Berkas"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Gangguan koneksi, silakan coba lagi."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Can't connect to host:"
-msgstr "Tidak bisa terhubung ke host:"
+msgstr "Tidak dapat terhubung ke host:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "No response from host:"
msgstr "Tidak ada respon dari host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Tidak dapat menjelaskan hostname:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Permintaan gagal, return code:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Permintaan Gagal."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Tidak dapat menyimpan tema ke dalam berkas:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Permintaan gagal, terlalu banyak pengalihan"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Mengalihkan Loop."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Permintaan gagal, return code:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Waktu"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Hash unduhan buruk, berkas mungkin telah diubah."
@@ -4821,6 +4834,10 @@ msgid "Idle"
msgstr "Menganggur"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Pasang..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Coba Lagi"
@@ -4833,14 +4850,12 @@ msgid "Download for this asset is already in progress!"
msgstr "Unduhan untuk aset ini sedang diproses!"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "First"
-msgstr "pertama"
+msgstr "Pertama"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Previous"
-msgstr "Tab sebelumnya"
+msgstr "Sebelum"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Next"
@@ -4851,13 +4866,17 @@ msgid "Last"
msgstr "Terakhir"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Semua"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Impor Ulang..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Pengaya"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4865,8 +4884,8 @@ msgid "Sort:"
msgstr "Sortir:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Terbalik"
+msgid "Reverse sorting."
+msgstr "Penyortiran terbalik."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4878,7 +4897,8 @@ msgid "Site:"
msgstr "Situs:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Dukungan..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4890,6 +4910,11 @@ msgid "Testing"
msgstr "Menguji"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Muat..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Berkas Aset ZIP"
@@ -4946,65 +4971,56 @@ msgid "Rotation Step:"
msgstr "Jangkah Perputaran:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Pindahkan garis-bantu vertikal"
+msgid "Move Vertical Guide"
+msgstr "Pindahkan Panduan Vertikal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
-msgid "Create new vertical guide"
-msgstr "Buat Subskribsi"
+msgid "Create Vertical Guide"
+msgstr "Buat Panduan Vertikal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
-msgid "Remove vertical guide"
-msgstr "Hapus Variabel"
+msgid "Remove Vertical Guide"
+msgstr "Hapus Panduan Vertikal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Pindahkan garis-bantu horisontal"
+msgid "Move Horizontal Guide"
+msgstr "Pindahkan Panduan Horisontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
-msgid "Create new horizontal guide"
-msgstr "Buat Subskribsi"
+msgid "Create Horizontal Guide"
+msgstr "Buat Panduan Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
-msgid "Remove horizontal guide"
-msgstr "Hapus Tombol-tombol yang tidak sah"
+msgid "Remove Horizontal Guide"
+msgstr "Hapus Panduan Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Buat garis-bantu vertikal dan horisontal baru"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Buat Panduan Horisontal dan Vertikal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move pivot"
-msgstr "Hapus Sinyal"
+msgstr "Pindahkan poros"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem"
-msgstr "Sunting CanvasItem"
+msgstr "Putar CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move anchor"
msgstr "Pindahkan jangkar"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Resize CanvasItem"
-msgstr "Sunting CanvasItem"
+msgstr "Ubah Ukuran CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem"
-msgstr "Sunting CanvasItem"
+msgstr "Skalakan CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem"
-msgstr "Sunting CanvasItem"
+msgstr "Pindahkan CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5040,27 +5056,23 @@ msgstr "Ubah Jangkar-jangkar"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "Semua pilihan"
+msgstr "Kunci yang Dipilih"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected"
-msgstr "Hapus yang Dipilih"
+msgstr "Lepas Kunci yang Dipilih"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected"
-msgstr "Hapus Pilihan"
+msgstr "Kelompokkan yang Dipilih"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Hapus Pilihan"
+msgstr "Keluarkan yang dipilih dari Grup"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
@@ -5068,8 +5080,12 @@ msgstr "Tempel Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Bersihkan Pertulangan"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
-msgstr "Buat Tulang Kustom(satu/lebih) dari Node(satu/lebih)"
+msgstr "Buat Tulang Kustom dari Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Bones"
@@ -5094,11 +5110,11 @@ 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 "Perkecil Pandangan"
+msgstr "Reset Perbesaran"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Mode Seleksi"
@@ -5120,17 +5136,19 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Klik kanan: Daftar seleksi kedalaman"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Mode Pindah"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Mode Putar"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr "Beralih Mode"
+msgstr "Mode Skala"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5150,11 +5168,11 @@ msgid "Pan Mode"
msgstr "Mode Geser Pandangan"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle snapping."
-msgstr "Beralih Breakpoint"
+msgstr "Jungkitkan Pengancingan."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Gunakan Snap"
@@ -5163,20 +5181,14 @@ msgid "Snapping Options"
msgstr "Opsi-opsi Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Grid"
-msgstr "Snap ke kotak-kotak"
+msgstr "Kancing ke Kisi"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
msgstr "Gunakan Snap Rotasi"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Atur Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relatif"
@@ -5185,39 +5197,37 @@ msgid "Use Pixel Snap"
msgstr "Gunakan Snap Piksel"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Smart Snapping"
-msgstr "Snap pintar"
+msgstr "Pengancingan Pintar"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Atur Snap..."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Parent"
-msgstr "Snap ke orang-tua"
+msgstr "Kancingkan ke Orangtuanya"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Anchor"
-msgstr "Snap ke jangkar node"
+msgstr "Kancing ke Jangkar Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Sides"
-msgstr "Snap ke sisi-sisi node"
+msgstr "Kancing ke Tepi Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Center"
-msgstr "Snap ke tengah node"
+msgstr "Kancing ke Tengah Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
-msgstr "Snape ke node-node lain"
+msgstr "Kancing ke Node Lain"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
-msgstr "Snape ke garis-bantu"
+msgstr "Kancing ke Panduan"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5240,9 +5250,8 @@ msgid "Restores the object's children's ability to be selected."
msgstr "Jadikan anak-anak object dapat di seleksi kembali."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton Options"
-msgstr "Singleton"
+msgstr "Opsi Pertulangan"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Bones"
@@ -5315,9 +5324,8 @@ msgid "Scale mask for inserting keys."
msgstr "Masker skala untuk menyisipkan key."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Insert keys (based on mask)."
-msgstr "Sisipkan Key Anim"
+msgstr "Sisipkan Kunci (berdasarkan mask)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5333,9 +5341,8 @@ msgstr ""
"Key harus disisipkan secara manual untuk pertama kali."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Auto Insert Key"
-msgstr "Sisipkan Key Anim"
+msgstr "Otomatis Sisipkan Kunci"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
@@ -5358,9 +5365,8 @@ msgid "Divide grid step by 2"
msgstr "Bagi langkah kisi demi 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Tampilan Belakang."
+msgstr "Geser Tampilan"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -5371,7 +5377,6 @@ msgid "Adding %s..."
msgstr "Menambahkan %s..."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Cannot instantiate multiple nodes without root."
msgstr "Tidak dapat menginstansiasi beberapa node tanpa root."
@@ -5386,9 +5391,8 @@ msgid "Error instancing scene from %s"
msgstr "Gagal meng-instance skena dari %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Change Default Type"
-msgstr "Ubah Tipe Nilai Array"
+msgstr "Ubah Tipe Baku"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5399,36 +5403,23 @@ msgstr ""
"Seret & lepas + Alt : Ubah tipe node"
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon3D"
-msgstr "Buat Bidang"
+msgstr "Buat Polygon3D"
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Edit Poly"
-msgstr "Sunting Bidang"
+msgstr "Sunting Poligon"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly (Remove Point)"
msgstr "Sunting Bidang (Hapus Titik)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
-#, fuzzy
msgid "Set Handle"
msgstr "Atur Pegangan"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-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 "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 "Muat Masker Emisi"
@@ -5436,9 +5427,8 @@ msgstr "Muat Masker Emisi"
#: 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:"
+msgstr "Mulai Ulang"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5472,9 +5462,8 @@ msgid "Emission Colors"
msgstr "Warna Emisi"
#: editor/plugins/cpu_particles_editor_plugin.cpp
-#, fuzzy
msgid "CPUParticles"
-msgstr "Partikel"
+msgstr "Partikel(CPU)"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -5519,51 +5508,44 @@ msgid "Load Curve Preset"
msgstr "Muat Preset Kurva"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
-msgstr "Tambahkan Sinyal"
+msgstr "Tambah Titik"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
-msgstr "Hapus Sinyal"
+msgstr "Hapus Titik"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Left Linear"
-msgstr "Linier"
+msgstr "Linier ke Kiri"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right Linear"
-msgstr "Tampilan Kanan."
+msgstr "Linier ke Kanan"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Load Preset"
-msgstr "Muat Galat"
+msgstr "Muat Preset"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Curve Point"
-msgstr "Hapus Sinyal"
+msgstr "Hapus Titik Kurva"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Toggle Curve Linear Tangent"
msgstr "Beralih Kurva Linear Tangen"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Hold Shift to edit tangents individually"
msgstr "Tahan Shift untuk menyunting tangen kurva satu-persatu"
#: editor/plugins/gi_probe_editor_plugin.cpp
msgid "Bake GI Probe"
-msgstr ""
+msgstr "Panggang GI Probe"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
-msgstr ""
+msgstr "Gradasi Disunting"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -5574,7 +5556,6 @@ msgid "Items"
msgstr "Item"
#: editor/plugins/item_list_editor_plugin.cpp
-#, fuzzy
msgid "Item List Editor"
msgstr "Penyunting Daftar Item"
@@ -5592,7 +5573,7 @@ msgstr "Buat Badan Trimesh Statis"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Convex Body"
-msgstr ""
+msgstr "Buat Bodi Cembung Statis"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
@@ -5607,9 +5588,8 @@ msgid "Failed creating shapes!"
msgstr "Gagal membuat bentuk!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Convex Shape(s)"
-msgstr "Buat Baru %s"
+msgstr "Buat Bentuk Cembung"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
@@ -5625,7 +5605,7 @@ msgstr "UV Unwrap gagal, mesh mungkin tidak bermacam-macam?"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "No mesh to debug."
-msgstr ""
+msgstr "Tidak ada mesh untuk diawakutu."
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/sprite_editor_plugin.cpp
@@ -5638,7 +5618,7 @@ msgstr "MeshInstance tidak memiliki Mesh!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
-msgstr ""
+msgstr "Mesh belum muncul untuk membuat garis tepi darinya!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
@@ -5649,41 +5629,36 @@ msgid "Could not create outline!"
msgstr "Tidak dapat membuat garis!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Outline"
-msgstr "Buat Garis"
+msgstr "Buat Garis Tepi"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr ""
+msgstr "Jala"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
msgstr "Buat Tubuh Statis Trimesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Trimesh Collision Sibling"
-msgstr "Buat Saudara Tabrakan Trimesh"
+msgstr "Buat Trimesh Collision Sibling"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Convex Collision Sibling(s)"
-msgstr "Buat Bidang"
+msgstr "Buat Convex Collision Sibling"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
msgstr "Buat Garis Mesh..."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "View UV1"
-msgstr "File:"
+msgstr "Tampilkan UV1"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "View UV2"
-msgstr "File:"
+msgstr "Tampilkan UV2"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Unwrap UV2 for Lightmap/AO"
@@ -5758,499 +5733,483 @@ msgid "Surface source is invalid (no faces)."
msgstr "Sumber permukaan tidak valid (tidak ada bidang)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
-msgstr ""
+msgstr "Pilih Mesh Sumber:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Target Surface:"
-msgstr ""
+msgstr "Pilih Target Permukaan:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Populate Surface"
-msgstr ""
+msgstr "Isi Permukaan"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Populate MultiMesh"
-msgstr ""
+msgstr "Isi MultiMesh"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Target Surface:"
-msgstr ""
+msgstr "Permukaan Target:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Source Mesh:"
-msgstr ""
+msgstr "Sumber Mesh:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "X-Axis"
-msgstr ""
+msgstr "Sumbu-X"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Y-Axis"
-msgstr ""
+msgstr "Sumbu-Y"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Z-Axis"
-msgstr ""
+msgstr "Sumbu-Z"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh Up Axis:"
-msgstr ""
+msgstr "Sumbu Atas Mesh:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Random Rotation:"
-msgstr ""
+msgstr "Perputaran Acak:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Random Tilt:"
-msgstr ""
+msgstr "Kemiringan Acak:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Random Scale:"
-msgstr ""
+msgstr "Skala Acak:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Populate"
-msgstr ""
+msgstr "Isi"
#: editor/plugins/navigation_polygon_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Navigation Polygon"
-msgstr ""
+msgstr "Buat Poligon Navigasi"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Convert to CPUParticles"
-msgstr "Sambungkan Ke Node:"
+msgstr "Konversikan menjadi CPUParticles"
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Generating Visibility Rect"
-msgstr ""
+msgstr "Menghasilkan Kotak Penampakan"
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Generate Visibility Rect"
-msgstr ""
+msgstr "Buatkan Kotak Penampakan"
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Can only set point into a ParticlesMaterial process material"
-msgstr ""
+msgstr "Hanya dapat mengatur titik ke dalam material proses ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
-msgstr ""
+msgstr "Waktu Pembuatan (detik):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr ""
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Node tidak mengandung geometri (bidang)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr ""
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
+msgstr "Node tidak mengandung geometri."
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Node tidak mengandung geometri."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
-msgstr ""
+msgstr "Buat Pengemisi"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Points:"
-msgstr ""
+msgstr "Titik Emisi:"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Surface Points"
-msgstr ""
+msgstr "Titik Permukaan"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Surface Points+Normal (Directed)"
-msgstr ""
+msgstr "Titik+Normal Permukaan (Diarahkan)"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
-msgstr ""
+msgstr "Volume"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Source: "
-msgstr ""
+msgstr "Sumber Emisi: "
#: editor/plugins/particles_editor_plugin.cpp
msgid "A processor material of type 'ParticlesMaterial' is required."
-msgstr ""
+msgstr "Pemroses material atau jenis 'ParticlesMaterial' dibutuhkan."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generating AABB"
-msgstr ""
+msgstr "Membuat AABB"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generate Visibility AABB"
-msgstr ""
+msgstr "Buat Penampakan AABB"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generate AABB"
-msgstr ""
+msgstr "Buat AABB"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
-msgstr ""
+msgstr "Hapus Titik dari Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Out-Control from Curve"
-msgstr ""
+msgstr "Hapus Kontrol-Luar dari Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove In-Control from Curve"
-msgstr ""
+msgstr "Hapus Kontrol-Dalam dari Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Add Point to Curve"
-msgstr ""
+msgstr "Tambah Titik ke Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Split Curve"
-msgstr "Sunting Kurva Node"
+msgstr "Pisahkan Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move Point in Curve"
-msgstr ""
+msgstr "Geser Titik dalam Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move In-Control in Curve"
-msgstr ""
+msgstr "Geser Kontrol-Dalam dalam Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move Out-Control in Curve"
-msgstr ""
+msgstr "Geser Kontrol-Luar dalam Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Select Points"
-msgstr ""
+msgstr "Pilih Titik"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Shift+Drag: Select Control Points"
-msgstr ""
+msgstr "Shift+Seret: Pilih Titik Kontrol"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Click: Add Point"
-msgstr ""
+msgstr "Klik: Tambah Titik"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Left Click: Split Segment (in curve)"
-msgstr ""
+msgstr "Klik Kiri: Pisahkan Segmen (dalam Kurva)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Right Click: Delete Point"
-msgstr ""
+msgstr "Klik Kanan: Hapus Titik"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Select Control Points (Shift+Drag)"
-msgstr ""
+msgstr "Pilih Titik Kontrol (Shift+Seret)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Add Point (in empty space)"
-msgstr ""
+msgstr "Tambah Titik (dalam ruang kosong)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Delete Point"
-msgstr ""
+msgstr "Hapus Titik"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Close Curve"
-msgstr ""
+msgstr "Tutup Kurva"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
msgid "Options"
-msgstr ""
+msgstr "Opsi"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Angles"
-msgstr ""
+msgstr "Cermin Pengatur Sudut"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Lengths"
-msgstr ""
+msgstr "Cermin Pengatur Panjang"
#: editor/plugins/path_editor_plugin.cpp
msgid "Curve Point #"
-msgstr ""
+msgstr "Titik #"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Set Curve Point Position"
-msgstr "Hapus Sinyal"
+msgstr "Atur Posisi Titik Kurva"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Set Curve In Position"
-msgstr "Hapus Sinyal"
+msgstr "Atur Posisi Kurva Dalam"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Set Curve Out Position"
-msgstr "Hapus Sinyal"
+msgstr "Atur Posisi Kurva Luar"
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Path"
-msgstr ""
+msgstr "Pisahkan Tapak"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove Path Point"
-msgstr ""
+msgstr "Hapus Titik Tapak"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Remove Out-Control Point"
-msgstr "Hapus Autoload"
+msgstr "Hapus Titik Kontrol-Luar"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove In-Control Point"
-msgstr ""
+msgstr "Hapus Titik Kontrol-Dalam"
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Segment (in curve)"
-msgstr ""
+msgstr "Pisahkan Segmen (dalam kurva)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
-msgstr "Hapus Sinyal"
+msgstr "Geser Persendian"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
-msgstr ""
+msgstr "Properti pertulangan dari Polygon2D tidak mengarah ke node Skeleton2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones"
-msgstr ""
+msgstr "Sinkronkan Pertulangan"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"No texture in this polygon.\n"
"Set a texture to be able to edit UV."
msgstr ""
+"Tidak ada tekstur dalam poligon ini.\n"
+"Atur tekstur supaya bisa menyunting UV-nya."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create UV Map"
-msgstr ""
+msgstr "Buat Peta UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"Polygon 2D has internal vertices, so it can no longer be edited in the "
"viewport."
msgstr ""
+"Polygon2D memiliki verteks internal, jadi tidak bisa disunting lagi di dalam "
+"viewport."
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon & UV"
-msgstr "Buat Bidang"
+msgstr "Buat Poligon & UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Internal Vertex"
-msgstr "Buat Subskribsi"
+msgstr "Buat Verteks Internal"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Internal Vertex"
-msgstr "Hapus item"
+msgstr "Hapus Verteks Internal"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Invalid Polygon (need 3 different vertices)"
-msgstr ""
+msgstr "Poligon tidak valid (butuh 3 verteks yang berbeda)"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Add Custom Polygon"
-msgstr "Sunting Bidang"
+msgstr "Tambah Poligon Kustom"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Custom Polygon"
-msgstr "Hapus Bidang dan Titik"
+msgstr "Hapus Poligon Kustom"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Transform UV Map"
-msgstr ""
+msgstr "Transformasikan Peta UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Transform Polygon"
-msgstr "Buat Bidang"
+msgstr "Transformasikan Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint Bone Weights"
-msgstr ""
+msgstr "Gambar Pembobotan Tulang"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Open Polygon 2D UV editor."
-msgstr "Penyunting UV Poligon 2D"
+msgstr "Buka Penyunting UV Poligon 2D."
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Polygon 2D UV Editor"
msgstr "Penyunting UV Poligon 2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV"
-msgstr ""
+msgstr "UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Points"
msgstr "Titik"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Polygons"
-msgstr "Sunting Bidang"
+msgstr "Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Bones"
-msgstr ""
+msgstr "Tulang"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Points"
-msgstr "Hapus Sinyal"
+msgstr "Geser Titik"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
-msgstr ""
+msgstr "Ctrl: Putar"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
-msgstr ""
+msgstr "Shift: Geser Semua"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift+Ctrl: Scale"
-msgstr ""
+msgstr "Shift+Ctrl: Skala"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Move Polygon"
-msgstr ""
+msgstr "Geser Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Rotate Polygon"
-msgstr ""
+msgstr "Putar Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Scale Polygon"
-msgstr ""
+msgstr "Skalakan Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create a custom polygon. Enables custom polygon rendering."
-msgstr ""
+msgstr "Buat poligon kustom. Mengaktifkan perenderan poligon kustom."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"Remove a custom polygon. If none remain, custom polygon rendering is "
"disabled."
msgstr ""
+"Hapus poligon kustom. Jika tidak tersisa, perenderan poligon kustom "
+"dinonaktifkan."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint weights with specified intensity."
-msgstr ""
+msgstr "Gambar pembobotan dengan intensitas yang ditentukan."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Unpaint weights with specified intensity."
-msgstr ""
+msgstr "Hapus pembobotan dengan intensitas yang ditentukan."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Radius:"
-msgstr ""
+msgstr "Radius:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon->UV"
-msgstr ""
+msgstr "Poligon->UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV->Polygon"
-msgstr ""
+msgstr "UV->Poligon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
-msgstr ""
+msgstr "Bersihkan UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Settings"
-msgstr "Pengaturan Editor"
+msgstr "Pengaturan Kisi"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
-msgstr ""
+msgstr "Pengancingan"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr ""
+msgstr "Aktifkan Pengancingan"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
-msgstr ""
+msgstr "Kisi"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Configure Grid:"
-msgstr "Atur Snap"
+msgstr "Konfigurasikan Kisi:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset X:"
-msgstr ""
+msgstr "Ofset X Kisi:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset Y:"
-msgstr ""
+msgstr "Ofset Y Kisi:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step X:"
-msgstr ""
+msgstr "Jarak X Kisi:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step Y:"
-msgstr ""
+msgstr "Jarak Y Kisi:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones to Polygon"
-msgstr ""
+msgstr "Sinkronkan Tulang ke Poligon"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
-msgstr ""
+msgstr "KESALAHAN: Tidak dapat memuat sumber daya!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Add Resource"
-msgstr ""
+msgstr "Tambah Sumber Daya"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Rename Resource"
@@ -6271,7 +6230,6 @@ msgstr "Tempel Resource"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Instance:"
msgstr "Instansi:"
@@ -6283,7 +6241,6 @@ msgstr "Jenis:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open in Editor"
msgstr "Buka dalam Penyunting"
@@ -6292,9 +6249,8 @@ msgid "Load Resource"
msgstr "Muat Sumber Daya"
#: editor/plugins/resource_preloader_editor_plugin.cpp
-#, fuzzy
msgid "ResourcePreloader"
-msgstr "Resource"
+msgstr "PreloaderSumberDaya"
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "AnimationTree has no path set to an AnimationPlayer"
@@ -6313,59 +6269,46 @@ msgid "Close and save changes?"
msgstr "Tutup dan simpan perubahan?"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error writing TextFile:"
-msgstr "Error menyimpan TileSet!"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error: could not load file."
-msgstr "Tidak dapat membuat folder."
+msgstr "Galat saat menulis TextFile:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error could not load file."
-msgstr "Tidak dapat membuat folder."
+msgid "Could not load file at:"
+msgstr "Galat tidak dapat memuat berkas."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "Error menyimpan TileSet!"
+msgstr "Galat saat menyimpan berkas!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "Error saat menyimpan."
+msgstr "Galat saat menyimpan tema."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
-msgstr "Galat saat memindahkan:"
+msgstr "Galat Menyimpan"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "Galat saat mengimpor:"
+msgstr "Galat saat mengimpor tema."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
-msgstr "Galat saat mengimpor:"
+msgstr "Galat saat mengimpor"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
-msgstr "Buat Direktori..."
+msgid "New Text File..."
+msgstr "Berkas Teks Baru..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
-msgstr "Buka sebuah File"
+msgstr "Buka Berkas"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Save File As..."
-msgstr "Simpan Sebagai..."
+msgstr "Simpan Berkas Sebagai..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme"
@@ -6393,23 +6336,20 @@ msgid "Find Next"
msgstr "Pencarian Selanjutnya"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Filter:"
+msgstr "Penyaring Skrip"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle alphabetical sorting of the method list."
msgstr "Beralih penyortiran alfabetis dari daftar fungsi."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter methods"
-msgstr "Filter:"
+msgstr "Penyaring fungsi"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Sort"
-msgstr "Sortir:"
+msgstr "Urutkan"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
@@ -6436,9 +6376,13 @@ msgid "File"
msgstr "Berkas"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "Buka"
+msgstr "Buka..."
+
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Buka Cepat Script..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
@@ -6446,27 +6390,24 @@ msgstr "Simpan Semua"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr ""
+msgstr "Muat Ulang Skrip secara Halus"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Copy Script Path"
-msgstr "Salin Resource"
+msgstr "Salin Lokasi Skrip"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "History Previous"
-msgstr "Tab sebelumnya"
+msgstr "Riwayat Sebelumnya"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Next"
-msgstr ""
+msgstr "Riwayat Selanjutnya"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Theme"
-msgstr "Simpan Tema"
+msgstr "Tema"
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme..."
@@ -6481,188 +6422,185 @@ msgid "Save Theme"
msgstr "Simpan Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Tutup Dokumentasi"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Tutup Semua"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Tutup Dokumentasi"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Jalankan"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Scripts Panel"
-msgstr "Beralih Favorit"
+msgstr "Jungkitkan Panel Skrip"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
-msgstr ""
+msgstr "Langkahi"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr ""
+msgstr "Masuki"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
-msgstr ""
+msgstr "Putuskan"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr ""
+msgstr "Lanjutkan"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
-msgstr ""
+msgstr "Biarkan Pengawakutu Terbuka"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Debug with External Editor"
-msgstr "Debug menggunakan penyunting eksternal"
+msgstr "Awakutu menggunakan Penyunting Eksternal"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open Godot online documentation."
-msgstr "Buka baru-baru ini"
+msgstr "Buka dokumentasi daring Godot."
#: editor/plugins/script_editor_plugin.cpp
msgid "Request Docs"
-msgstr ""
+msgstr "Minta Dokumentasi"
#: editor/plugins/script_editor_plugin.cpp
msgid "Help improve the Godot documentation by giving feedback."
-msgstr ""
+msgstr "Bantu tingkatkan dokumentasi Godot dengan memberikan tanggapan."
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
-msgstr ""
+msgstr "Cari dokumentasi referensi."
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to previous edited document."
msgstr "Ke dokumen yang disunting sebelumnya."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Go to next edited document."
-msgstr "Ke dokumen yang disunting selanjutnya."
+msgstr "Pergi ke dokumen yang disunting selanjutnya."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Discard"
-msgstr "Berlainan"
+msgstr "Abaikan"
#: editor/plugins/script_editor_plugin.cpp
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?:"
msgstr ""
+"Berkas berikut lebih baru dalam diska.\n"
+"Aksi apa yang ingin diambil?:"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Reload"
-msgstr ""
+msgstr "Muat Ulang"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Resave"
-msgstr ""
+msgstr "Simpan Ulang"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
-msgstr ""
+msgstr "Pengawakutu"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Search Results"
-msgstr "Mencari Bantuan"
+msgstr "Hasil Pencarian"
-#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Bersihkan Scenes baru-baru ini"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
-msgstr "Sambungkan Ke Node:"
+msgstr "Hubungan dengan fungsi:"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Source"
-msgstr "Resource"
+msgstr "Sumber"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "Sinyal-sinyal"
+msgstr "Sinyal"
#: editor/plugins/script_text_editor.cpp
msgid "Target"
-msgstr ""
+msgstr "Target"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
-msgstr "Memutuskan '%s' dari '%s'"
+msgstr ""
+"Tidak ditemukan fungsi '%s' yang dihubungkan untuk sinyal '%s' dari node "
+"'%s' ke node '%s'."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Line"
-msgstr "Baris:"
+msgstr "Baris"
#: editor/plugins/script_text_editor.cpp
msgid "(ignore)"
-msgstr ""
+msgstr "(abaikan)"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function"
-msgstr "Tambahkan Fungsi"
+msgstr "Pergi ke Fungsi"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
-msgstr ""
+msgstr "Hanya sumber daya dari berkas sistem yang dapat dihapus."
#: editor/plugins/script_text_editor.cpp
msgid "Lookup Symbol"
-msgstr ""
+msgstr "Simbol Pencarian"
#: editor/plugins/script_text_editor.cpp
msgid "Pick Color"
-msgstr ""
+msgstr "Pilih Warna"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Convert Case"
-msgstr ""
+msgstr "Konversikan Pengkapitalan"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Uppercase"
-msgstr ""
+msgstr "Huruf Besar"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Lowercase"
-msgstr ""
+msgstr "Huruf Kecil"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Capitalize"
-msgstr ""
+msgstr "Kapitalisasi"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
-msgstr ""
+msgstr "Penyorot Sintaks"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Pergi Ke"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "Bilah Marka"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Hapus Titik"
+msgstr "Breakpoint"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6670,136 +6608,131 @@ msgid "Cut"
msgstr "Potong"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Delete Line"
-msgstr "Hapus"
+msgstr "Hapus Baris"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Left"
-msgstr ""
+msgstr "Indentasi Kiri"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Right"
-msgstr ""
+msgstr "Indentasi Kanan"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Comment"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Mode Layar Penuh"
+msgstr "Jungkitkan Komentar"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Lanjut ke Langkah Berikutnya"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Ke dokumen yang disunting sebelumnya."
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Hapus Pilihan"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
-msgstr "Pergi ke Baris"
+msgstr "Lipat/Bentangkan Baris"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
-msgstr ""
+msgstr "Lipat Semua Baris"
#: editor/plugins/script_text_editor.cpp
msgid "Unfold All Lines"
-msgstr ""
+msgstr "Bentangkan Semua Baris"
#: editor/plugins/script_text_editor.cpp
msgid "Clone Down"
-msgstr ""
+msgstr "Duplikat ke Bawah"
#: editor/plugins/script_text_editor.cpp
msgid "Complete Symbol"
-msgstr ""
+msgstr "Simbol Lengkap"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Seleksi Skala"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
-msgstr ""
+msgstr "Hapus Spasi di Belakang"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Spaces"
-msgstr "Sambungkan Ke Node:"
+msgstr "Konversikan Indentasi ke Spasi"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Tabs"
-msgstr "Sambungkan Ke Node:"
+msgstr "Konversikan Indentasi ke Tab"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr ""
+msgstr "Indentasi Otomatis"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Beralih Breakpoint"
+msgid "Find Previous"
+msgstr "Cari Sebelumnya"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr ""
+msgid "Find in Files..."
+msgstr "Cari Dalam Berkas..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Lanjut ke Langkah Berikutnya"
+msgid "Contextual Help"
+msgstr "Bantuan Kontekstual"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Ke dokumen yang disunting sebelumnya."
+msgid "Toggle Bookmark"
+msgstr "Jungkitkan Markah Buku"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+msgid "Go to Next Bookmark"
+msgstr "Pergi ke Markah Buku Berikutnya"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Find in Files..."
-msgstr "Saring berkas..."
+msgid "Go to Previous Bookmark"
+msgstr "Pergi ke Markah Buku Sebelumnya"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Hapus Semua Markah Buku"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function..."
-msgstr "Hapus Fungsi"
+msgstr "Pergi ke Fungsi..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Line..."
-msgstr "Pergi ke Baris"
+msgstr "Pergi ke Baris..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr ""
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Beralih Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Hapus Semua Titik Jeda"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Pergi ke Langkah Jeda Berikutnya"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Pergi ke Langkah Jeda Sebelumnya"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
+"Shader ini telah dimodifikasi dalam diska.\n"
+"Aksi apa yang harus diambil?"
#: editor/plugins/shader_editor_plugin.cpp
msgid "Shader"
-msgstr ""
+msgstr "Shader"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "This skeleton has no bones, create some children Bone2D nodes."
msgstr ""
+"Kerangka ini tidak memiliki pertulangan, buatlah beberapa anak node Bone2D."
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Create Rest Pose from Bones"
@@ -6807,122 +6740,115 @@ msgstr "Buat Pose Istirahat dari Pertulangan"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Rest Pose to Bones"
-msgstr ""
+msgstr "Atur Pose Istirahat ke Pertulangan"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton2D"
-msgstr "Singleton"
+msgstr "Skeleton2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
-msgstr ""
+msgstr "Buat Pose Istirahat (Dari Pertulangan)"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Bones to Rest Pose"
-msgstr ""
+msgstr "Atur Tulang ke Pose Istirahat"
#: editor/plugins/skeleton_editor_plugin.cpp
msgid "Create physical bones"
-msgstr ""
+msgstr "Buat tulang fisik"
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton"
-msgstr "Singleton"
+msgstr "Kerangka"
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Create physical skeleton"
-msgstr "Buat Subskribsi"
+msgstr "Buat kerangka fisik"
#: editor/plugins/skeleton_ik_editor_plugin.cpp
-#, fuzzy
msgid "Play IK"
-msgstr "Mainkan"
+msgstr "Mainkan IK"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
-msgstr ""
+msgstr "Ortogonal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective"
-msgstr ""
+msgstr "Perspektif"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Aborted."
-msgstr ""
+msgstr "Transformasi Dibatalkan."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "X-Axis Transform."
-msgstr ""
+msgstr "Transformasi Sumbu X."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Y-Axis Transform."
-msgstr ""
+msgstr "Transformasi Sumbu Y."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Z-Axis Transform."
-msgstr ""
+msgstr "Transformasi Sumbu Z."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
-msgstr ""
+msgstr "Tampilkan Transformasi Planar."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scaling: "
-msgstr ""
+msgstr "Penskalaan: "
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Translating: "
-msgstr "Transisi"
+msgstr "Mentranslasi: "
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotating %s degrees."
-msgstr ""
+msgstr "Memutar %s derajat."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Keying is disabled (no key inserted)."
-msgstr ""
+msgstr "Penguncian dinonaktifkan (tidak ada kunci yang dimasukkan)."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Animation Key Inserted."
-msgstr ""
+msgstr "Kunci Animasi Dimasukkan."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pitch"
-msgstr ""
+msgstr "Dongak"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Yaw"
-msgstr ""
+msgstr "Oleng"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
-msgstr ""
+msgstr "Objek Digambar"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Material Changes"
-msgstr "Menyimpan perubahan-perubahan lokal..."
+msgstr "Perubahan Material"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Shader Changes"
-msgstr "Ubah"
+msgstr "Perubahan Shader"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Surface Changes"
-msgstr ""
+msgstr "Perubahan Permukaan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Draw Calls"
-msgstr ""
+msgstr "Gambarkan Panggilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Vertices"
-msgstr ""
+msgstr "Titik"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
@@ -6969,127 +6895,125 @@ msgid "Rear"
msgstr "Belakang"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Align with View"
-msgstr "Tampilan Kanan."
+msgid "Align Transform with View"
+msgstr "Sejajarkan Transformasi dengan Tampilan"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Sejajarkan Rotasi dengan Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
-msgstr ""
+msgstr "Tidak ada induk untuk menginstance turunan disana."
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "This operation requires a single selected node."
-msgstr ""
+msgstr "Operasi ini membutuhkan satu node yang dipilih."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
-msgstr ""
+msgstr "Kunci Rotasi Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Normal"
-msgstr ""
+msgstr "Tampilkan Normal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Wireframe"
-msgstr ""
+msgstr "Tampilkan Jaring-jaring"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Overdraw"
-msgstr ""
+msgstr "Tampilkan Overdraw"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Unshaded"
-msgstr ""
+msgstr "Tampilan Tak Berbayang"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Environment"
-msgstr ""
+msgstr "Tampilkan Lingkungan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Gizmos"
-msgstr ""
+msgstr "Tampilkan Gizmo"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
-msgstr ""
+msgstr "Tampilkan Informasi"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "View FPS"
-msgstr "File:"
+msgstr "Tampilkan FPS"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Half Resolution"
-msgstr "Beri Skala Seleksi"
+msgstr "Setengah Resolusi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Audio Listener"
-msgstr ""
+msgstr "Listener Audio"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Doppler Enable"
-msgstr "Aktifkan"
+msgid "Enable Doppler"
+msgstr "Aktifkan penyaringan"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Cinematic Preview"
-msgstr "Buat Pratinjau Mesh"
+msgstr "Pratinjau Sinematik"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
-msgstr ""
+msgstr "TampilanBebas Kiri"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Right"
-msgstr ""
+msgstr "TampilanBebas Kanan"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Freelook Forward"
-msgstr "Maju"
+msgstr "TampilanBebas Maju"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Freelook Backwards"
-msgstr "Ke belakang"
+msgstr "TampilanBebas Mundur"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
-msgstr ""
+msgstr "TampilanBebas Atas"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Freelook Down"
-msgstr "Scroll kebawah."
+msgstr "TampilanBebas Bawah"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Speed Modifier"
-msgstr ""
+msgstr "Pengubah Kecepatan TampilanBebas"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
+"Catatan: Nilai FPS yang ditampilkan adalah framerate-nya penyunting.\n"
+"Tidak bisa digunakan sebagai indikasi kinerja game yang dapat dihandalkan."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
-msgstr ""
+msgstr "Rotasi Tampilan Terkunci"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
-msgstr ""
+msgstr "Dialog XForm"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
-msgstr ""
+msgstr "Kancingkan Node ke Lantai"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Metode Publik:"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7097,486 +7021,422 @@ msgid ""
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
+"Seret: Rotasi\n"
+"Alt+Seret: Geser\n"
+"Alt+Klik Kanan: Daftar seleksi mendalam"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Metode Publik:"
+msgid "Use Local Space"
+msgstr "Mode Ruang Lokal (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
-msgstr ""
+msgstr "Tampilan Bawah"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View"
-msgstr ""
+msgstr "Tampilan Atas"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
-msgstr ""
+msgstr "Tampilan Belakang"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View"
-msgstr ""
+msgstr "Tampilan Depan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left View"
-msgstr ""
+msgstr "Tampilan Kiri"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Right View"
-msgstr ""
+msgstr "Tampilan Kanan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
-msgstr ""
+msgstr "Beralih Tampilan Ortogonal/Perspektif"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
-msgstr ""
+msgstr "Sisipkan Kunci Animasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
-msgstr ""
+msgstr "Asal Fokus"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "Semua pilihan"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
+msgstr "Pemilihan Fokus"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Freelook"
-msgstr "Mode Layar Penuh"
+msgstr "Jungkitkan Mode Tampilan Bebas"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform"
-msgstr ""
+msgstr "Transformasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
-msgstr ""
+msgstr "Kancingkan Objek ke Lantai"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
-msgstr ""
+msgstr "Dialog Transformasi..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
-msgstr ""
+msgstr "1 Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports"
-msgstr ""
+msgstr "2 Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
-msgstr ""
+msgstr "2 Tampilan (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
-msgstr ""
+msgstr "3 Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
-msgstr ""
+msgstr "3 Tampilan (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
-msgstr ""
+msgstr "4 Tampilan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
-msgstr ""
+msgstr "Gizmo"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Origin"
-msgstr ""
+msgstr "Tampilkan Titik Asal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Grid"
-msgstr ""
+msgstr "Tampilkan Kisi"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Pengaturan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
-msgstr ""
+msgstr "Pengaturan Pengancingan"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate Snap:"
-msgstr ""
+msgstr "Kancing Translasi:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr ""
+msgstr "Kancing Rotasi (derajat):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
-msgstr ""
+msgstr "Kancing Skala (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
-msgstr ""
+msgstr "Pengaturan Viewport"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
-msgstr ""
+msgstr "FOV Perspektif (derajat):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Near:"
-msgstr ""
+msgstr "Tampilan Z-Terdekat:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Far:"
-msgstr ""
+msgstr "Tampilan Z-Terjauh:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Change"
-msgstr ""
+msgstr "Perubahan Transformasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate:"
-msgstr ""
+msgstr "Translasi:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate (deg.):"
-msgstr ""
+msgstr "Rotasi (derajat):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale (ratio):"
-msgstr ""
+msgstr "Skala (rasio):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Type"
-msgstr ""
+msgstr "Jenis Transformasi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pre"
-msgstr ""
+msgstr "Sebelum"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Post"
-msgstr ""
+msgstr "Sesudah"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Nameless gizmo"
-msgstr ""
+msgstr "Gizmo tak bernama"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Mesh2D"
-msgstr "Buat Baru %s"
+msgstr "Buat Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon2D"
-msgstr "Buat Bidang"
+msgstr "Buat Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create CollisionPolygon2D"
-msgstr "Buat Bidang"
+msgstr "Buat CollisionPolygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create LightOccluder2D"
-msgstr "Buat Folder"
+msgstr "Buat LightOccluder2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite is empty!"
-msgstr ""
+msgstr "Sprite kosong!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
-msgstr ""
+msgstr "Tidak dapat mengonversi sprite menggunakan frame animasi menjadi mesh."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't replace by mesh."
-msgstr ""
+msgstr "Geometri tidak valid, tidak dapat diganti dengan mesh."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Mesh2D"
-msgstr "Sambungkan Ke Node:"
+msgstr "Konversikan menjadi Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
-msgstr ""
+msgstr "Geometri tidak valid, tidak dapat membuat poligon."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Polygon2D"
-msgstr "Sambungkan Ke Node:"
+msgstr "Konversikan menjadi Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
-msgstr ""
+msgstr "Geometri tidak valid, tidak dapat membuat collision polygon."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create CollisionPolygon2D Sibling"
-msgstr "Buat Bidang"
+msgstr "Buat CollisionPolygon2D Sibling"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create light occluder."
-msgstr ""
+msgstr "Geometri tidak valid, tidak dapat membuat light occluder."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create LightOccluder2D Sibling"
-msgstr ""
+msgstr "Buat LightOccluder2D Sibling"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
-msgstr ""
+msgstr "Sprite"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
-msgstr ""
+msgstr "Penyederhanaan: "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Grow (Pixels): "
-msgstr ""
+msgstr "Pertumbuhan (Piksel): "
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Update Preview"
-msgstr "Pratinjau"
+msgstr "Perbarui Pratinjau"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "Mengatur..."
+msgstr "Pengaturan:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "Tidak ada berkas dipilih!"
+msgstr "Tidak ada frame yang dipilih"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr ""
+msgstr "Tambah %d Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr ""
+msgstr "Tambah Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
-msgstr ""
+msgstr "GALAT: Tidak dapat memuat aset frame!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Resource clipboard is empty or not a texture!"
-msgstr ""
+msgstr "Papan klip sumber daya kosong atau bukan tekstur!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
-msgstr ""
+msgstr "Rekat Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
-msgstr ""
+msgstr "Tambah Kosong"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation FPS"
-msgstr ""
+msgstr "Ubah FPS Animasi"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "(empty)"
-msgstr ""
+msgstr "(kosong)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "Animasi"
+msgstr "Animasi:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "New Animation"
-msgstr "Animasi"
+msgstr "Animasi Baru"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Speed (FPS):"
-msgstr ""
+msgstr "Kecepatan (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr ""
+msgstr "Pengulangan"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animation Frames:"
-msgstr "Nama Animasi:"
+msgstr "Frame Animasi:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add a Texture from File"
-msgstr "Tambahkan Node (Node-node) dari Tree"
+msgstr "Tambah Tekstur dari Berkas"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr ""
+msgstr "Tambah Frame dari Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
-msgstr ""
+msgstr "Sisipkan Kosong (Sebelum)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (After)"
-msgstr ""
+msgstr "Sisipkan Kosong (Sesudah)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move (Before)"
-msgstr "Salin Resource"
+msgstr "Geser (Sebelum)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (After)"
-msgstr ""
+msgstr "Geser (Sesudah)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "Mode Seleksi"
+msgstr "Pilih Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
-msgstr ""
+msgstr "Horisontal:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Vertical:"
-msgstr ""
+msgstr "Vertikal:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select/Clear All Frames"
-msgstr "Pilih Semua"
+msgstr "Pilih/Hapus Semua Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Create Frames from Sprite Sheet"
-msgstr "Buat dari Tema Editor Saat Ini"
+msgstr "Buat Frame dari Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
-msgstr ""
+msgstr "SpriteFrame"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
-msgstr ""
+msgstr "Atur Kotak Region"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Margin"
-msgstr ""
+msgstr "Atur Batas"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr ""
+msgstr "Mode Pengancingan:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
msgid "None"
-msgstr ""
+msgstr "Tidak ada"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr ""
+msgstr "Pengancingan Piksel"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr ""
+msgstr "Pengancingan Kisi"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
-msgstr ""
+msgstr "Iris Otomatis"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Offset:"
-msgstr ""
+msgstr "Pengimbangan:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
-msgstr ""
+msgstr "Langkah:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
-msgstr ""
+msgstr "Pemisah:"
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "TextureRegion"
-msgstr "Penyunting Daerah Tekstur"
-
-#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
+msgstr "TeksturRegion"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
-msgstr ""
+msgstr "Tambahkan Semua Item"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All"
-msgstr ""
+msgstr "Tambahkan Semua"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Remove All Items"
-msgstr "Hapus Pilihan"
+msgstr "Hapus Semua Item"
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Remove All"
-msgstr "Hapus"
+msgstr "Hapus semua"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "Sunting tema..."
+msgstr "Sunting Tema"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
@@ -7584,118 +7444,113 @@ msgstr "Menu untuk menyunting tema."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
-msgstr ""
+msgstr "Tambah Item Kelas"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Class Items"
-msgstr ""
+msgstr "Hapus Item Kelas"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Template"
-msgstr ""
+msgstr "Buat Templat Kosong"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Create Empty Editor Template"
-msgstr "Buat Templat Penyunting Kosongan"
+msgstr "Buat Templat Penyunting Kosong"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Create From Current Editor Theme"
-msgstr "Buat dari Tema Editor Saat Ini"
+msgstr "Buat dari Tema Penyunting Saat Ini"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Button"
-msgstr "Kondisikan Putar Otomatis"
+msgstr "Tombol Jungkit"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Button"
-msgstr "Dinonaktifkan"
+msgstr "Tombol Dinonaktifkan"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
-msgstr ""
+msgstr "Item"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Item"
-msgstr "Dinonaktifkan"
+msgstr "Item yang Dinonaktifkan"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Check Item"
-msgstr ""
+msgstr "Item Check"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Checked Item"
-msgstr ""
+msgstr "Item yang Dicentang"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Radio Item"
-msgstr ""
+msgstr "Item Radio"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Checked Radio Item"
-msgstr ""
+msgstr "Item Radio yang Dicentang"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Named Sep."
-msgstr ""
+msgstr "Pemisah yang diberi nama."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Submenu"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
-msgstr ""
+#, fuzzy
+msgid "Subitem 1"
+msgstr "Item 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
-msgstr ""
+#, fuzzy
+msgid "Subitem 2"
+msgstr "Item 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
-msgstr ""
+msgstr "Memiliki"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Many"
-msgstr ""
+msgstr "Banyak"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled LineEdit"
-msgstr "Dinonaktifkan"
+msgstr "LineEdit Dinonaktifkan"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
-msgstr ""
+msgstr "Tab 1"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 2"
-msgstr ""
+msgstr "Tab 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 3"
-msgstr ""
+msgstr "Tab 3"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Editable Item"
-msgstr "Edit Variabel:"
+msgstr "Item dapat diedit"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Subpohon"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
-msgstr ""
+msgstr "Memiliki,Banyak,Opsi"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
-msgstr ""
+msgstr "Jenis data:"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Icon"
@@ -7703,11 +7558,11 @@ msgstr "Ikon"
#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Style"
-msgstr ""
+msgstr "Gaya"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Font"
-msgstr ""
+msgstr "Fonta"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
@@ -7718,273 +7573,250 @@ msgid "Constant"
msgstr "Konstan"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Erase Selection"
-msgstr "Beri Skala Seleksi"
+msgstr "Hapus Pilihan"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Fix Invalid Tiles"
-msgstr "Nama tidak sah."
+msgstr "Perbaiki Tile Tidak Valid"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cut Selection"
-msgstr "Beri Skala Seleksi"
+msgstr "Potong Pilihan"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
-msgstr ""
+msgstr "Cat TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Line Draw"
-msgstr "Linier"
+msgstr "Lukis Segaris"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rectangle Paint"
-msgstr ""
+msgstr "Cat Persegi Panjang"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Bucket Fill"
-msgstr ""
+msgstr "Ember Isian"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
-msgstr ""
+msgstr "Hapus TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "Pencarian Selanjutnya"
+msgstr "Cari Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
+msgstr "Mengubah urutan"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
-msgstr ""
+msgstr "Nonaktifkan Autotile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Enable Priority"
-msgstr "Sunting Filter"
+msgstr "Aktifkan Prioritas"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr ""
+msgstr "Cat Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift + Klik Kanan: Menggambar Garis\n"
+"Shift + Ctrl + Klik Kanan: Cat Persegi Panjang"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr ""
+msgstr "Pilih Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
-msgstr "Mode Putar"
+msgstr "Putar ke Kiri"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
-msgstr "Mode Putar"
+msgstr "Putar ke kanan"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
-msgstr ""
+msgstr "Balik secara Horizontal"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Vertically"
-msgstr ""
+msgstr "Balik secara Vertikal"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Transform"
-msgstr "Ubah Transformasi Animasi"
+msgstr "Bersihkan Transformasi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Add Texture(s) to TileSet."
-msgstr "Tambahkan Node (Node-node) dari Tree"
+msgstr "Tambahkan Tekstur ke TileSet."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "Hapus Sinyal"
+msgstr "Hapus Tekstur yang dipilih dari TileSet."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
-msgstr ""
+msgstr "Buat dari Skena"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from Scene"
-msgstr ""
+msgstr "Gabung dari Skena"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Next Coordinate"
-msgstr ""
+msgstr "Koordinat berikutnya"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the next shape, subtile, or Tile."
-msgstr ""
+msgstr "Pilih bentuk berikutnya, subtile, atau Tile."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Previous Coordinate"
-msgstr "Tab sebelumnya"
+msgstr "Koordinat Sebelumnya"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the previous shape, subtile, or Tile."
-msgstr ""
+msgstr "Pilih bentuk sebelumnya, subtile, atau Tile."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "Mode Putar"
+msgstr "Mode Wilayah"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "Mode Interpolasi"
+msgstr "Mode Tabrakan"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion Mode"
-msgstr "Sunting Bidang"
+msgstr "Mode Oklusi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Mode"
-msgstr "Node Animasi"
+msgstr "Mode Navigasi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask Mode"
-msgstr "Mode Putar"
+msgstr "Mode Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "Ekspor Projek"
+msgstr "Mode Prioritas"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "Mode Geser Pandangan"
+msgstr "Mode Ikon"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index Mode"
-msgstr "Mode Geser Pandangan"
+msgstr "Mode Indeks Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
-msgstr ""
+msgstr "Salin bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste bitmask."
-msgstr "Tempelkan Animasi"
+msgstr "Rekatkan bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Erase bitmask."
-msgstr "Beri Skala Seleksi"
+msgstr "Hapus bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new rectangle."
-msgstr "Buat Baru %s"
+msgstr "Buat persegi panjang baru."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "Buat Bidang"
+msgstr "Buat poligon baru."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
-msgstr ""
+msgstr "Jaga poligon agar tetap di dalam wilayah Rect."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
msgstr ""
+"Aktifkan pengancingan dan tampilkan kisi (dapat dikonfigurasi melalui "
+"Inspektur)."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
-msgstr ""
+msgstr "Tampilkan Nama Tile (Tahan Tombol Alt)"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected texture? This will remove all tiles which use it."
-msgstr "Hapus Sinyal"
+msgstr ""
+"Hapus tekstur yang dipilih? Ini akan menghapus semua tile yang "
+"menggunakannya."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "You haven't selected a texture to remove."
-msgstr ""
+msgstr "Anda belum memilih tekstur untuk dihapus."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from scene? This will overwrite all current tiles."
-msgstr ""
+msgstr "Buat dari skena? Ini akan menimpa semua tile saat ini."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from scene?"
-msgstr ""
+msgstr "Gabung dari skena?"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Texture"
-msgstr "Hapus Templat"
+msgstr "Hapus Tekstur"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "%s file(s) were not added because was already on the list."
-msgstr ""
+msgstr "Berkas %s tidak ditambahkan karena sudah ada dalam daftar."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
"Drag handles to edit Rect.\n"
"Click on another Tile to edit it."
msgstr ""
+"Seret gagang untuk menyunting Rect.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete selected Rect."
-msgstr "Hapus file yang dipilih?"
+msgstr "Hapus Rect yang dipilih."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select current edited sub-tile.\n"
"Click on another Tile to edit it."
-msgstr "Simpan sumber yang sedang diatur."
+msgstr ""
+"Pilih sub-tile yang disunting saat ini.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "Hapus Titik"
+msgstr "Hapus poligon."
#: 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 "Simpan sumber yang sedang diatur."
+msgstr ""
+"Klik Kiri: Nyalakan bit.\n"
+"Klik Kanan: Matikan bit.\n"
+"Shift + Klik Kiri: Atur bit wildcard.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -7992,630 +7824,684 @@ msgid ""
"bindings.\n"
"Click on another Tile to edit it."
msgstr ""
+"Pilih sub-tile untuk digunakan sebagai ikon, sub-tile juga akan digunakan "
+"pada binding autotile yang tidak valid.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
"Select sub-tile to change its priority.\n"
"Click on another Tile to edit it."
msgstr ""
+"Pilih sub-tile untuk mengubah prioritasnya.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: 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 "Simpan sumber yang sedang diatur."
+msgstr ""
+"Pilih sub-tile untuk mengubah nilai index Z-nya.\n"
+"Klik pada Tile lain untuk menyuntingnya."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Set Tile Region"
-msgstr "Penyunting Daerah Tekstur"
+msgstr "Atur Tile Region"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Tile"
-msgstr "Buat Folder"
+msgstr "Buat Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Icon"
-msgstr ""
+msgstr "Atur Ikon Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Bitmask"
-msgstr "Sunting Filter"
+msgstr "Sunting Bitmask Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Collision Polygon"
-msgstr "Sunting poligon yang ada:"
+msgstr "Sunting Poligon Collision"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Occlusion Polygon"
-msgstr "Sunting Bidang"
+msgstr "Sunting Poligon Oklusi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Navigation Polygon"
-msgstr "Sunting poligon yang ada:"
+msgstr "Sunting Poligon Navigasi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste Tile Bitmask"
-msgstr "Tempelkan Animasi"
+msgstr "Rekatkan Bitmask Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Clear Tile Bitmask"
-msgstr ""
+msgstr "Bersihkan Bitmask Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Polygon Concave"
-msgstr ""
+msgstr "Buat Poligon Cekung"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Polygon Convex"
-msgstr "Buat Bidang"
+msgstr "Buat Poligon Cembung"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Tile"
-msgstr "Hapus Templat"
+msgstr "Hapus Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Collision Polygon"
-msgstr "Hapus Bidang dan Titik"
+msgstr "Hapus Poligon Collision"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Occlusion Polygon"
-msgstr "Hapus Autoload"
+msgstr "Hapus Poligon Oklusi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Navigation Polygon"
-msgstr "Hapus Animasi"
+msgstr "Hapus Poligon Navigasi"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Priority"
-msgstr "Sunting Filter"
+msgstr "Sunting Prioritas Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
-msgstr ""
+msgstr "Sunting Index Z Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Collision Polygon"
-msgstr "Buat Bidang"
+msgstr "Buat Poligon Collision"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Occlusion Polygon"
-msgstr "Buat Bidang"
+msgstr "Buat Poligon Oklusi"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "This property can't be changed."
msgstr "Properti ini tidak dapat diubah."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "TileSet..."
+msgstr "TileSet"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Hanya GLES3)"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input +"
-msgstr "Tambah Masukan"
+msgstr "Tambah masukan +"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add output +"
-msgstr "Tambah Masukan"
+msgstr "Tambah keluaran +"
#: 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 "Inspektur"
+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 "Tambah Masukan"
+msgstr "Tambah port masukan"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "Tambah port keluaran"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port type"
-msgstr "Ubah Tipe Nilai Array"
+msgstr "Ubah jenis port masukan"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "Ubah Tipe Nilai Array"
+msgstr "Ubah jenis port keluaran"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "Ubah Nilai Array"
+msgstr "Ubah nama port masukan"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port name"
-msgstr "Ubah Nilai Array"
+msgstr "Ubah nama port keluaran"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove input port"
-msgstr "Hapus Sinyal"
+msgstr "Hapus port masukan"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove output port"
-msgstr "Hapus Sinyal"
+msgstr "Hapus port keluaran"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set expression"
-msgstr "Ubah Pernyataan"
+msgstr "Tetapkan ekspresi"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Resize VisualShader node"
-msgstr "Hapus Variabel"
+msgstr "Atur ulang ukuran node VisualShader"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Uniform Name"
-msgstr ""
+msgstr "Tetapkan Nama Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set Input Default Port"
-msgstr "Jadikan Baku untuk '%s'"
+msgstr "Atur Port Masukan Baku"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node to Visual Shader"
-msgstr ""
+msgstr "Tambah Node ke Visual Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Duplicate Nodes"
-msgstr "Duplikat Key"
+msgstr "Duplikat Node"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
+msgid "Paste Nodes"
+msgstr "Path ke Node:"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
-msgstr "Metode Publik:"
+msgstr "Hapus Node"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Input Type Changed"
-msgstr ""
+msgstr "Tipe Input Visual Shader Berubah"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
-msgstr ""
+msgstr "Titik"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Fragment"
-msgstr "Argumen:"
+msgstr "Fragmen"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Light"
-msgstr "Kanan"
+msgstr "Cahaya"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Buat Node Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
-msgstr "Buat Folder"
+msgstr "Buat Node Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "Tambahkan Fungsi"
+msgstr "Fungsi warna."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "Operator warna."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "Buat Fungsi"
+msgstr "Fungsi grayscale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
-msgstr ""
+msgstr "Konversikan vektor HSV menjadi setara dengan RGB."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts RGB vector to HSV equivalent."
-msgstr ""
+msgstr "Konversikan vektor RGB menjadi setara HSV."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Namai kembali Fungsi"
+msgstr "Fungsi sepia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
-msgstr ""
+msgstr "Operator terbakar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Operator gelapkan."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Hanya yang berbeda"
+msgstr "Operator perbedaan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Operator dodge."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "HardLight operator"
-msgstr ""
+msgstr "Operator HardLight"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "Operator terangkan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Operator overlay."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Operator layar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "Operator SoftLight."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
-msgstr "Konstan"
+msgstr "Konstanta warna."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Ubah Transformasi Animasi"
+msgstr "Warna seragam."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Mengembalikan hasil boolean dari perbandingan %s antara dua parameter."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Sama dengan (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Lebih Besar Dari (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Lebih Besar dari atau Sama dengan (> =)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
msgstr ""
+"Mengembalikan vektor terkait jika skalar yang disediakan sama, lebih besar "
+"atau kurang."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Mengembalikan hasil boolean dari perbandingan antara INF dan parameter "
+"skalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Mengembalikan hasil boolean dari perbandingan antara NaN dan parameter "
+"skalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Kurang dari (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Kurang dari atau Sama dengan (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Tidak sama dengan (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
+"Mengembalikan vektor terkait jika nilai boolean yang diberikan benar atau "
+"salah."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Boolean constant."
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Mengembalikan hasil boolean dari perbandingan antara dua parameter."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
msgstr ""
+"Mengembalikan hasil boolean dari perbandingan antara INF (atau NaN) dan "
+"parameter skalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr "Konstanta Boolean."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "Seragam Boolean."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "Parameter masukan '% s' untuk semua mode shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Snap ke orang-tua"
+msgstr "Parameter masukan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "Parameter input '%s' untuk mode shader titik dan fragmen."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "Parameter masukan '%s' untuk mode shader fragmen dan cahaya."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "Parameter masukan '%s' untuk mode shader fragmen."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "Parameter masukan '%s' untuk mode shader cahaya."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "Parameter masukan '%s' untuk mode shader titik."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "Parameter masukan '%s' untuk mode shader titik dan fragmen."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Seleksi Skala"
+msgstr "Fungsi skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar operator."
-msgstr ""
+msgstr "Operator skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
-msgstr ""
+msgstr "Konstanta E (2.718282). Mewakili basis dari logaritma natural."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "Konstanta Epsilon (0.00001). Angka skalar terkecil yang mungkin."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "Konstanta Phi (1.618034). Rasio emas."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/4 constant (0.785398) or 45 degrees."
-msgstr ""
+msgstr "Konstanta Pi/4 (0.785398) atau 45 derajat."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/2 constant (1.570796) or 90 degrees."
-msgstr ""
+msgstr "Konstanta Pi/2 (1.570796) atau 90 derajat."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "Konstanta pi (3.141593) atau 180 derajat."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "Konstanta Tau (6.283185) atau 360 derajat."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "Konstanta Sqrt2 (1.414214). Akar kuadrat dari 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai absolut dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai arc-cosinus dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Mengembalikan nilai cosinus hiperbolik invers dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai arc-sinus dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Mengembalikan nilai sinus hiperbolik invers dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai arc-tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "Mengembalikan nilai arc-tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Mengembalikan nilai hiperbolik tangen invers dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
msgstr ""
+"Mencari bilangan bulat terdekat yang lebih besar dari atau sama dengan "
+"parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
-msgstr ""
+msgstr "Batasi nilai untuk berada di antara dua nilai selanjutnya."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai cosinus dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Mengembalikan nilai cosinus hiperbolik dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "Mengubah kuantitas dalam radian menjadi derajat."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr ""
+msgstr "Eksponensial Basis-E."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr ""
+msgstr "Eksponensial Basis-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
msgstr ""
+"Mencari bilangan bulat terdekat kurang dari atau sama dengan parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "Hitung bagian pecahan dari argumen."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai invers dari akar kuadrat dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "Logaritma natural."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "Logaritma basis-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "Mengembalikan nilai yang lebih besar dari dua nilai."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "Mengembalikan nilai terendah dari 2 nilai."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
-msgstr ""
+msgstr "Interpolasi linier antara dua skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai lawan dari parameter."
#: 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 ""
+"Mengembalikan nilai parameter pertama yang dinaikkan ke pangkat parameter "
+"kedua."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "Mengubah kuantitas dalam derajat ke radian."
#: 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 ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "Mencari bilangan bulat terdekat menuju ke parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Mencari bilangan bulat genap terdekat menuju ke parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "Patok nilai antara 0,0 dan 1,0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "Ekstrak tanda parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai sinus dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Mengembalikan nilai sinus hiperbolik dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai akar kuadrat dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Fungsi SmoothStep( skalar(tepi0), skalar(tepi1), skalar(x) ).\n"
+"\n"
+"Mengembalikan 0.0 jika 'x' lebih kecil dari 'tepi0' dan 1.0 jika x lebih "
+"besar dari 'tepi1'. Jika tidak, nilai balik diinterpolasi antara 0.0 dan 1.0 "
+"menggunakan polinomial Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Fungsi Step( skalar(tepi), skalar(x) ).\n"
+"\n"
+"Mengembalikan nilai 0.0 jika 'x' lebih kecil dari 'tepi' dan sebaliknya 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "Mengembalikan nilai tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr ""
+msgid "Finds the truncated value of the parameter."
+msgstr "Mencari nilai terpotong dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Menambahkan skalar ke skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "Membagi skalar dengan skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "Mengalikan skalar dengan skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "Mengembalikan nilai sisa dari dua skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "Kurangi skalar dari skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar constant."
-msgstr ""
+msgstr "Konstanta skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Ubah Transformasi Animasi"
+msgstr "Seragam skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "Lakukan pencarian tekstur kubik."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "Lakukan pencarian tekstur."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr ""
+msgid "Cubic texture uniform lookup."
+msgstr "Pencarian seragam tekstur kubik."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "2D texture uniform."
-msgstr "Format Tekstur"
+msgid "2D texture uniform lookup."
+msgstr "Pencarian seragam tekstur 2D."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Pencarian seragam tekstur 2D dengan triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Buat Bidang"
+msgstr "Fungsi Transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8623,171 +8509,207 @@ 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 ""
+"Menghitung produk terluar dari sepasang vektor.\n"
+"\n"
+"OuterProduct memperlakukan parameter pertama 'c' sebagai vektor kolom "
+"(matriks dengan satu kolom) dan parameter kedua 'r' sebagai vektor baris "
+"(matriks dengan satu baris) dan melakukan perkalian matriks aljabar linier "
+"'c * r', menghasilkan matriks yang banyak barisnya adalah banyak komponen "
+"dalam 'c' dan yang banyak kolomnya adalah banyak komponen dalam 'r'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
-msgstr ""
+msgstr "Menyusun transformasi dari empat vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Mengurai transformasi menjadi empat vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr ""
+msgid "Calculates the determinant of a transform."
+msgstr "Menghitung determinan dari transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Menghitung invers transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Menghitung transpos transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Mengalikan transformasi dengan transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Mengalikan vektor dengan transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Buat Bidang"
+msgstr "Konstanta Transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Buat Bidang"
+msgstr "Seragam Transformasi."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Hapus Fungsi"
+msgstr "Fungsi vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
-msgstr ""
+msgstr "Operator vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "Menyusun vektor dari tiga skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "Mengurai vektor menjadi tiga skalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "Menghitung cross product dari dua vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "Mengembalikan jarak antara dua titik."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "Menghitung dot product dari dua vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Mengembalikan vektor yang menunjuk ke arah yang sama dengan vektor "
+"referensi. Fungsi ini memiliki tiga parameter vektor: N, vektor untuk "
+"berorientasi, I, vektor insiden, dan Nref, vektor referensi. Jika dot "
+"product dari I dan Nref lebih kecil dari nol, nilai pengembaliannya adalah "
+"N. Jika tidak -N yang dikembalikan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "Menghitung panjang vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "Interpolasi linier antara dua vektor."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolasi linier antara dua vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
-msgstr ""
+msgstr "Menghitung produk normalisasi 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 "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Mengembalikan vektor yang menunjuk ke arah refleksi (a: vektor insiden, b: "
+"vektor normal)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
-msgstr ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Mengembalikan vektor yang menunjuk ke arah refraksi."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Fungsi SmoothStep( vektor(tepi0), vektor(tepi1), vektor (x)).\n"
+"\n"
+"Mengembalikan nilai 0.0 jika 'x' lebih kecil dari 'tepi0' dan 1.0 jika 'x' "
+"lebih besar dari 'tepi1'. Jika tidak, nilai balik diinterpolasi antara 0.0 "
+"dan 1.0 menggunakan polinomial Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Fungsi SmoothStep( skalar(tepi0), skalar(tepi1), skalar(x) ).\n"
+"\n"
+"Mengembalikan 0.0 jika 'x' lebih kecil dari 'tepi0' dan 1.0 jika x lebih "
+"besar dari 'tepi1'. Jika tidak, nilai balik diinterpolasi antara 0.0 dan 1.0 "
+"menggunakan polinomial Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Fungsi Step( vektor(tepi), vektor(x)).\n"
+"\n"
+"Mengembalikan nilai 0.0 jika 'x' lebih kecil dari 'tepi' dan sebaliknya 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Fungsi Step( skalar(tepi), vektor(x)).\n"
+"\n"
+"Mengembalikan nilai 0.0 jika 'x' lebih kecil dari 'tepi' dan sebaliknya 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "Menambahkan vektor ke vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "Membagi vektor dengan vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "Mengalikan vektor dengan vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two vectors."
-msgstr ""
+msgstr "Mengembalikan nilai sisa dari dua vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts vector from vector."
-msgstr ""
+msgstr "Kurangi vektor dari vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector constant."
-msgstr ""
+msgstr "Konstanta vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector uniform."
-msgstr ""
+msgstr "Seragam vektor."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8795,91 +8717,112 @@ 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 ""
+"Ekspresi Bahasa Godot Shader Kustom, dengan jumlah khusus port masukan dan "
+"keluaran. Ini adalah injeksi langsung kode ke fungsi titik/fragmen/cahaya, "
+"jangan menggunakannya untuk menulis deklarasi fungsi di dalamnya."
#: 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 ""
+"Mengembalikan nilai falloff berdasarkan dot product dari nilai normal "
+"permukaan dan arah pandangan kamera (berikan masukan yang terkait dengannya)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Khusus mode Fragmen / Cahaya) Fungsi skalar turunan."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Khusus mode Fragmen / Cahaya) Fungsi vektor turunan."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Vektor) Turunan dalam 'x' menggunakan "
+"perbedaan lokal."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Skalar) Turunan dalam 'x' menggunakan "
+"perbedaan lokal."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Vektor) Turunan dalam 'y' menggunakan "
+"perbedaan lokal."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Skalar) Turunan dalam 'y' menggunakan "
+"perbedaan lokal."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Vektor) Jumlah dari turunan absolut dari 'x' "
+"dan 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Khusus mode Fragmen/Cahaya) (Skalar) Jumlah dari turunan absolut dari 'x' "
+"dan 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
-msgstr ""
+msgstr "ShaderVisual"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "Sunting Filter"
+msgstr "Sunting Properti Visual"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Visual Shader Mode Changed"
-msgstr "Ubah"
+msgstr "Mode Shader Visual Berubah"
#: editor/project_export.cpp
-#, fuzzy
msgid "Runnable"
-msgstr "Aktifkan"
+msgstr "Dapat dijalankan"
#: editor/project_export.cpp
-#, fuzzy
msgid "Delete patch '%s' from list?"
-msgstr "Hapus Penampilan"
+msgstr "Hapus entri penambalan '%s' dari daftar?"
#: editor/project_export.cpp
-#, fuzzy
msgid "Delete preset '%s'?"
-msgstr "Hapus file yang dipilih?"
+msgstr "Hapus preset '%s'?"
#: editor/project_export.cpp
msgid ""
"Failed to export the project for platform '%s'.\n"
"Export templates seem to be missing or invalid."
msgstr ""
+"Gagal mengekspor proyek untuk platform '%s'.\n"
+"Templat Ekspor kelihatannya belum terpasang atau tidak valid."
#: editor/project_export.cpp
msgid ""
@@ -8887,203 +8830,203 @@ msgid ""
"This might be due to a configuration issue in the export preset or your "
"export settings."
msgstr ""
+"Gagal mengekspor proyek untuk platform '%s'.\n"
+"Ini mungkin disebabkan oleh masalah konfigurasi dalam preset ekspor atau "
+"pengaturan ekspor Anda."
#: editor/project_export.cpp
msgid "Release"
-msgstr ""
+msgstr "Rilis"
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "Mengekspor untuk %s"
+msgstr "Mengekspor Semua"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "File tidak ada."
+msgstr "Lokasi ekspor yang diberikan tidak ada:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
-msgstr ""
+msgstr "Templat ekspor untuk platform ini tidak ada / rusak:"
#: editor/project_export.cpp
msgid "Presets"
-msgstr ""
+msgstr "Prasetel"
#: editor/project_export.cpp editor/project_settings_editor.cpp
msgid "Add..."
-msgstr ""
+msgstr "Tambahkan..."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Path"
-msgstr "Ekspor Projek"
+msgstr "Lokasi Ekspor"
#: editor/project_export.cpp
msgid "Resources"
-msgstr ""
+msgstr "Sumber Daya"
#: editor/project_export.cpp
msgid "Export all resources in the project"
-msgstr ""
+msgstr "Ekspor semua sumber daya dalam proyek"
#: editor/project_export.cpp
msgid "Export selected scenes (and dependencies)"
-msgstr ""
+msgstr "Ekspor skena terpilih (dan dependensinya)"
#: editor/project_export.cpp
msgid "Export selected resources (and dependencies)"
-msgstr ""
+msgstr "Expor sumber daya terpilih (dan dependensinya)"
#: editor/project_export.cpp
msgid "Export Mode:"
-msgstr ""
+msgstr "Mode Ekspor:"
#: editor/project_export.cpp
msgid "Resources to export:"
-msgstr ""
+msgstr "Sumber daya yang akan diexpor:"
#: editor/project_export.cpp
msgid ""
"Filters to export non-resource files (comma separated, e.g: *.json, *.txt)"
msgstr ""
+"Penyaringan untuk mengekspor berkas non-sumber (dipisahkan koma, contoh: *."
+"json, *.txt)"
#: editor/project_export.cpp
msgid ""
"Filters to exclude files from project (comma separated, e.g: *.json, *.txt)"
msgstr ""
+"Penyaringan untuk mengecualikan berkas dalam proyek (dipisahkan koma, "
+"contoh: *.json, *.txt)"
#: editor/project_export.cpp
-#, fuzzy
msgid "Patches"
-msgstr "Kecocokan:"
+msgstr "Tambalan"
#: editor/project_export.cpp
msgid "Make Patch"
-msgstr ""
+msgstr "Buat Tambalan"
#: editor/project_export.cpp
msgid "Features"
-msgstr ""
+msgstr "Fitur"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
-msgstr ""
+msgstr "Ubah suaian (dipisahkan koma):"
#: editor/project_export.cpp
-#, fuzzy
msgid "Feature List:"
-msgstr "Daftar Fungsi:"
+msgstr "Daftar Fitur:"
#: editor/project_export.cpp
msgid "Script"
msgstr "Skrip"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script Export Mode:"
-msgstr "Ekspor Projek"
+msgstr "Mode Ekspor Skrip:"
#: editor/project_export.cpp
msgid "Text"
-msgstr ""
+msgstr "Teks"
#: editor/project_export.cpp
msgid "Compiled"
-msgstr ""
+msgstr "Dikompilasi"
#: editor/project_export.cpp
msgid "Encrypted (Provide Key Below)"
-msgstr ""
+msgstr "Dienkripsi (Sertakan Kunci Berikut)"
#: editor/project_export.cpp
msgid "Invalid Encryption Key (must be 64 characters long)"
-msgstr ""
+msgstr "Kunci Enkripsi Tidak Valid (panjangnya harus 64 karakter)"
#: editor/project_export.cpp
msgid "Script Encryption Key (256-bits as hex):"
-msgstr ""
+msgstr "Kunci Enkripsi Skrip (256-bit berbentuk heksa):"
#: editor/project_export.cpp
msgid "Export PCK/Zip"
-msgstr ""
+msgstr "Ekspor PCK/Zip"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "Ekspor Projek"
+msgstr "Mode ekspor?"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All"
-msgstr "Ekspor"
+msgstr "Ekspor Semua"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
-msgstr ""
+msgstr "Tidak ada templat ekspor untuk platform ini:"
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Mengatur Templat Ekspor"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export With Debug"
-msgstr "Ekspor Tile Set"
+msgstr "Ekspor dengan Awakutu"
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path does not exist."
-msgstr "File tidak ada."
+msgstr "Lokasi ini tidak ada."
#: editor/project_manager.cpp
msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
-msgstr ""
+msgstr "Berkas proyek '.zip' tidak valid, tidak berisi berkas 'project.godot'."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
-msgstr ""
+msgstr "Silakan pilih direktori kosong."
#: editor/project_manager.cpp
msgid "Please choose a 'project.godot' or '.zip' file."
-msgstr ""
+msgstr "Silakan pilih berkas 'project.godot' atau '.zip'."
#: editor/project_manager.cpp
msgid "Directory already contains a Godot project."
-msgstr ""
+msgstr "Direktori ini sudah berisi proyek Godot."
#: editor/project_manager.cpp
-#, fuzzy
msgid "New Game Project"
-msgstr "Projek Baru Permainan"
+msgstr "Proyek Baru Permainan"
#: editor/project_manager.cpp
msgid "Imported Project"
-msgstr ""
+msgstr "Proyek yang Diimpor"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Nama Projek:"
+msgstr "Nama Proyek Tidak Valid."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Couldn't create folder."
msgstr "Tidak dapat membuat folder."
#: editor/project_manager.cpp
msgid "There is already a folder in this path with the specified name."
-msgstr ""
+msgstr "Sudah ada direktori di lokasi ini dengan nama yang diberikan."
#: editor/project_manager.cpp
msgid "It would be a good idea to name your project."
-msgstr ""
+msgstr "Sebaiknya berikan nama untuk proyek Anda."
#: editor/project_manager.cpp
msgid "Invalid project path (changed anything?)."
-msgstr ""
+msgstr "Lokasi proyek tidak valid (mengubah sesuatu?)."
#: editor/project_manager.cpp
msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
+"Tidak dapat memuat project.godot dalam lokasi proyek (galat %d). Mungkin "
+"berkas itu tidak ada atau rusak."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
@@ -9091,16 +9034,15 @@ msgstr "Tidak dapat menyunting project.godot dalam lokasi proyek."
#: editor/project_manager.cpp
msgid "Couldn't create project.godot in project path."
-msgstr ""
+msgstr "Tidak dapat membuat project.godot dalam lokasi proyek."
#: editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "Berkas berikut gagal diekstrak dari paket:"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Rename Project"
-msgstr "Projek Baru Permainan"
+msgstr "Ubah Nama Proyek"
#: editor/project_manager.cpp
msgid "Import Existing Project"
@@ -9120,7 +9062,7 @@ msgstr "Buat & Ubah"
#: editor/project_manager.cpp
msgid "Install Project:"
-msgstr ""
+msgstr "Pasang Proyek:"
#: editor/project_manager.cpp
msgid "Install & Edit"
@@ -9135,17 +9077,16 @@ msgid "Project Path:"
msgstr "Lokasi Projek:"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Project Installation Path:"
-msgstr "Lokasi Projek:"
+msgstr "Lokasi Pemasangan Proyek:"
#: editor/project_manager.cpp
msgid "Renderer:"
-msgstr ""
+msgstr "Perender:"
#: editor/project_manager.cpp
msgid "OpenGL ES 3.0"
-msgstr ""
+msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid ""
@@ -9154,10 +9095,14 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
+"Kualitas visual lebih tinggi\n"
+"Semua fitur tersedia\n"
+"Tidak kompatibel dengan perangkat lama\n"
+"Tidak direkomendasikan untuk permainan berbasis web"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
-msgstr ""
+msgstr "OpenGL ES 2.0"
#: editor/project_manager.cpp
msgid ""
@@ -9166,24 +9111,35 @@ msgid ""
"Works on most hardware\n"
"Recommended for web games"
msgstr ""
+"Kualitas visual lebih rendah\n"
+"Beberapa fitur tidak tersedia\n"
+"Bekerja di sebagian besar perangkat\n"
+"Direkomendasikan untuk permainan berbasis web"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
-msgstr ""
+msgstr "Perender dapat diubah nanti, tapi skena mungkin perlu disesuaikan."
#: editor/project_manager.cpp
msgid "Unnamed Project"
-msgstr ""
+msgstr "Proyek Tanpa Nama"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Impor Projek yang Sudah Ada"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
-msgstr "Menyambungkan..."
+msgstr "Tidak dapat membuka proyek di '%s'."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to open more than one project?"
-msgstr "Apakah Anda yakin membuka lebih dari satu projek?"
+msgstr "Apakah Anda yakin membuka lebih dari satu proyek?"
#: editor/project_manager.cpp
msgid ""
@@ -9197,6 +9153,15 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
+"Berkas pengaturan proyek berikut tidak mencantumkan versi Godot mana ketika "
+"itu dibuat.\n"
+"\n"
+"%s\n"
+"\n"
+"Jika Anda memutuskan untuk membukanya, proyek ini akan dikonversi ke format "
+"berkas pengaturan Godot saat ini.\n"
+"Peringatan: Anda tidak akan lagi bisa membuka proyek ini menggunakan versi "
+"Godot sebelumnya."
#: editor/project_manager.cpp
msgid ""
@@ -9209,12 +9174,22 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
+"Berkas pengaturan proyek berikut dihasilkan oleh Godot versi lebih lama, dan "
+"perlu dikonversi untuk versi ini.\n"
+"\n"
+"%s\n"
+"\n"
+"Apakah Anda ingin mengonversinya?\n"
+"Peringatan: Anda tidak akan lagi bisa membuka proyek ini menggunakan Godot "
+"versi sebelumnya."
#: editor/project_manager.cpp
msgid ""
"The project settings were created by a newer engine version, whose settings "
"are not compatible with this version."
msgstr ""
+"Pengaturan proyek dibuat oleh versi mesin yang lebih baru, yang mana "
+"pengaturannya tidak kompatibel dengan versi ini."
#: editor/project_manager.cpp
msgid ""
@@ -9231,49 +9206,63 @@ msgid ""
"Can't run project: Assets need to be imported.\n"
"Please edit the project to trigger the initial import."
msgstr ""
+"Tidak dapat menjalankan proyek: Aset perlu diimpor.\n"
+"Silakan sunting proyek untuk memicu pengimporan awal."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "Apakah Anda yakin menjalankan lebih dari satu projek?"
+msgstr "Apakah Anda yakin menjalankan %d proyek sekaligus?"
#: editor/project_manager.cpp
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
msgstr ""
+"Hapus %d proyek dalam daftar?\n"
+"Konten di folder proyek tidak akan dimodifikasi."
#: editor/project_manager.cpp
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
msgstr ""
+"Hapus proyek ini dalam daftar?\n"
+"Konten di folder proyek tidak akan dimodifikasi."
#: editor/project_manager.cpp
+#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
+"Hapus %d proyek dalam daftar?\n"
+"Konten di folder proyek tidak akan dimodifikasi."
#: editor/project_manager.cpp
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
+"Bahasa diubah.\n"
+"Antarmuka akan diperbarui setelah menjalankan ulang penyunting atau manajer "
+"proyek."
#: editor/project_manager.cpp
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
msgstr ""
+"Apakah Anda yakin untuk memindai %s folder untuk proyek Godot yang ada?\n"
+"Ini bisa memakan waktu yang lama."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Manajer Proyek"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Daftar Projek"
+#, fuzzy
+msgid "Projects"
+msgstr "Proyek"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9288,41 +9277,36 @@ msgid "New Project"
msgstr "Projek Baru"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Hapus Sinyal"
+msgstr "Hapus yang Tidak Ada"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Templates"
-msgstr "Hapus Pilihan"
-
-#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Keluar"
+msgstr "Templat"
#: editor/project_manager.cpp
msgid "Restart Now"
-msgstr ""
+msgstr "Mulai ulang Sekarang"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Can't run project"
-msgstr "Menyambungkan..."
+msgstr "Tidak dapat menjalankan proyek"
#: editor/project_manager.cpp
msgid ""
"You currently don't have any projects.\n"
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+"Saat ini Anda tidak memiliki proyek.\n"
+"Apakah Anda ingin menjelajahi contoh proyek resmi di Pustaka Aset?"
#: editor/project_settings_editor.cpp
msgid "Key "
-msgstr ""
+msgstr "Kunci "
#: editor/project_settings_editor.cpp
msgid "Joy Button"
-msgstr ""
+msgstr "Tombol Joystick"
#: editor/project_settings_editor.cpp
msgid "Joy Axis"
@@ -9330,36 +9314,35 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Mouse Button"
-msgstr ""
+msgstr "Tombol Mouse"
#: editor/project_settings_editor.cpp
msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
msgstr ""
+"Nama aksi tidak valid. Tidak boleh kosong atau mengandung '/', ':', '=', "
+"'\\' atau '\"'"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "KESALAHAN: Nama animasi sudah ada!"
+msgstr "Sudah ada aksi dengan nama '%s'."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
-msgstr ""
+msgstr "Ubah nama Input Action Event"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "Ubah Nama Animasi:"
+msgstr "Ubah deadzone Aksi"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
-msgstr ""
+msgstr "Tambah Input Action Event"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "All Devices"
-msgstr "Perangkat"
+msgstr "Semua Perangkat"
#: editor/project_settings_editor.cpp
msgid "Device"
@@ -9375,55 +9358,51 @@ msgstr "Alt+"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Control+"
-msgstr ""
+msgstr "Kontrol+"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr ""
+msgstr "Tekan Tombol..."
#: editor/project_settings_editor.cpp
msgid "Mouse Button Index:"
-msgstr ""
+msgstr "Indeks Tombol Mouse:"
#: editor/project_settings_editor.cpp
msgid "Left Button"
-msgstr ""
+msgstr "Tombol Kiri"
#: editor/project_settings_editor.cpp
msgid "Right Button"
-msgstr ""
+msgstr "Tombol Kanan"
#: editor/project_settings_editor.cpp
msgid "Middle Button"
-msgstr ""
+msgstr "Tombol Tengah"
#: editor/project_settings_editor.cpp
msgid "Wheel Up Button"
-msgstr ""
+msgstr "Tombol Gulir ke atas"
#: editor/project_settings_editor.cpp
msgid "Wheel Down Button"
-msgstr ""
+msgstr "Tombol Gulir ke bawah"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Left Button"
-msgstr "Tombol Kiri."
+msgstr "Tombol Gulir ke kiri"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Right Button"
-msgstr "Tombol Kanan."
+msgstr "Tombol Gulir ke kanan"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 1"
-msgstr "Tombol"
+msgstr "Tombol X 1"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 2"
-msgstr "Tombol"
+msgstr "Tombol X 2"
#: editor/project_settings_editor.cpp
msgid "Joypad Axis Index:"
@@ -9653,6 +9632,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Pengaya"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9711,14 +9694,6 @@ msgstr "Metode Publik:"
msgid "Select Method"
msgstr "Metode Publik:"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10017,6 +9992,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Ubah nama port keluaran"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10063,6 +10043,11 @@ msgid "Extend Script"
msgstr "Buka Cepat Script..."
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Buat Baru %s"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Jadikan Skena Dasar"
@@ -10141,19 +10126,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10254,6 +10239,11 @@ msgid "Error loading script from %s"
msgstr "Error memuat font."
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Timpa"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10288,7 +10278,7 @@ msgid "Script is valid."
msgstr "Pohon animasi valid."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10457,6 +10447,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Pengaturan Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10903,10 +10897,30 @@ msgid "Set Variable Type"
msgstr "Edit Variabel:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Tidak boleh sama dengan nama tipe bawaan yang ada."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Buat persegi panjang baru."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variabel-variabel:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Buat persegi panjang baru."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Buat poligon baru."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Nama bukan sebuah pengidentifikasi yang sah:"
@@ -11109,11 +11123,6 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "Path ke Node:"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "Anggota"
@@ -11867,8 +11876,9 @@ msgid "HSV"
msgstr ""
#: scene/gui/color_picker.cpp
+#, fuzzy
msgid "Raw"
-msgstr ""
+msgstr "Mentah"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11959,22 +11969,6 @@ msgstr ""
"tidak, jadikan sebagai RenderTarget dan tetapkan tekstur internal nya ke "
"beberapa node untuk ditampilkan."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Error menginisialisasi FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Format font tidak diketahui."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error memuat font."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ukuran font tidak sah."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Masukan"
@@ -11989,6 +11983,11 @@ msgstr "Ukuran font tidak sah."
msgid "Invalid source for shader."
msgstr "Ukuran font tidak sah."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ukuran font tidak sah."
+
#: servers/visual/shader_language.cpp
#, fuzzy
msgid "Assignment to function."
@@ -12008,6 +12007,114 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex."
msgid "Constants cannot be modified."
msgstr "Konstanta tidak dapat dimodifikasi."
+#~ msgid "No Matches"
+#~ msgstr "Tidak ada yang cocok"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Tidak dapat membuka file_type_cache.cch untuk menulis, berkas cache tidak "
+#~ "disimpan!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "'%s' tidak bisa ditelusuri karena tidak bisa ditemukan dalam berkas "
+#~ "sistem!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Galat saat memuat gambar:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Tidak ada piksel dengan transparansi > 128 di dalam gambar..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Induk tidak memiliki sisi yang solid untuk diisi."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Tidak dapat memetakan area."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Bidang tidak memiliki area!"
+
+#~ msgid "No faces!"
+#~ msgstr "Tidak ada bidang!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Galat: tidak dapat memuat berkas."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Aktifkan Efek Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Pilih Mode (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Mode Geser (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Mode Rotasi (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Mode Skala (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Koordinat Lokal"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Mode Pengancingan (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Alat Pilih"
+
+#~ msgid "Tool Move"
+#~ msgstr "Alat Geser"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Alat Rotasi"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Alat Skala"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Hapus semua proyek yang hilang dalam daftar? (folder konten tidak akan "
+#~ "dimodifikasi)"
+
+#~ msgid "Project List"
+#~ msgstr "Daftar Projek"
+
+#~ msgid "Exit"
+#~ msgstr "Keluar"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Error menginisialisasi FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Format font tidak diketahui."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error memuat font."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ukuran font tidak sah."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Direktori Sebelumnya"
+
+#~ msgid "Next Folder"
+#~ msgstr "Folder Berikutnya"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Buka Screenshoots secara otomatis"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Buka di pengolah gambar lainnya"
+
+#~ msgid "Reverse"
+#~ msgstr "Terbalik"
+
#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "Gagal memuat resource."
@@ -12487,9 +12594,6 @@ msgstr "Konstanta tidak dapat dimodifikasi."
#~ msgid "Pick New Name and Location For:"
#~ msgstr "Tentukan Nama dan Lokasi Baru untuk:"
-#~ msgid "Re-Import..."
-#~ msgstr "Impor Ulang..."
-
#, fuzzy
#~ msgid "Texture Options"
#~ msgstr "Opsi Tekstur"
diff --git a/editor/translations/is.po b/editor/translations/is.po
index d63db7f02d..7a5faac0b8 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -59,7 +59,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -134,6 +133,31 @@ msgid "Anim Change Call"
msgstr "Útkall breyting símtal"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim breyta lyklagrind tími"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim breyting umskipti"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Breyta umbreytingu"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim breyta lyklagrind gildi"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Útkall breyting símtal"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -638,15 +662,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -871,8 +895,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -966,7 +989,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -1003,7 +1026,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr "Breyta"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1092,14 +1115,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1116,7 +1139,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1133,7 +1156,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1602,12 +1624,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1669,7 +1690,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1720,7 +1741,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1745,23 +1766,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1995,6 +2020,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2292,6 +2321,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2385,6 +2422,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2438,6 +2479,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Fjarlægja val"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2465,20 +2511,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2511,24 +2553,33 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Breyta..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2608,13 +2659,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Stillið breyting á:"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2629,14 +2681,6 @@ 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 ""
@@ -2657,14 +2701,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2672,12 +2716,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2950,6 +2995,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Breyta:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3111,7 +3161,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3128,6 +3178,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3189,12 +3243,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3208,13 +3260,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3299,19 +3355,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3344,11 +3392,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3408,6 +3456,10 @@ msgstr "Hreyfimynd Tvöfalda Lykla"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3471,6 +3523,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3531,6 +3587,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3538,12 +3602,21 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Anim DELETE-lyklar"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3556,12 +3629,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Breyta"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3767,7 +3841,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4520,10 +4594,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4536,14 +4606,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4584,6 +4682,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4612,13 +4714,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4626,7 +4730,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4639,7 +4743,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4651,6 +4755,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4701,31 +4809,33 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Fjarlægja val"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Fjarlægja val"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4807,6 +4917,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Breyta umbreytingu"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4836,6 +4951,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4856,14 +4972,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4887,6 +5006,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4903,11 +5023,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4920,6 +5035,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5127,16 +5247,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5450,14 +5560,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5541,19 +5643,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5884,7 +5990,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5990,11 +6095,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6018,7 +6119,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6099,6 +6200,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6136,11 +6241,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6228,6 +6333,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6294,6 +6403,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6328,92 +6438,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Val á kvarða"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6591,7 +6706,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6647,7 +6766,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6701,7 +6820,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6712,27 +6831,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6776,26 +6875,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6850,7 +6929,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7148,10 +7227,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7238,11 +7313,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7349,14 +7424,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7370,8 +7437,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7663,6 +7730,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7743,6 +7814,11 @@ msgid "Duplicate Nodes"
msgstr "Tvíteknir lyklar"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Anim DELETE-lyklar"
@@ -7764,6 +7840,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7837,6 +7917,22 @@ msgid "Color uniform."
msgstr "Breyta umbreytingu"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7844,10 +7940,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7937,7 +8067,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7945,7 +8075,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7957,7 +8087,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7974,7 +8104,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8043,11 +8173,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8063,7 +8193,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8074,7 +8204,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8083,7 +8213,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8091,11 +8221,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8136,11 +8266,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8149,7 +8283,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8167,15 +8301,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8224,7 +8358,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8239,6 +8373,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8252,19 +8390,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8273,7 +8411,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8282,14 +8420,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8334,47 +8472,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8541,6 +8686,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8687,6 +8836,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8756,8 +8913,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8780,8 +8937,9 @@ msgid "Project Manager"
msgstr "Verkefna Stjóri"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Verkefna Stjóri"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8805,10 +8963,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9143,6 +9297,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9195,14 +9353,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9490,6 +9640,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9532,6 +9686,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9604,19 +9762,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9707,6 +9865,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9735,7 +9897,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9895,6 +10057,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10308,10 +10474,27 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Val á kvarða"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10496,10 +10679,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11229,22 +11408,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11257,6 +11420,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 41cdd4df93..fa32a7d606 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -35,12 +35,16 @@
# Marco <rodomar705@gmail.com>, 2019.
# Davide Giuliano <davidegiuliano00@gmail.com>, 2019.
# Stefano Merazzi <asso99@hotmail.com>, 2019.
+# Sinapse X <sinapsex13@gmail.com>, 2019.
+# Micila Micillotto <micillotto@gmail.com>, 2019.
+# Mirko Soppelsa <miknsop@gmail.com>, 2019.
+# No <kingofwizards.kw7@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:50+0000\n"
-"Last-Translator: Marco <rodomar705@gmail.com>\n"
+"PO-Revision-Date: 2019-08-04 14:23+0000\n"
+"Last-Translator: No <kingofwizards.kw7@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -92,7 +96,6 @@ msgid "On call to '%s':"
msgstr "Alla chiamata di '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Libero"
@@ -161,6 +164,26 @@ msgid "Anim Change Call"
msgstr "Cambia chiamata animazione"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Cambio Multiplo Tempo Keyframe"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Animazione Cambio Multiplo Transizione"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Animazione Cambio Multiplo Trasformazione"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animazione Cambio Multiplo Valore Keyframe"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Animazione Cambio Multiplo Chiamata"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Cambia lunghezza dell'animazione"
@@ -662,16 +685,18 @@ msgid "Line Number:"
msgstr "Numero linea:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Rimpiazzate %d occorrenze."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Nessuna corrispondenza"
+#, fuzzy
+msgid "%d match."
+msgstr "Trovata/e %d corrispondenza/e."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Rimpiazzate %d occorrenze."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Trovata/e %d corrispondenza/e."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -821,9 +846,8 @@ msgid "Connect"
msgstr "Connetti"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Segnali:"
+msgstr "Segnale:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -899,8 +923,7 @@ msgstr "Preferiti:"
msgid "Recent:"
msgstr "Recenti:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -988,9 +1011,8 @@ msgid "Owners Of:"
msgstr "Proprietari di:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Rimuovi i file selezionati dal progetto? (non annullabile)"
+msgstr "Rimuovere i file selezionati dal progetto? (Non può essere annullato)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1002,13 +1024,13 @@ msgstr ""
"esse funzionino.\n"
"Rimuoverli comunque? (non annullabile)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Impossibile rimuovere:"
#: editor/dependency_editor.cpp
msgid "Error loading:"
-msgstr "Errore in caricamento:"
+msgstr "Errore di caricamento:"
#: editor/dependency_editor.cpp
msgid "Load failed due to missing dependencies:"
@@ -1038,7 +1060,7 @@ msgstr "Eliminare permanentemente %d elementi? (Non annullabile!)"
msgid "Show Dependencies"
msgstr "Mostra Dipendenze"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Esplora risorse orfane"
@@ -1127,14 +1149,16 @@ msgid "License"
msgstr "Licenza"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licenza di terze parti"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine si basa su parecchie librerie libere ed open source, tutte "
@@ -1155,7 +1179,8 @@ msgid "Licenses"
msgstr "Licenze"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Errore nell'apertura del pacchetto, non è in formato zip."
#: editor/editor_asset_installer.cpp
@@ -1172,7 +1197,6 @@ msgid "Success!"
msgstr "Successo!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installa"
@@ -1361,7 +1385,6 @@ msgstr ""
"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 built-in type name."
msgstr "Non deve essere in conflitto con un nome di tipo built-in esistente."
@@ -1545,6 +1568,7 @@ msgstr "Modello non trovato:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"Su export di 32-bit il PCK integrato non può essere più grande di 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1563,7 +1587,6 @@ msgid "Scene Tree Editing"
msgstr "Editor delle scene"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Import Dock"
msgstr "Importa"
@@ -1572,9 +1595,8 @@ msgid "Node Dock"
msgstr "Nodo"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "Filesystem"
+msgstr "Filesystem e dock di importazione"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1625,7 +1647,6 @@ msgid "File '%s' format is invalid, import aborted."
msgstr "Il formato del file '%s' non è valido, importazione annullata."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
@@ -1642,9 +1663,8 @@ msgid "Unset"
msgstr "Disattiva"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Profilo attuale"
+msgstr "Profilo corrente:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1656,19 +1676,17 @@ msgid "New"
msgstr "Nuovo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importa"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Esporta"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Profili disponibili"
+msgstr "Profili disponibili:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1723,7 +1741,7 @@ msgstr "Mostra nel gestore file"
msgid "New Folder..."
msgstr "Nuova cartella..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Aggiorna"
@@ -1774,7 +1792,7 @@ msgstr "Va' avanti"
msgid "Go Up"
msgstr "Va' su"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Attiva/disattiva file nascosti"
@@ -1799,23 +1817,27 @@ msgid "Move Favorite Down"
msgstr "Sposta preferito in giù"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Cartella precedente"
+msgid "Go to previous folder."
+msgstr "Vai alla cartella precedente."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Cartella successiva"
+msgid "Go to next folder."
+msgstr "Vai alla cartella successiva."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Va' alla cartella superiore."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Ricarica files."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Aggiungi/rimuovi cartella attuale dai preferiti."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Attiva/disattiva visibilità dei file nascosti."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2057,6 +2079,11 @@ msgstr "Rimuovi tutto"
msgid "Clear Output"
msgstr "Svuota output"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Finestra"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Esportazione progetto fallita con codice di errore %d."
@@ -2385,6 +2412,15 @@ msgid "Pick a Main Scene"
msgstr "Scegli una scena principale"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Chiudi scena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Chiudi scena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Impossibile abilitare il componente aggiuntivo in: '%s' lettura della "
@@ -2503,6 +2539,11 @@ msgstr "Esegui Scena"
msgid "Close Tab"
msgstr "Chiudi scheda"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Chiudi scheda"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Chiudi le altre schede"
@@ -2556,6 +2597,10 @@ msgid "Go to previously opened scene."
msgstr "Vai alla scena precedentemente aperta."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copia Testo"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Scheda successiva"
@@ -2583,6 +2628,10 @@ msgstr "Nuova scena ereditata..."
msgid "Open Scene..."
msgstr "Apri scena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Apri recente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Salva scena"
@@ -2592,14 +2641,6 @@ msgid "Save All Scenes"
msgstr "Salva tutte le scene"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Chiudi scena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Apri recente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Converti in..."
@@ -2609,7 +2650,7 @@ msgstr "Libreria delle Mesh..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr "TileSet..."
+msgstr "TileSet…"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2629,25 +2670,36 @@ msgstr "Ripristina scena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Strumenti di progetto o scena vari."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Progetto"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Impostazioni progetto"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Strumenti"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Esporta..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Installa Android Build Template"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Apri la cartella del progetto"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Strumenti"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Esplora risorse orfane"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2745,12 +2797,13 @@ msgstr ""
"Quando usata in remoto su un dispositivo, sarà più efficiente con un "
"filesystem in rete."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Impostazioni editor"
#: editor/editor_node.cpp
@@ -2758,32 +2811,21 @@ msgid "Editor Layout"
msgstr "Layout dell'editor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Rendi Scena Radice"
+msgstr "Acquisisci screenshot"
#: 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"
+"Gli screenshot vengono memorizzati nella cartella Data/Settings dell'editor."
#: 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"
+msgstr "Abilita/Disabilita la console di sistema"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2799,14 +2841,15 @@ msgstr "Apri cartella impostazioni editor"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
-msgstr "Gestisci template d'esportazione"
+msgid "Manage Editor Features..."
+msgstr "Gestisci le funzionalità dell'editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gestisci template d'esportazione"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Aiuto"
@@ -2814,12 +2857,13 @@ msgstr "Aiuto"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Cerca"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentazione online"
@@ -2893,17 +2937,14 @@ msgid "Spins when the editor window redraws."
msgstr "Gira quando la finestra dell'editor viene ridisegnata."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Continuo"
+msgstr "Aggiorna continuamente"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Aggiorna cambiamenti"
+msgstr "Aggiorna quando modificato"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
msgstr "Disabilita l'icona girevole di aggiornamento"
@@ -2934,21 +2975,21 @@ msgstr "Non salvare"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
msgstr ""
+"Modello build di Android non è presente, si prega di installare i modelli "
+"rilevanti."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "Gestisci template d'esportazione"
+msgstr "Gestisci i 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."
+"Questo installerà il progetto Android per build personalizzate.\n"
+"Nota bene: per essere usato, deve essere abilitato per l'esportazione del "
+"preset."
#: editor/editor_node.cpp
msgid ""
@@ -2956,6 +2997,9 @@ msgid ""
"Remove the \"build\" directory manually before attempting this operation "
"again."
msgstr ""
+"Android build template è già installato e non sarà sovrascritto.\n"
+"Rimuovi la cartella \"build\" manualmente prima di ritentare questa "
+"operazione."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
@@ -3099,6 +3143,10 @@ msgstr "Tempo"
msgid "Calls"
msgstr "Chiamate"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Modifica Testo:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "On"
@@ -3271,7 +3319,8 @@ msgid "Import From Node:"
msgstr "Importa Da Nodo:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Ri-Scarica"
#: editor/export_template_manager.cpp
@@ -3288,6 +3337,10 @@ msgid "Download"
msgstr "Scarica"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mancante)"
@@ -3351,12 +3404,10 @@ msgid "No response."
msgstr "Nessuna risposta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Richiesta fallita."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Ridirigi Loop."
@@ -3370,15 +3421,22 @@ msgid "Download Complete."
msgstr "Download Completato."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Impossibile salvare il tema su file:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Installazione dei template fallita. Gli archivi dei template che danno "
"problemi possono essere trovati in '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Errore nella richiesta url: "
#: editor/export_template_manager.cpp
@@ -3428,9 +3486,8 @@ msgid "SSL Handshake Error"
msgstr "Errore nell'Handshake SSL"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "Estrazione asset"
+msgstr "Decomprimendo Android Build Sources"
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3464,22 +3521,11 @@ msgstr "Scarica Template"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Seleziona mirror dalla lista: (Shift+Click: Apri in Browser)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Impossibile aprire file_type_cache.cch per scrittura, non salvo la cache dei "
-"tipi di file!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Preferiti"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Impossibile navigare a '%s' perché non è stato trovato nel file system!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Stato: Importazione file fallita. Si prega di riparare il file e "
@@ -3514,14 +3560,14 @@ msgid "Provided name contains invalid characters."
msgstr "Il nome fornito contiene caratteri non validi."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Il nome contiene caratteri non validi."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Un file o cartella con questo nome é già esistente."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Il nome contiene caratteri non validi."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Rinomina file:"
@@ -3538,7 +3584,6 @@ msgid "Duplicating folder:"
msgstr "Duplicando cartella:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
msgstr "Nuova scena ereditata"
@@ -3578,6 +3623,11 @@ msgstr "Duplica..."
msgid "Move To..."
msgstr "Sposta in..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nuova scena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nuovo Script..."
@@ -3616,9 +3666,8 @@ msgid "Re-Scan Filesystem"
msgstr "Re-Scan Filesystem"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Toggle Split Mode"
-msgstr "Attiva/disattiva la modalità split"
+msgstr "Attiva/disattiva la modalità Split"
#: editor/filesystem_dock.cpp
msgid "Search files"
@@ -3644,6 +3693,11 @@ msgstr "C'è già un file o una cartella con lo stesso nome in questo percorso."
msgid "Overwrite"
msgstr "Sovrascrivi"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Crea da Scena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Crea Script"
@@ -3706,6 +3760,14 @@ msgid "Search complete"
msgstr "Ricerca completata"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Aggiungi a Gruppo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Rimuovi da Gruppo"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Il nome del gruppo è già esistente."
@@ -3713,12 +3775,23 @@ msgstr "Il nome del gruppo è già esistente."
msgid "Invalid group name."
msgstr "Nome del gruppo non valido."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gestisci Gruppi"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Elimina Gruppo Immagini"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Gruppi"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nodi non in Gruppo"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3731,12 +3804,12 @@ msgid "Nodes in Group"
msgstr "Nodi in Gruppo"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Aggiungi a Gruppo"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Rimuovi da Gruppo"
+msgid "Group Editor"
+msgstr "Editor Gruppo"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3837,7 +3910,7 @@ msgstr "Importa Come:"
#: editor/import_dock.cpp editor/property_editor.cpp
msgid "Preset..."
-msgstr "Preset..."
+msgstr "Preset…"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -3944,7 +4017,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Set"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Seleziona un Nodo per modificare Segnali e Gruppi."
#: editor/plugin_config_dialog.cpp
@@ -4261,7 +4335,6 @@ msgid "Edit Filtered Tracks:"
msgstr "Modifica Tracce Filtrate:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
msgstr "Abilita filtraggio"
@@ -4398,9 +4471,8 @@ msgid "Enable Onion Skinning"
msgstr "Abilita l'Onion Skinning"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Onion Skinning Options"
-msgstr "Onion Skinning"
+msgstr "Opzioni dell'onion skinning"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
@@ -4711,10 +4783,6 @@ msgid "View Files"
msgstr "Vedi Files"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Impossibile risolvere l'hostname:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Errore di connessione, si prega di riprovare."
@@ -4727,14 +4795,47 @@ msgid "No response from host:"
msgstr "Nessuna risposta dall'host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Impossibile risolvere l'hostname:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Richiesta fallita, codice di return:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Richiesta fallita."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Impossibile salvare il tema su file:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Richiesta fallita, troppi ridirezionamenti"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Ridirigi Loop."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Richiesta fallita, codice di return:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tempo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Hash di download non buono, si presume il file sia stato manipolato."
@@ -4775,6 +4876,10 @@ msgid "Idle"
msgstr "Inattivo"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Installa..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Riprova"
@@ -4803,13 +4908,17 @@ msgid "Last"
msgstr "Ultimo"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Tutti"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Re-Importa..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4817,8 +4926,8 @@ msgid "Sort:"
msgstr "Ordina:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Inverti"
+msgid "Reverse sorting."
+msgstr "Ordinamento inverso."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4830,7 +4939,8 @@ msgid "Site:"
msgstr "Sito:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Supporta..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4842,6 +4952,11 @@ msgid "Testing"
msgstr "Testing"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Carica..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP File degli Asset"
@@ -4900,32 +5015,32 @@ msgid "Rotation Step:"
msgstr "Step Rotazione:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Muovi guida verticale"
+msgid "Move Vertical Guide"
+msgstr "Muovi Guida Verticale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Crea nuova guida verticale"
+msgid "Create Vertical Guide"
+msgstr "Crea Guida Verticale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Rimuovi guida verticale"
+msgid "Remove Vertical Guide"
+msgstr "Rimuovi Guida Verticale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Sposta guida orizzontale"
+msgid "Move Horizontal Guide"
+msgstr "Sposta Guida Orizzontale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Crea nuova guida orizzontale"
+msgid "Create Horizontal Guide"
+msgstr "Crea Guida Orizzontale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Rimuovi guida orizzontale"
+msgid "Remove Horizontal Guide"
+msgstr "Rimuovi Guida Orizzontale"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Crea nuove guide orizzontali e verticali"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Crea Guide Orizzontali e Verticali"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4964,13 +5079,12 @@ 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."
+"Quando attivato, muovere i nodi Control cambia le loro ancore invece dei "
+"loro margini."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -4986,9 +5100,8 @@ msgstr "Cambia Ancore"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "Strumento Seleziona"
+msgstr "Blocca selezionato"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5002,22 +5115,25 @@ msgstr "Gruppo Selezionato"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Copia Selezione"
+msgstr "Rimuovi selezionati dal gruppo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
msgstr "Incolla Posa"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Rimuovi ossa"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Crea Ossa personalizzate a partire da uno o più Nodi"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Bones"
-msgstr "Pulisci Posa"
+msgstr "Rimuovi ossa"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
@@ -5042,6 +5158,7 @@ msgid "Zoom Reset"
msgstr "Ripristino Zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Modalità di Selezione"
@@ -5064,14 +5181,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+RMB: Selezione Lista Profondità"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Modalità Movimento"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Modalità Rotazione"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Modalità Scala"
@@ -5097,6 +5217,7 @@ msgid "Toggle snapping."
msgstr "Abilita snapping."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Usa lo Snap"
@@ -5105,7 +5226,6 @@ msgid "Snapping Options"
msgstr "Opzioni di Snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Grid"
msgstr "Snap alla griglia"
@@ -5114,11 +5234,6 @@ msgid "Use Rotation Snap"
msgstr "Usa lo Snap di Rotazione"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configura Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relativo"
@@ -5127,39 +5242,37 @@ msgid "Use Pixel Snap"
msgstr "Usa Pixel Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Smart Snapping"
msgstr "Snapping intelligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configura Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
-msgstr "Snap su Genitore"
+msgstr "Snap al Genitore"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Anchor"
-msgstr "Snap su ancora nodo"
+msgstr "Snap ad ancora del nodo"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Sides"
msgstr "Snap sui lati del nodo"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Center"
msgstr "Snap al centro del nodo"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
msgstr "Snap ad altri nodi"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
-msgstr "Snap sulle guide"
+msgstr "Snap alle guide"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5240,14 +5353,12 @@ msgid "Frame Selection"
msgstr "Selezione Frame"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Preview Canvas Scale"
-msgstr "Anteprima Atlas"
+msgstr "Anteprima dimensione canvas"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Translation mask for inserting keys."
-msgstr "Maschera di traduzione per inserimento chiavi"
+msgstr "Maschera di traduzione per inserimento chiavi."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation mask for inserting keys."
@@ -5268,6 +5379,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 ""
+"Inserimento automatico di chiavi quando gli oggetti sono traslati, ruotati o "
+"ridimensionati (basato sulla maschera).\n"
+"Le chiavi sono soltanto aggiunte su tracciati già esistenti, nessun "
+"tracciato nuovo verrà creato.\n"
+"Le chiavi devono essere inserite manualmente per la prima volta."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Auto Insert Key"
@@ -5294,9 +5410,8 @@ msgid "Divide grid step by 2"
msgstr "Dividi per 2 il passo della griglia"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Vista dal Retro"
+msgstr "Vista panoramica"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -5321,7 +5436,6 @@ msgid "Error instancing scene from %s"
msgstr "Errore istanziamento scena da %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Change Default Type"
msgstr "Cambia tipo di default"
@@ -5351,16 +5465,6 @@ msgstr "Imposta Maniglia"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Errore di caricamento immagine:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Nessun pixel con trasparenza >128 nell'immagine..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Carica Maschera Emissione"
@@ -5368,9 +5472,8 @@ msgstr "Carica Maschera Emissione"
#: 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"
+msgstr "Ricomincia"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5450,17 +5553,14 @@ msgid "Load Curve Preset"
msgstr "Carica Preset Curve"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
msgstr "Aggiungi punto"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
msgstr "Rimuovi punto"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Left Linear"
msgstr "Lineare sinistra"
@@ -5469,7 +5569,6 @@ msgid "Right Linear"
msgstr "Lineare destra"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Load Preset"
msgstr "Carica preset"
@@ -5592,9 +5691,8 @@ msgid "Create Trimesh Collision Sibling"
msgstr "Crea Fratello di Collisione Trimesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Convex Collision Sibling(s)"
-msgstr "Crea Fratello di Collisione Convessa"
+msgstr "Crea Fratello(i) di Collisione Convessa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
@@ -5680,14 +5778,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Sorgente superficie invalida (nessuna faccia)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Il genitore non ha facce solde da popolare."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Impossibile mappare l'area."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Seleziona una Mesh Sorgente:"
@@ -5773,20 +5863,27 @@ msgid "Generation Time (sec):"
msgstr "Tempo di Generazione (sec):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Le facce non contengono area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Il nodo non contiene geometria (facce)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Nessuna faccia!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Il nodo non contiene geometria."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Il nodo non contiene geometria (facce)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Il nodo non contiene geometria."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -5913,12 +6010,12 @@ msgstr "Opzioni"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Angles"
-msgstr ""
+msgstr "Specchia maniglie angolari"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Lengths"
-msgstr ""
+msgstr "Specchia lunghezza maniglie"
#: editor/plugins/path_editor_plugin.cpp
msgid "Curve Point #"
@@ -5957,7 +6054,6 @@ msgid "Split Segment (in curve)"
msgstr "Spezza Segmento (in curva)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
msgstr "Sposta articolazione"
@@ -6093,9 +6189,8 @@ msgstr ""
"personalizzato dei poligoni è disabilitato."
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Paint weights with specified intensity."
-msgstr "Colora i pesi con le intensità specificate."
+msgstr "Colora i pesi con l'intensità specificata."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Unpaint weights with specified intensity."
@@ -6122,7 +6217,6 @@ msgid "Grid Settings"
msgstr "Impostazioni Griglia"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Snap"
@@ -6228,12 +6322,9 @@ msgid "Error writing TextFile:"
msgstr "Errore scrittura TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Errore: impossibile caricare il file."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Errore: impossibile caricare il file."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Impossibile trovare tile:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6256,7 +6347,8 @@ msgid "Error Importing"
msgstr "Errore di Importazione"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nuovo TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6293,18 +6385,16 @@ msgid "Find Next"
msgstr "Trova Successivo"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Filtra proprietà"
+msgstr "Filtra script"
#: 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:"
+msgstr "Modalità di filtraggio"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6339,6 +6429,11 @@ msgid "Open..."
msgstr "Apri..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Apri Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Salva Tutto"
@@ -6376,13 +6471,13 @@ msgid "Save Theme"
msgstr "Salva Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Chiudi Documentazione"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Chiudi Tutto"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Chiudi Documentazione"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Esegui"
@@ -6418,7 +6513,7 @@ msgstr "Debug con Editor Esterno"
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Godot online documentation."
-msgstr "Apri la documentazione online di Godot"
+msgstr "Apri la documentazione online di Godot."
#: editor/plugins/script_editor_plugin.cpp
msgid "Request Docs"
@@ -6470,6 +6565,11 @@ msgstr "Debugger"
msgid "Search Results"
msgstr "Cerca Risultati"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Rimuovi scene recenti"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Connessioni al metodo:"
@@ -6537,8 +6637,9 @@ msgid "Syntax Highlighter"
msgstr "Evidenziatore di Sintassi"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Vai a"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6546,9 +6647,8 @@ msgid "Bookmarks"
msgstr "Segnalibri"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Crea punti."
+msgstr "Punti di rottura"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6572,22 +6672,6 @@ msgid "Toggle Comment"
msgstr "Cambia a Commento"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Abilita/Disabilita Segnalibri"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Vai al Segnalibri Successivo"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Vai al Segnalibri Precedente"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Rimuovi tutti i Segnalibri"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Piega/Dispiega Linea"
@@ -6608,6 +6692,11 @@ msgid "Complete Symbol"
msgstr "Completa Simbolo"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Scala selezione"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Taglia Spazi in Coda"
@@ -6624,29 +6713,32 @@ msgid "Auto Indent"
msgstr "Auto Indenta"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Abilita Breakpoint"
+msgid "Find Previous"
+msgstr "Trova Precedente"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Rimuovi Tutti i Breakpoints"
+msgid "Find in Files..."
+msgstr "Cerca nei File..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Vai a Breakpoint Successivo"
+msgid "Contextual Help"
+msgstr "Aiuto Contestuale"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Vai a Breakpoint Precedente"
+msgid "Toggle Bookmark"
+msgstr "Abilita/Disabilita Segnalibri"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Trova Precedente"
+msgid "Go to Next Bookmark"
+msgstr "Vai al Segnalibri Successivo"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Cerca nei File..."
+msgid "Go to Previous Bookmark"
+msgstr "Vai al Segnalibri Precedente"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Rimuovi tutti i Segnalibri"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6657,8 +6749,21 @@ msgid "Go to Line..."
msgstr "Vai a Linea..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Aiuto Contestuale"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Abilita Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Rimuovi Tutti i Breakpoints"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Vai a Breakpoint Successivo"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Vai a Breakpoint Precedente"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6686,7 +6791,7 @@ msgstr "Imposta Ossa in Posizione di Riposo"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Skeleton2D"
-msgstr "Skeleton2D"
+msgstr "Scheletro2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
@@ -6837,8 +6942,12 @@ msgid "Rear"
msgstr "Retro"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Allinea alla Vista"
+msgid "Align Transform with View"
+msgstr "Allinea Trasformazione con la Vista"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Allinea Rotazione con la Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6893,8 +7002,9 @@ msgid "Audio Listener"
msgstr "Listener Audio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Abilita Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Abilita filtraggio"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6950,45 +7060,25 @@ msgid "Snap Nodes To Floor"
msgstr "Sposta i Nodi sul Pavimento"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Modalità di Selezione (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid ""
"Drag: Rotate\n"
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
msgstr ""
"Trascina: Ruota\n"
-"Alt+Trascina: Muovi\n"
-"Alt+PDM: Selezione Lista Profondità"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Modalità Movimento (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Modalità Rotazione (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Modalità Scala (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordinate locali"
+"Alt+Trascina: Sposta\n"
+"Alt+RMB: Selezione Lista Profondità"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Modalità Spazio Locale (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Modalità Snap (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vista dal Basso"
@@ -7013,7 +7103,6 @@ msgid "Right View"
msgstr "Vista Destra"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Switch Perspective/Orthogonal View"
msgstr "Cambia tra Vista Prospettiva/Ortogonale"
@@ -7030,26 +7119,6 @@ msgid "Focus Selection"
msgstr "Centra a Selezione"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Allinea Selezione Con Vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Strumento Seleziona"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Strumento Sposta"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Strumento Ruota"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Strumento Scala"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Abilita/Disabilita Vista libera"
@@ -7059,7 +7128,6 @@ msgid "Transform"
msgstr "Trasforma"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Snap Object to Floor"
msgstr "Posa l'oggetto sul suolo"
@@ -7105,7 +7173,8 @@ msgstr "Visualizza Griglia"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Impostazioni"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7173,9 +7242,8 @@ msgid "Nameless gizmo"
msgstr "Gizmo senza nome"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Mesh2D"
-msgstr "Crea Mesh 2D"
+msgstr "Crea Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create Polygon2D"
@@ -7204,9 +7272,8 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "Geometria non valida, impossibile sostituirla con una mesh."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Mesh2D"
-msgstr "Converti in Mesh 2D"
+msgstr "Converti in Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -7402,10 +7469,6 @@ msgid "TextureRegion"
msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Impossibile salvare il tema su file:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Aggiungi Tutti gli Elementi"
@@ -7490,11 +7553,13 @@ msgid "Submenu"
msgstr "Sottomenù"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Elemento 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Elemento 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7599,14 +7664,6 @@ msgid "Transpose"
msgstr "Trasponi"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Specchia X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Specchia Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Disabilita Autotile"
@@ -7619,9 +7676,10 @@ msgid "Paint Tile"
msgstr "Disegna Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift + PDM: Traccia una linea\n"
"Shift + Ctrl + PDM: Colora il rettangolo"
@@ -7631,27 +7689,22 @@ msgid "Pick Tile"
msgstr "Preleva Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
msgstr "Ruota a sinistra"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
msgstr "Ruota a destra"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Flip Horizontally"
-msgstr "Ribalta in orizzontale"
+msgstr "Ribalta orizzontalmente"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Flip Vertically"
-msgstr "Ribalta in verticale"
+msgstr "Ribalta verticalmente"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Transform"
msgstr "Cancella la trasformazione"
@@ -7688,9 +7741,8 @@ msgid "Select the previous shape, subtile, or Tile."
msgstr "Seleziona la precedente forma, sottotile, o Tile."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "Modalità esecuzione:"
+msgstr "Modalità regione"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision Mode"
@@ -7927,6 +7979,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Solo GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Aggiungi Input +"
@@ -8003,6 +8059,11 @@ msgid "Duplicate Nodes"
msgstr "Duplica Nodi"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Incolla Nodi"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Elimina Nodi"
@@ -8023,6 +8084,11 @@ msgid "Light"
msgstr "Luce"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Crea Nodo Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Crea Nodo Shader"
@@ -8032,7 +8098,7 @@ msgstr "Colora funzione."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "Operatore colore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Grayscale function."
@@ -8059,365 +8125,427 @@ msgid "Darken operator."
msgstr "Operatore Darken."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Solo le Differenze"
+msgstr "Operatore \"differenza\"."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Operatore schivata."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "HardLight operator"
-msgstr ""
+msgstr "Operatore HardLight"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "Operatore \"schiarischi\"."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Operatore overlay."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Operatore schermo."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "Operatore SoftLight."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
-msgstr "Costante"
+msgstr "Costante di colore."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Cancella la trasformazione"
+msgstr "Uniforme di colore."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Ritorna il risultato booleano del confronto di %s tra due parametri."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Uguale (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Maggiore Di (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Maggiore o Uguale (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
msgstr ""
+"Ritorna un vettore associato se gli scalari di quello fornito sono uguali, "
+"maggiori o minori."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Ritorna il risultato booleano del confronto tra INF e un parametro scalare."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Ritorna il risultato booleano del confronto tra NaN e un parametro scalare."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Minore Di (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Minore o Uguale (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Non Uguale (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
+"Ritorna un vettore associato se il valore booleano fornito è vero o falso."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Ritorna il risultato booleano del confronto tra due parametri."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Ritorna il risultato booleano del confronto tra INF (o NaN) e un parametro "
+"scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Boolean constant."
-msgstr "Cambia Costante Vett."
+msgstr "Costante booleana."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "Uniforme booleana."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "Parametro di input '%s' per tutte le modalità shader."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Snap su Genitore"
+msgstr "Parametro di input."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "Parametro di input '%s' per le modalità shader vertex e fragment."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "Parametro di input '%s' per le modalità shader fragment e light."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "Parametro di input '%s' per la modalità shader fragment."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "Parametro di input '%s' per la modalità shader light."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "Parametro di input '%s' per la modalità shader vertex."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "Parametro di input '%s' per la modalità shader vertex e fragment."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Cambia Funzione Scalare"
+msgstr "Funzione scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "Cambia Operatore Scalare"
+msgstr "Operatore scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
-msgstr ""
+msgstr "La costante E (2.718282). Rappresenta la base del logaritmo naturale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "La costante Epsilon (0.00001). Il numero scalare più piccolo."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "La costante Phi (1.618034). Il rapporto aureo."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/4 constant (0.785398) or 45 degrees."
-msgstr ""
+msgstr "La costante Pi/4 (0.785398 radianti), o 45 gradi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/2 constant (1.570796) or 90 degrees."
-msgstr ""
+msgstr "La costante Pi/2 (1.570796 radianti), o 90 gradi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "La costante Pi (3.141593 radianti), o 180 gradi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "La costante Tau (6.283185 radianti), o 360 gradi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "La costante Sqrt2 (1.414214). La radice quadrata di 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "Ritorna il valore assoluto del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "Ritorna l'arco-coseno del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Ritorna l'inversa del coseno iperbolico del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "Ritorna l'arco-seno del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Ritorna l'inversa del seno iperbolico del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+msgstr "Ritorna l'arco-tangente del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "Ritorna l'arco-tangente dei parametri."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Ritorna l'inversa della tangente iperbolica del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
msgstr ""
+"Trova il numero intero più vicino che sia maggiore o uguale al parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
-msgstr ""
+msgstr "Vincola un valore tra due altri valori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "Ritorna il coseno del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Ritorna il coseno iperbolico del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "Converte una quantità di radianti in gradi."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr ""
+msgstr "Esponenziale in base e."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr ""
+msgstr "Esponenziale in base 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
msgstr ""
+"Trova il numero intero più vicino che sia minore o uguale al parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "Calcola la parte frazionaria dell'argomento."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
-msgstr ""
+msgstr "Ritorna l'inversa della radice quadrata del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "Logaritmo naturale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "Logaritmo in base 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "Ritorna il maggiore di due valori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "Ritorna il minore di due valori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
-msgstr ""
+msgstr "Interpolazione lineare tra due scalari."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "Ritorna il valore opposto del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - scalar"
-msgstr ""
+msgstr "1.0 - scalare"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the value of the first parameter raised to the power of the second."
msgstr ""
+"Ritorna il valore del primo parametro elevato alla potenza del secondo."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "Converte una quantità in gradi in radianti."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / scalar"
-msgstr ""
+msgstr "1.0 / scalare"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "Trova il numero intero più vicino al parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Trova il numero intero pari più vicino al parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "Blocca il valore tra 0.0 ed 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "Estrae il segno del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "Ritorna il seno del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Ritorna il seno iperbolico del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "Ritorna la radice quadrata del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è più piccolo di 'edge0', o 1.0 se 'x' è più largo di "
+"'edge1'. Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 "
+"usando i polinomi di Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è più piccolo di 'edge', altrimenti 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "Ritorna la tangente del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Ritorna la tangente iperbolica del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr ""
+msgid "Finds the truncated value of the parameter."
+msgstr "Trova il valore troncato del parametro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Aggiunge scalare allo scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "Divide lo scalare per scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "Moltiplica lo scalare per scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "Ritorna il resto dei due scalari."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "Sottrae scalare dallo scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar constant."
-msgstr "Cambia Costante Scalare"
+msgstr "Costante scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Cambia Uniforme Scalare"
+msgstr "Uniforme scalare."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "Esegue la ricerca di texture cubiche."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "Esegue la ricerca di texture."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "Cubic texture uniform."
-msgstr "Cambia Uniforme Texture"
+msgid "Cubic texture uniform lookup."
+msgstr "Controllo dell'uniforme della texture cubica."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "2D texture uniform."
-msgstr "Cambia Uniforme Texture"
+msgid "2D texture uniform lookup."
+msgstr "Controllo dell'uniforme della texture 2D."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Controllo dell'uniforme della texture cubica con triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Finestra di Transform..."
+msgstr "Funzione di trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8425,174 +8553,207 @@ 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 ""
+"Calcola il prodotto esterno di una coppia di vettori.\n"
+"\n"
+"OuterProduct considera il primo parametro 'c' come un vettore colonna "
+"(matrice con una colonna) ed il secondo, 'r', come un vettore riga (matrice "
+"con una riga) ed esegue una moltiplicazione algebrica lineare di matrici 'c "
+"* r', creando una matrice i cui numeri di righe sono il numero di componenti "
+"di 'c' e le cui colonne sono il numero di componenti in 'r'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
-msgstr ""
+msgstr "Compone la trasformazione da quattro vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Scompone la trasformazione in quattro vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr ""
+msgid "Calculates the determinant of a transform."
+msgstr "Calcola il determinante di una trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "Calcola l'inverso di una trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "Calcola la trasposizione di una trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Moltiplica la trasformazione per la trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Moltiplica il vettore per la trasformazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Transform Abortito."
+msgstr "Costante transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Transform Abortito."
+msgstr "Uniforme transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Assegnazione alla funzione."
+msgstr "Funzione vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector operator."
-msgstr "Cambia Operatore Vett."
+msgstr "Operatore vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "Compone il vettore da tre scalari."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "Scompone il vettore a tre scalari."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "Calcola il prodotto incrociato di due vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "Ritorna la distanza tra due punti."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "Calcola il prodotto scalare di due vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Ritorna un vettore che punta nella stessa direzione di quello di "
+"riferimento. La funzione ha tre vettori parametro: N, il vettore da "
+"orientare; I, quello incidente; ed Nref, il vettore di riferimento. Se il "
+"prodotto scalare di I ed Nref è minore di zero, il valore di ritorno è N. "
+"Altrimenti il ritorno sarà -N."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "Calcola la lunghezza di un vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "Interpolazione lineare tra due vettori."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolazione lineare tra due vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
-msgstr ""
+msgstr "Calcola il prodotto di normalizzazione del vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - vector"
-msgstr ""
+msgstr "1.0 - vettore"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / vector"
-msgstr ""
+msgstr "1.0 / vettore"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
+"Ritorna un vettore che punta nella direzione della riflessione ( a : vettore "
+"incidente, b : vettore normale )."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
-msgstr ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "Ritorna un vettore che punta nella direzione della refrazione."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è minore di 'edge0', ed 1.0 se 'x' è maggiore di 'edge1'. "
+"Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 usando i "
+"polinomiali di Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è minore di 'edge0', ed 1.0 se 'x' è maggiore di 'edge1'. "
+"Altrimenti, il valore di ritorno è interpolato tra 0.0 ed 1.0 usando i "
+"polinomiali di Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è minore di 'edge', altrimenti 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Ritorna 0.0 se 'x' è minore di 'edge', altrimenti 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+msgstr "Aggiunge un vettore al vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "Divide vettore per vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
-msgstr ""
+msgstr "Moltiplica vettore per vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two vectors."
-msgstr ""
+msgstr "Ritorna il resto dei due vettori."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts vector from vector."
-msgstr ""
+msgstr "Sottrae vettore dal vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector constant."
-msgstr "Cambia Costante Vett."
+msgstr "Costante vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector uniform."
-msgstr "Assegnazione all'uniforme."
+msgstr "Uniforme vettore."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8600,56 +8761,81 @@ 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 ""
+"Una espressione del Custom Godot Shader Language, con quantità "
+"personalizzabile di porte input ed output. Questa è una iniezione diretta di "
+"codice nella funzione vertex/fragment/light. Non usarla per scrivere le "
+"dichiarazione della funzione all'interno."
#: 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 ""
+"Ritorna il decadimento in base al prodotto scalare della normale della "
+"superfice e direzione della telecamera (passa gli input associati ad essa)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Solo modalità Fragment/Light) Fuzione derivata scalare."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(Solo modalità Fragment/Light) Fuzione derivata vettoriale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Solo modalità Fragment/Light) (Vettore) Derivata in 'x' usando la "
+"differenziazione locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
+"(Solo modalità Fragment/Light) (Scalare) Derivata in 'x' usando la "
+"differeziazione locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Soltanto modalità Fragment/Light) (Vettore) Derivata in 'y' usando la "
+"differenziazione locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
+"(Soltanto modalità Fragment/Light) (Scalare) Derivata in 'y' usando la "
+"differenziazione locale."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Soltanto modalità Fragment/Light) (Vettore) Somma delle derivate assolute "
+"in 'x' ed 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
+"(Soltanto modalità Fragment/Light) (Scalare) Somma delle derivate assolute "
+"in 'x' ed 'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8825,6 +9011,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Le export templates per questa piattaforma sono mancanti:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gestisci template d'esportazione"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Esporta Con Debug"
@@ -8984,6 +9174,15 @@ msgid "Unnamed Project"
msgstr "Progetto Senza Nome"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importa Progetto Esistente"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Impossibile aprire il progetto a '%s'."
@@ -8992,7 +9191,6 @@ msgid "Are you sure to open more than one project?"
msgstr "Sei sicuro di voler aprire più di un progetto?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"The following project settings file does not specify the version of Godot "
"through which it was created.\n"
@@ -9015,7 +9213,6 @@ msgstr ""
"precedenti del motore."
#: 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"
@@ -9027,8 +9224,7 @@ msgid ""
"engine anymore."
msgstr ""
"Il seguente file delle impostazioni del progetto è stato generato da una "
-"versione precedente del motore e deve essere convertito per questa "
-"versione:\n"
+"versione precedente del motore e deve essere convertito a questa versione:\n"
"\n"
"%s\n"
"\n"
@@ -9045,14 +9241,13 @@ msgstr ""
"del motore, le cui impostazioni non sono compatibili con questa versione."
#: 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 ""
"Non è possibile eseguire il progetto: nessuna scena principale definita.\n"
-"Si prega di modificare il progetto e impostare la scena principale in "
+"Si prega di modificare il progetto e di impostare la scena principale in "
"\"Impostazioni Progetto\" nella categoria \"Applicazione\"."
#: editor/project_manager.cpp
@@ -9064,36 +9259,33 @@ msgstr ""
"Per favore modifica il progetto per azionare l'importo iniziale."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to run %d projects at once?"
-msgstr "Sei sicuro di voler eseguire più di un progetto?"
+msgstr "Sei sicuro di voler eseguire %d progetti contemporaneamente?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
msgstr ""
-"Rimuovere progetto dalla lista? (I contenuti della cartella non saranno "
-"modificati)"
+"Rimuovere %d progetti dalla lista?\n"
+"I contenuti delle cartelle di progetto non saranno modificati."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
msgstr ""
-"Rimuovere progetto dalla lista? (I contenuti della cartella non saranno "
-"modificati)"
+"Rimuovere questo progetto dalla lista?\n"
+"I contenuti della cartella di progetto non saranno modificati."
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Rimuovere progetto dalla lista? (I contenuti della cartella non saranno "
-"modificati)"
+"Rimuovere %d progetti dalla lista?\n"
+"I contenuti delle cartelle di progetto non saranno modificati."
#: editor/project_manager.cpp
msgid ""
@@ -9105,19 +9297,22 @@ msgstr ""
"gestore dei progetti sarà avviato."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
-msgstr "Stai per esaminare %s cartelle per progetti Godot esistenti. Confermi?"
+msgstr ""
+"Sei sicuro di voler scannerizzare %s cartelle per progetti Godot già "
+"esistenti?\n"
+"Per questo potrebbe volerci un pò."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Gestore dei progetti"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Lista Progetti"
+#, fuzzy
+msgid "Projects"
+msgstr "Progetto"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9132,19 +9327,14 @@ msgid "New Project"
msgstr "Nuovo Progetto"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "Rimuovi punto"
+msgstr "Rimuovi mancante"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "Templates"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Esci"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Riavvia Ora"
@@ -9153,13 +9343,12 @@ msgid "Can't run project"
msgstr "Impossibile eseguire il progetto"
#: 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 ""
-"Al momento non hai alcun progetto.\n"
-"Ti piacerebbe esplorare gli esempi ufficiali nella Libreria delle Risorse?"
+"Al momento non hai nessun progetto.\n"
+"Ti piacerebbe esplorare gli esempi ufficiali nella libreria degli Asset?"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9186,9 +9375,8 @@ msgstr ""
"'\\' oppure '\"'"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "L'Azione '%s' esiste già!"
+msgstr "Un'azione col nome '%s' è già esistente."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -9196,7 +9384,7 @@ msgstr "Rinomina Evento di Azione Input"
#: editor/project_settings_editor.cpp
msgid "Change Action deadzone"
-msgstr ""
+msgstr "Cambia la zona morta d'azione"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
@@ -9388,11 +9576,11 @@ msgstr "Rimuovi Opzione di Remap Rimorse"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter"
-msgstr ""
+msgstr "Filtro lingue modificato"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter Mode"
-msgstr ""
+msgstr "Modalità filtro lingue modificata"
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
@@ -9407,9 +9595,8 @@ msgid "Override For..."
msgstr "Sovrascrivi Per..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-#, fuzzy
msgid "The editor must be restarted for changes to take effect."
-msgstr "Per rendere effettive le modifiche è necessario un riavvio dell'editor"
+msgstr "Per rendere effettive le modifiche, l'editor deve essere riavviato."
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -9425,7 +9612,7 @@ msgstr "Azione"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
-msgstr ""
+msgstr "Zona morta"
#: editor/project_settings_editor.cpp
msgid "Device:"
@@ -9465,15 +9652,13 @@ msgstr "Locale"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
-msgstr ""
+msgstr "Filtro lingue"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
msgstr "Mostra tutte le lingue"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
msgstr "Mostra solo le lingue selezionate"
@@ -9489,6 +9674,10 @@ msgstr "Lingue:"
msgid "AutoLoad"
msgstr "AutoLoad"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9541,14 +9730,6 @@ msgstr "Seleziona il Metodo Virtuale"
msgid "Select Method"
msgstr "Seleziona Metodo"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Impossibile eseguire lo strumento di PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "Impossibile ricaricare l'immagine convertita usando il tool PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Rinomina in Blocco"
@@ -9562,7 +9743,6 @@ msgid "Suffix"
msgstr "Suffisso"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
msgstr "Opzioni avanzate"
@@ -9825,9 +10005,8 @@ msgid "User Interface"
msgstr "Interfaccia Utente"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "Elimina Nodo"
+msgstr "Altro nodo"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -9846,6 +10025,11 @@ msgid "Remove Node(s)"
msgstr "Rimuovi nodo(i)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Cambia Nome porta Input"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9870,7 +10054,6 @@ msgid "Clear Inheritance"
msgstr "Liberare ereditarietà"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "Apri la documentazione"
@@ -9879,9 +10062,8 @@ msgid "Add Child Node"
msgstr "Aggiungi Nodo Figlio"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Comprimi Tutto"
+msgstr "Espandi/Collassa tutto"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -9892,6 +10074,10 @@ msgid "Extend Script"
msgstr "Estendi Script"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Reparent a Nuovo Nodo"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Rendi Scena Radice"
@@ -9912,9 +10098,8 @@ msgid "Delete (No Confirm)"
msgstr "Elimina (Senza Conferma)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Aggiungi/Crea un Nuovo Nodo"
+msgstr "Aggiungi/Crea un Nuovo Nodo."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -9949,52 +10134,51 @@ msgid "Toggle Visible"
msgstr "Attiva/Disattiva Visibilità"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "Seleziona Nodo"
+msgstr "Sblocca nodo"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Button Group"
-msgstr "Pulsante 7"
+msgstr "Gruppo pulsanti"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "Errore di Connessione"
+msgstr "(Collegamento da)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
msgstr "Avviso confugurazione nodo:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Il nodo ha connessione(i) e gruppo(i).\n"
"Fai clic per mostrare i segnali dock."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Il nodo ha connessioni.\n"
"Fai click per mostrare il dock segnali."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Il nodo e in un gruppo.\n"
"Fai click per mostrare il dock gruppi."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Apri Script"
+msgstr "Apri script:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -10021,6 +10205,8 @@ msgid ""
"AnimationPlayer is pinned.\n"
"Click to unpin."
msgstr ""
+"AnimationPlayer è bloccato.\n"
+"Fare clic per sbloccare."
#: editor/scene_tree_editor.cpp
msgid "Invalid node name, the following characters are not allowed:"
@@ -10043,39 +10229,32 @@ msgid "Select a Node"
msgstr "Scegli un Nodo"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "Percorso vuoto"
+msgstr "Il percorso è vuoto."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Il nome del file è vuoto"
+msgstr "Il nome del file è vuoto."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is not local."
-msgstr "Percorso non locale"
+msgstr "Percorso non locale."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid base path."
-msgstr "Percorso di base invalido"
+msgstr "Percorso di base non valido."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Una cartella con lo stesso nome esiste già"
+msgstr "Esiste già una directory con lo stesso nome."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Estensione Invalida"
+msgstr "Estensione non valida."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Wrong extension chosen."
-msgstr "Estensione scelta errata"
+msgstr "Selezionata estensione errata."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
@@ -10090,56 +10269,53 @@ msgid "Error loading script from %s"
msgstr "Errore caricamento script da %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sovrascrivi"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
-msgstr "Apri Script/Scegli Posizione"
+msgstr "Apri Script / Scegli Posizione"
#: editor/script_create_dialog.cpp
msgid "Open Script"
msgstr "Apri Script"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "File exists, it will be reused."
-msgstr "Il file esiste, sarà riutilizzato"
+msgstr "Il file è già esistente, quindi, verrà riutilizzato."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Nome classe invalido"
+msgstr "Nome classe non valido."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid inherited parent name or path."
-msgstr "Nome genitore ereditato o percorso invalido"
+msgstr "Nome o percorso genitore ereditato non valido."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script is valid."
-msgstr "Script valido"
+msgstr "Lo script è valido."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
-msgstr "Consentiti: a-z, A-Z, 0-9 e _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Consentiti: a-z, A-Z, 0-9, _ e ."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in script (into scene file)."
-msgstr "Script built-in (nel file scena)"
+msgstr "Script incorporato (nel file della scena)."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Crea nuovo file script"
+msgstr "Verrà creato un nuovo file di script."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Carica file script esistente"
+msgstr "Caricherà un file di script esistente."
#: editor/script_create_dialog.cpp
msgid "Language"
@@ -10271,7 +10447,7 @@ msgstr "Imposta da Tree"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "Esporta misure in formato CSV"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -10286,6 +10462,10 @@ msgid "Change Shortcut"
msgstr "Cambia Scorciatoia"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Impostazioni editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Scorciatoie"
@@ -10311,7 +10491,7 @@ msgstr "Cambia dimensione Telecamera"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Notifier AABB"
-msgstr ""
+msgstr "Cambia notificatore AABB"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Particles AABB"
@@ -10403,12 +10583,11 @@ msgstr "GDNativeLibrary"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
-msgstr ""
+msgstr "Singleton GDNative abilitato"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "Disabilita l'icona girevole di aggiornamento"
+msgstr "Singleton GDNative disabilitato"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -10496,9 +10675,8 @@ msgid "GridMap Fill Selection"
msgstr "GridMap Riempi Selezione"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
-msgstr "GridMap Elimina Selezione"
+msgstr "Sezione GridMap incolla"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -10586,7 +10764,7 @@ msgstr "Il nome della classe non può essere una parola chiave riservata"
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
-msgstr ""
+msgstr "Fine dell'analisi dell’eccezione interna dello stack"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Bake NavMesh"
@@ -10705,10 +10883,30 @@ msgid "Set Variable Type"
msgstr "Imposta Tipo di Variabile"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Non deve essere in conflitto con un nome di tipo built-in esistente."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Crea un nuovo rettangolo."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Valiabili:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Crea un nuovo rettangolo."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Crea un nuovo poligono."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Il nome non è un identificatore valido:"
@@ -10877,9 +11075,8 @@ msgid "Available Nodes:"
msgstr "Nodi Disponibili:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Select or create a function to edit its graph."
-msgstr "Seleziona o crea una funzione per modificare il grafico"
+msgstr "Seleziona o crea una funzione per modificarne il grafico."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
@@ -10898,10 +11095,6 @@ msgid "Cut Nodes"
msgstr "Taglia Nodi"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Incolla Nodi"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Modifica Membro"
@@ -11020,15 +11213,21 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"Le build personalizzate richiedono un percorso per un Android SDK valido "
+"nelle impostazioni dell'editor."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"Percorso per Android SDK per build personalizzata nelle impostazioni "
+"dell'editor non è valido."
#: platform/android/export/export.cpp
msgid ""
"Android project is not installed for compiling. Install from Editor menu."
msgstr ""
+"Android Project non è installato per la compilazione. Installalo dal menu "
+"Editor."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -11043,6 +11242,9 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Tentativo di costruire da un template build personalizzato, ma nesuna "
+"informazione sulla sua versione esiste. Perfavore, reinstallalo dal menu "
+"'Progetto'."
#: platform/android/export/export.cpp
msgid ""
@@ -11051,20 +11253,28 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"Versione build di Android non coerente:\n"
+" Template installato: %s\n"
+" Versione Godot: %s\n"
+"Perfavore, reinstalla il build template di Android dal menu 'Progetto'."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "Compilazione di un progetto 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 ""
+"Costruzione del progetto Android fallita, controlla l'output per vedere gli "
+"errori.\n"
+"In alternativa, visita docs.godotengine.org per la documentazione della "
+"build Android."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "Nessun apk build generato a: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -11198,13 +11408,12 @@ msgstr ""
"620x300)."
#: scene/2d/animated_sprite.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite to display frames."
msgstr ""
"Una risorsa SpriteFrames deve essere creata o impostata nella proprietà "
-"'Frames' affinché AnimatedSprite mostri i frame."
+"\"Frames\" in modo da far mostrare i frame dal nodo AnimatedSprite."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11269,13 +11478,12 @@ 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\" "
"property."
msgstr ""
-"Una texture con la forma della luce deve essere fornita nella proprietà "
-"'texture'."
+"Una texture con una forma della luce deve essere fornita alla proprietà "
+"\"Texture\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11285,11 +11493,9 @@ msgstr ""
"l'occlusore abbia effetto."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+"Il poligono per questo occluder è vuoto. Perfavore, disegna un poligono."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11380,63 +11586,54 @@ msgstr ""
"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."
+"TileMap con Use Parent abilitato richiede un genitore CollisionObject2D per "
+"dargli forma. Perfavore, usalo come figlio di Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, etc. per dargli una forma."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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."
+"VisibilityEnabler2D funziona meglio quando usato con il nodo principale "
+"della scena ereditata direttamente come genitore."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera deve avere un nodo ARVROrigin come suo genitore"
+msgstr "ARVRCamera deve avere un nodo ARVROrigin come genitore."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr "ARVRController deve avere un nodo ARVROrigin come suo genitore"
+msgstr "ARVRController deve avere un nodo ARVROrigin come genitore."
#: 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 ""
-"L'id del controller non deve essere 0 o questo controller non sarà legato ad "
-"un vero controller"
+"L'id del controller non deve essere 0 o non verrà associato ad un controller "
+"attuale."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ARVRAnchor deve avere un nodo ARVROrigin come suo genitore"
+msgstr "ARVRAnchor deve avere un nodo ARVROrigin come genitore."
#: 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 ""
-"L'id dell'ancora non deve essere 0 o questa ancora non sarà legata ad una "
-"vera ancora"
+"L'ID dell'ancora non deve essere 0 oppure non verrà associato ad un'ancora "
+"attuale."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin necessita di un nodo figlio ARVRCamera"
+msgstr "ARVROrigin richiede un nodo figlio di tipo ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
@@ -11448,11 +11645,11 @@ msgstr "(Tempo Rimanente: %d:%02d s)"
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Meshes: "
-msgstr ""
+msgstr "Stampa Meshes: "
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Lights:"
-msgstr ""
+msgstr "Stampando Luci:"
#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
msgid "Finishing Plot"
@@ -11460,7 +11657,7 @@ msgstr "Trama di Finitura"
#: scene/3d/baked_lightmap.cpp
msgid "Lighting Meshes: "
-msgstr ""
+msgstr "Illuminando Meshes: "
#: scene/3d/collision_object.cpp
msgid ""
@@ -11499,36 +11696,36 @@ 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."
msgstr ""
-"Perché CollisionShape funzioni deve essere fornita una forma. Si prega di "
-"creare una risorsa forma (shape)!"
+"Una forma deve essere fornita per il CollisionShape per farlo funzionare. "
+"Perfavore, creali una risorsa \"forma\"."
#: scene/3d/collision_shape.cpp
msgid ""
"Plane shapes don't work well and will be removed in future versions. Please "
"don't use them."
msgstr ""
+"Le forme planari non funzionano bene e verranno rimosse nelle versioni "
+"future. Per favore, non usarle."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
msgstr "Niente è visibile perché non è stata assegnata alcuna 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 ""
-"L'animazione delle particelle richiede l'utilizzo di uno SpatialMaterial con "
-"\"Billboard Particles\" abilitato."
+"Le animazioni per CPUParticles richiedono l'uso di un SpatialMaterial la cui "
+"modalità Billboard è impostata a \"Particle Billboard\"."
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
-msgstr ""
+msgstr "Tracciando Meshes"
#: scene/3d/gi_probe.cpp
msgid ""
@@ -11541,6 +11738,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"Un SpotLight con un angolo più ampio di 90 gradi non può proiettare ombre."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11572,26 +11770,24 @@ msgid ""
msgstr "Nulla é visibile perché le mesh non sono state assegnate ai draw pass."
#: scene/3d/particles.cpp
-#, fuzzy
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
-"L'animazione delle particelle richiede l'utilizzo di uno SpatialMaterial con "
-"\"Billboard Particles\" abilitato."
+"Le animazioni delle particelle richiedono l'uso di un SpatialMaterial la cui "
+"modalità Billboard è impostata a \"Particle Billboard\"."
#: scene/3d/path.cpp
msgid "PathFollow only works when set as a child of a Path node."
msgstr "PathFollow funziona solo se impostato come figlio di un nodo Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"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."
+"Il flag ROTATION_ORIENTED di un PathFollow richiede \"Up Vector\" di essere "
+"abilitato nella risorsa Curve del genitore Path."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11604,18 +11800,16 @@ msgstr ""
"Modifica invece la dimensione in sagome di collisione figlie."
#: scene/3d/remote_transform.cpp
-#, 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."
+"La proprietà \"Remove Path\" deve essere puntata su un Spatial o Spatial-"
+"derived valido per funzionare."
#: scene/3d/soft_body.cpp
-#, fuzzy
msgid "This body will be ignored until you set a mesh."
-msgstr "Questo corpo verrà ignorato finché non imposti una mesh"
+msgstr "Questo corpo verrà ignorato fino a quando non imposterai una mesh."
#: scene/3d/soft_body.cpp
msgid ""
@@ -11628,13 +11822,12 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
"Una risorsa SpriteFrames deve essere creata o impostata nella proprietà "
-"'Frames' affinché AnimatedSprite3D mostri i frame."
+"\"Frames\" in modo da far mostrare i frame dall'AnimatedSprite3D."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11649,6 +11842,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WordEnvironment richiede la sua proprietà \"Environment\" di contenere un "
+"Environment per avere un effetto visibile."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11686,9 +11881,8 @@ msgid "Nothing connected to input '%s' of node '%s'."
msgstr "Nulla collegato all'ingresso '%s' del nodo '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "Una radice AnimationNode per il grafico non è impostata."
+msgstr "Non è stato impostato alcun AnimationNode root per il grafico."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11702,9 +11896,8 @@ msgstr ""
"AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "La radice di AnimationPlayer non è un nodo valido."
+msgstr "Il nodo root dell'AnimationPlayer non è valido."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11716,12 +11909,11 @@ msgstr "Scegliere un colore dallo schermo."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "Imbardata"
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11732,22 +11924,22 @@ msgid "Add current color as a preset."
msgstr "Aggiungi il colore corrente come preset."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
-"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\"."
+"Il Contanier da se non serve alcuna funzione affinché uno script non "
+"configura il comportamento di posizione dei figli.\n"
+"Se non intendi aggiungere uno script, usa un semplice nodo 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 ""
+"Il tooltip non comparirà poiché il Mouse filter del control è impostato a "
+"\"Ignore\". Per risolvere questo, impostalo a \"Stop\" o \"Pass\"."
#: scene/gui/dialogs.cpp
msgid "Alert!"
@@ -11758,31 +11950,28 @@ 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, 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."
+"I popup saranno nascosti per default affinché non chiami la funzione "
+"popup(), oppure una delle funzioni popup*(). Farli diventare visibili per "
+"modificarli va bene, ma scompariranno all'esecuzione."
#: scene/gui/range.cpp
-#, fuzzy
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr "Se exp_edit è true min_value deve essere > 0."
+msgstr "Se \"Exp Edit\" è abilitato, \"Min Value\" deve essere maggiore di 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer é fatto per funzionare con un solo controllo figlio.\n"
-"Usa un container come figlio (VBox,HBox,etc), o un Control impostando la "
-"dimensione minima manualmente."
+"ScrollContainer è inteso per funzionare con un singolo figlio di controllo.\n"
+"Usa un container come figlio (VBox, HBox, ect.), oppure un nodo Control ed "
+"imposta la dimensione minima personalizzata manualmente."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11808,35 +11997,22 @@ msgstr ""
"Control, in modo che possa ottenere una dimensione. Altrimenti, renderlo un "
"RenderTarget e assegnare alla sua texture interna qualche nodo da mostrare."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Errore inizializzazione FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Formato font sconosciuto."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Errore caricamento font."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Dimensione font Invalida."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Ingresso"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Sorgente non valida per la shader."
+msgstr "Fonte non valida per l'anteprima."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Sorgente non valida per la shader."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Funzione di confronto non valida per quel tipo."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Assegnazione alla funzione."
@@ -11846,13 +12022,134 @@ msgid "Assignment to uniform."
msgstr "Assegnazione all'uniforme."
#: servers/visual/shader_language.cpp
-#, fuzzy
msgid "Varyings can only be assigned in vertex function."
-msgstr "Varyings può essere assegnato solo nella funzione del vertice."
+msgstr "Varyings può essere assegnato soltanto nella funzione del vertice."
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Le constanti non possono essere modificate."
+
+#~ msgid "No Matches"
+#~ msgstr "Nessuna corrispondenza"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Impossibile aprire file_type_cache.cch per scrittura, non salvo la cache "
+#~ "dei tipi di file!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Impossibile navigare a '%s' perché non è stato trovato nel file system!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Errore di caricamento immagine:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Nessun pixel con trasparenza >128 nell'immagine..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Il genitore non ha facce solde da popolare."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Impossibile mappare l'area."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Le facce non contengono area!"
+
+#~ msgid "No faces!"
+#~ msgstr "Nessuna faccia!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Errore: impossibile caricare il file."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Errore: impossibile caricare il file."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Abilita Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Modalità di Selezione (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Modalità Movimento (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Modalità Rotazione (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Modalità Scala (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordinate locali"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Modalità Snap (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Strumento Seleziona"
+
+#~ msgid "Tool Move"
+#~ msgstr "Strumento Sposta"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Strumento Ruota"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Strumento Scala"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Rimuovere tutti i progetti mancanti dalla lista?\n"
+#~ "(Il contenuto delle cartelle di progetto non saranno modificati)"
+
+#~ msgid "Project List"
+#~ msgstr "Lista Progetti"
+
+#~ msgid "Exit"
+#~ msgstr "Esci"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Impossibile eseguire lo strumento di PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "Impossibile ricaricare l'immagine convertita usando il tool PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Errore inizializzazione FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Formato font sconosciuto."
+
+#~ msgid "Error loading font."
+#~ msgstr "Errore caricamento font."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Dimensione font Invalida."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Cartella precedente"
+
+#~ msgid "Next Folder"
+#~ msgstr "Cartella successiva"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Apri screenshots automaticamente"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Apri in un editor di immagini esterno."
+
+#~ msgid "Reverse"
+#~ msgstr "Inverti"
+
+#~ msgid "Mirror X"
+#~ msgstr "Specchia X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Specchia Y"
#~ msgid "Generating solution..."
#~ msgstr "Generando la soluzione..."
@@ -12437,9 +12734,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Cancella selezione"
-#~ msgid "Could not find tile:"
-#~ msgstr "Impossibile trovare tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nome elemento o ID:"
@@ -12710,9 +13004,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "Info"
-#~ msgid "Re-Import..."
-#~ msgstr "Re-Importa..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Nessuna bit mask da importare!"
@@ -13106,9 +13397,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "Stereo"
-#~ msgid "Window"
-#~ msgstr "Finestra"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Scalando a %s%%."
@@ -13339,9 +13627,6 @@ msgstr ""
#~ msgid "Add Image Group"
#~ msgstr "Aggiungi Gruppo Immagini"
-#~ msgid "Delete Image Group"
-#~ msgstr "Elimina Gruppo Immagini"
-
#~ msgid "Project Export Settings"
#~ msgstr "Impostazioni Esportazione Progetto"
@@ -13426,9 +13711,6 @@ msgstr ""
#~ msgid "Export Project PCK"
#~ msgstr "Esporta Progetto PCK"
-#~ msgid "Export..."
-#~ msgstr "Esporta..."
-
#~ msgid "Project Export"
#~ msgstr "Esportazione Progetto"
@@ -13531,9 +13813,6 @@ msgstr ""
#~ msgid "Deploy File Server Clients"
#~ msgstr "Distribuisci i Client del File Server"
-#~ msgid "Group Editor"
-#~ msgstr "Editor Gruppo"
-
#~ msgid "%d frames"
#~ msgstr "%d frames"
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index d44fc089e8..3e529af0cb 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -2,7 +2,7 @@
# Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
-# akirakido <achts.y@gmail.com>, 2016-2017, 2018.
+# akirakido <achts.y@gmail.com>, 2016-2017, 2018, 2019.
# D_first <dntk.daisei@gmail.com>, 2017, 2018.
# Daisuke Saito <d.saito@coriginate.com>, 2017, 2018.
# h416 <shinichiro.hirama@gmail.com>, 2017.
@@ -15,7 +15,7 @@
# Tohru Ike (rokujyouhitoma) <rokujyouhitomajp@gmail.com>, 2017-2018.
# yu tang <0011solo@gmail.com>, 2018.
# zukkun <zukkun@gmail.com>, 2018.
-# sugusan <sugusan.development@gmail.com>, 2018.
+# sugusan <sugusan.development@gmail.com>, 2018, 2019.
# Nathan Lovato <nathan.lovato.art@gmail.com>, 2018.
# nyanode <akaruooyagi@yahoo.co.jp>, 2018.
# nitenook <admin@alterbaum.net>, 2018, 2019.
@@ -23,12 +23,15 @@
# Hidetsugu Takahashi <manzyun@gmail.com>, 2019.
# Wataru Onuki <watonu@magadou.com>, 2019.
# John Smith <weblater_jp@susa.eek.jp>, 2019.
+# Takuya Watanabe <watanabe@zblog.sakura.ne.jp>, 2019.
+# Sodium11 <Sodium11.for.gitserver@gmail.com>, 2019.
+# leela <53352@protonmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:49+0000\n"
-"Last-Translator: John Smith <weblater_jp@susa.eek.jp>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: leela <53352@protonmail.com>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
"Language: ja\n"
@@ -36,7 +39,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -78,7 +81,6 @@ msgid "On call to '%s':"
msgstr "'%s' ã¸ã®å‘¼ã³å‡ºã—:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "解放"
@@ -147,6 +149,31 @@ msgid "Anim Change Call"
msgstr "アニメーション呼出ã—ã®å¤‰æ›´"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "アニメーションキーフレームã®æ™‚間を変更"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "アニメーションã®ãƒˆãƒ©ãƒ³ã‚¸ã‚·ãƒ§ãƒ³ã‚’変更"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "アニメーションã®ãƒˆãƒ©ãƒ³ã‚¹ãƒ•ã‚©ãƒ¼ãƒ ã‚’変更"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "アニメーションキーフレームã®å€¤ã‚’変更"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "アニメーション呼出ã—ã®å¤‰æ›´"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "アニメーションã®é•·ã•ã‚’変更"
@@ -184,9 +211,8 @@ msgid "Animation length (frames)"
msgstr "アニメーションã®é•·ã• (フレーム)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
-msgstr "アニメーションã®é•·ã• (秒)"
+msgstr "アニメーションã®é•·ã•(秒)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
@@ -407,9 +433,8 @@ msgid "Add Transform Track Key"
msgstr "変æ›ãƒˆãƒ©ãƒƒã‚¯ã‚­ãƒ¼ã‚’追加"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "トラックを追加"
+msgstr "トラックキーを追加"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
@@ -477,9 +502,8 @@ msgid "Select All"
msgstr "ã™ã¹ã¦é¸æŠž"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "ノードをé¸æŠž"
+msgstr "é¸æŠžè§£é™¤"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -491,9 +515,8 @@ msgstr ""
"ノードã”ã¨ã«ãƒˆãƒ©ãƒƒã‚¯ã‚’グループ化ã™ã‚‹ã‹ã€ãƒ—レーンãªãƒªã‚¹ãƒˆã¨ã—ã¦è¡¨ç¤ºã—ã¾ã™ã€‚"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "スナップ"
+msgstr "スナップ:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -602,7 +625,7 @@ msgstr "ã™ã¹ã¦ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’クリーンアップ"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "アニメーションをクリーンアップ(「元ã«æˆ»ã™ã€ä¸å¯!)"
+msgstr "アニメーションをクリーンアップ (å…ƒã«æˆ»ã›ã¾ã›ã‚“!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
@@ -626,9 +649,8 @@ msgid "Copy"
msgstr "コピー"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "オーディオクリップ:"
+msgstr "オーディオトラッククリップã®è¿½åŠ "
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -659,16 +681,18 @@ msgid "Line Number:"
msgstr "行番å·:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d 箇所を置æ›ã—ã¾ã—ãŸã€‚"
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "一致ãªã—"
+#, fuzzy
+msgid "%d match."
+msgstr "ï¼…d件ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d 箇所を置æ›ã—ã¾ã—ãŸã€‚"
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "ï¼…d件ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -720,23 +744,20 @@ 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
msgid "Connect to Script:"
@@ -747,9 +768,8 @@ msgid "From Signal:"
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
@@ -777,9 +797,8 @@ msgid "Extra Call Arguments:"
msgstr "追加ã®å‘¼å‡ºã—引数:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "アニメーションã®ã‚ªãƒ—ション"
+msgstr "高度ãªè¨­å®š"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -799,9 +818,8 @@ msgid "Disconnects the signal after its first emission."
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
@@ -822,7 +840,6 @@ msgid "Connect"
msgstr "接続"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "シグナル:"
@@ -848,14 +865,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?"
@@ -902,8 +917,7 @@ msgstr "ãŠæ°—ã«å…¥ã‚Š:"
msgid "Recent:"
msgstr "最近:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -931,22 +945,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
@@ -993,9 +1005,8 @@ msgid "Owners Of:"
msgstr "次ã®ã‚ªãƒ¼ãƒŠãƒ¼:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "é¸æŠžã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’プロジェクトã‹ã‚‰é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿï¼ˆã€Œå…ƒã«æˆ»ã™ã€ä¸å¯ï¼‰"
+msgstr "é¸æŠžã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’プロジェクトã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1004,9 +1015,9 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
"除去ã—よã†ã¨ã—ã¦ã„るファイルã¯ä»–ã®ãƒªã‚½ãƒ¼ã‚¹ã®å‹•ä½œã«å¿…è¦ã§ã™ã€‚\n"
-"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿï¼ˆã€Œå…ƒã«æˆ»ã™ã€ä¸å¯ï¼‰"
+"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ (å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "除去ä¸å¯:"
@@ -1036,14 +1047,13 @@ msgstr "読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ï¼"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’完全ã«å‰Šé™¤ã—ã¾ã™ã‹?(「元ã«æˆ»ã™ã€ä¸å¯!)"
+msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’完全ã«å‰Šé™¤ã—ã¾ã™ã‹?(元ã«æˆ»ã›ã¾ã›ã‚“!)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Show Dependencies"
-msgstr "ä¾å­˜é–¢ä¿‚"
+msgstr "ä¾å­˜é–¢ä¿‚を表示"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "孤立リソース エクスプローラー"
@@ -1085,7 +1095,7 @@ msgstr "プロジェクト創始者"
#: editor/editor_about.cpp
msgid "Lead Developer"
-msgstr "開発主任"
+msgstr "開発リーダー"
#: editor/editor_about.cpp
msgid "Project Manager "
@@ -1132,23 +1142,26 @@ msgid "License"
msgstr "ライセンス"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
-msgstr "サードパーティ ライセンス"
+#, fuzzy
+msgid "Third-party Licenses"
+msgstr "サードパーティーライセンス"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
-"Godot Engineã¯ã€MITライセンスã¨äº’æ›æ€§ã®ã‚ã‚‹ã€å¤šæ•°ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティ製ã®ãƒ•ãƒªãƒ¼ãŠ"
-"よã³ã‚ªãƒ¼ãƒ—ンソースライブラリã«ä¾å­˜ã—ã¦ã„ã¾ã™ã€‚ 以下ã¯ã€ã‚µãƒ¼ãƒ‰ãƒ‘ーティ製コン"
-"ãƒãƒ¼ãƒãƒ³ãƒˆã®å„著作権ãŠã‚ˆã³ãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ¡é …ã®ç·è¦§ã§ã™ã€‚"
+"Godot Engineã¯ã€MITライセンスã®æ¡é …ã¨äº’æ›æ€§ã®ã‚ã‚‹ã€å¤šæ•°ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティã®ãƒ•"
+"リーãŠã‚ˆã³ã‚ªãƒ¼ãƒ—ンソースライブラリを利用ã—ã¦ã„ã¾ã™ã€‚ 以下ã¯ã€ãã®ã‚ˆã†ãªã™ã¹ã¦"
+"ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティコンãƒãƒ¼ãƒãƒ³ãƒˆã®ãã‚Œãžã‚Œã®è‘—作権表示ã¨ãƒ©ã‚¤ã‚»ãƒ³ã‚¹æ¡é …を網羅ã—"
+"ãŸãƒªã‚¹ãƒˆã§ã™ã€‚"
#: editor/editor_about.cpp
msgid "All Components"
-msgstr "全コンãƒãƒ¼ãƒãƒ³ãƒˆ"
+msgstr "å…¨ã¦ã®ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆ"
#: editor/editor_about.cpp
msgid "Components"
@@ -1159,7 +1172,8 @@ msgid "Licenses"
msgstr "ライセンス"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "パッケージファイルを開ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚zip å½¢å¼ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
#: editor/editor_asset_installer.cpp
@@ -1176,7 +1190,6 @@ msgid "Success!"
msgstr "æˆåŠŸï¼"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "インストール"
@@ -1360,19 +1373,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 built-in type name."
-msgstr "無効ãªåå‰ã§ã™ã€‚既存ã®çµ„è¾¼ã¿åž‹åã¨é‡è¤‡ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。"
+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."
@@ -1407,9 +1417,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."
@@ -1462,9 +1471,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"
@@ -1550,45 +1558,39 @@ msgstr "テンプレートファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"32ビットã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã§ã¯ã€çµ„ã¿è¾¼ã¿PCKã¯4GiBを超ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
#: 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
msgid "Asset Library"
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 and Import Docks"
-msgstr "ファイルシステム"
+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 '.'"
@@ -1596,80 +1598,68 @@ 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 "(エディタ無効ã€ãƒ—ロパティ無効)"
#: 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 "ファイル '%s' ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆãŒç„¡åŠ¹ã§ã™ã€‚インãƒãƒ¼ãƒˆãŒä¸­æ­¢ã•ã‚Œã¾ã—ãŸã€‚"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
-"プロファイル '%s' ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚インãƒãƒ¼ãƒˆå‰ã«æœ€åˆã«ãƒªãƒ¢ãƒ¼ãƒˆã§å®Ÿè¡Œã™ã‚‹"
-"ã¨ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã¯ä¸­æ­¢ã•ã‚Œã¾ã™ã€‚"
+"プロファイル '%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 "未設定"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³:"
+msgstr "ç¾åœ¨ã®ãƒ—ロファイル:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "ç¾åœ¨:"
+msgstr "最新ã«ã™ã‚‹"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1677,49 +1667,41 @@ msgid "New"
msgstr "æ–°è¦"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "インãƒãƒ¼ãƒˆ"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "エクスãƒãƒ¼ãƒˆ"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "利用å¯èƒ½ãªãƒŽãƒ¼ãƒ‰:"
+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"
@@ -1750,7 +1732,7 @@ msgstr "ファイルマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã§è¡¨ç¤º"
msgid "New Folder..."
msgstr "æ–°è¦ãƒ•ã‚©ãƒ«ãƒ€..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "å†èª­è¾¼"
@@ -1801,7 +1783,7 @@ msgstr "進む"
msgid "Go Up"
msgstr "上ã¸"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "éš ã—ファイルã®åˆ‡ã‚Šæ›¿ãˆ"
@@ -1826,29 +1808,28 @@ msgid "Move Favorite Down"
msgstr "ãŠæ°—ã«å…¥ã‚Šã‚’下ã¸"
#: editor/editor_file_dialog.cpp
-#, fuzzy
-msgid "Previous Folder"
-msgstr "å‰ã®åºŠé¢"
+msgid "Go to previous folder."
+msgstr "å‰ã®ãƒ•ã‚©ãƒ«ãƒ€ã¸ç§»å‹•ã™ã‚‹ã€‚"
#: editor/editor_file_dialog.cpp
-#, fuzzy
-msgid "Next Folder"
-msgstr "次ã®åºŠé¢"
+msgid "Go to next folder."
+msgstr "次ã®ãƒ•ã‚©ãƒ«ãƒ€ã¸ç§»å‹•ã™ã‚‹ã€‚"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
-msgstr "親フォルダã¸"
+msgstr "親フォルダã¸ç§»å‹•ã™ã‚‹ã€‚"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "ファイル更新。"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "(Un)favorite current folder."
-msgstr "フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’ãŠæ°—ã«å…¥ã‚Šã«ã™ã‚‹/ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å¤–ã™ã€‚"
-#: editor/editor_file_dialog.cpp
-#, fuzzy
-msgid "Toggle visibility of hidden files."
-msgstr "éš ã—ファイルã®åˆ‡ã‚Šæ›¿ãˆ"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "éš ã—ファイルã®è¡¨ç¤º/éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -2072,9 +2053,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
@@ -2090,6 +2070,11 @@ msgstr "クリア"
msgid "Clear Output"
msgstr "出力をクリア"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "ウィンドウ"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "プロジェクトã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãŒã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ %d ã§å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -2232,7 +2217,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."
@@ -2249,7 +2233,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"
@@ -2257,12 +2240,11 @@ 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 "
@@ -2290,12 +2272,11 @@ msgstr "シーンを開ã"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr "基本シーンを開ã"
+msgstr "ベースã®ã‚·ãƒ¼ãƒ³ã‚’é–‹ã"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "シーンã®ã‚¯ã‚¤ãƒƒã‚¯ã‚ªãƒ¼ãƒ—ン..."
+msgstr "クイックオープン..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2314,14 +2295,12 @@ msgid "Save changes to '%s' before closing?"
msgstr "é–‰ã˜ã‚‹å‰ã«ã€'%s' ã¸ã®å¤‰æ›´ã‚’ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Saved %s modified resource(s)."
-msgstr "リソースã®èª­è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+msgstr "ï¼…s個ã®å¤‰æ›´ã•ã‚ŒãŸãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å­˜ã—ã¾ã—ãŸã€‚"
#: editor/editor_node.cpp
-#, fuzzy
msgid "A root node is required to save the scene."
-msgstr "大ããªãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ãŸã‚ã«ä¸€ã¤ãƒ•ã‚¡ã‚¤ãƒ«ãŒå¿…è¦ã§ã™"
+msgstr "シーンをä¿å­˜ã™ã‚‹ã«ã¯ãƒ«ãƒ¼ãƒˆãƒŽãƒ¼ãƒ‰ãŒå¿…è¦ã§ã™ã€‚"
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -2373,7 +2352,7 @@ msgstr "å…ƒã«æˆ»ã™"
#: editor/editor_node.cpp
msgid "This action cannot be undone. Revert anyway?"
-msgstr "ã“ã®æ“作ã¯ã€Œå…ƒã«æˆ»ã™ã€ã¯ã§ãã¾ã›ã‚“。ãã‚Œã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹ï¼Ÿ"
+msgstr "ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。ãã‚Œã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹?"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2417,6 +2396,15 @@ msgid "Pick a Main Scene"
msgstr "メインシーンをé¸ã¶"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "シーンを閉ã˜ã‚‹"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "シーンを閉ã˜ã‚‹"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "アドオンプラグインを有効ã«ã§ãã¾ã›ã‚“: '%s' 設定ã®è§£æžã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -2530,6 +2518,11 @@ msgstr "シーンをプレイ"
msgid "Close Tab"
msgstr "タブを閉ã˜ã‚‹"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "タブを閉ã˜ã‚‹"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "ä»–ã®ã‚¿ãƒ–ã‚’é–‰ã˜ã‚‹"
@@ -2539,9 +2532,8 @@ msgid "Close Tabs to the Right"
msgstr "タブをå³ã«é–‰ã˜ã‚‹"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "ã™ã¹ã¦é–‰ã˜ã‚‹"
+msgstr "ã™ã¹ã¦ã®ã‚¿ãƒ–ã‚’é–‰ã˜ã‚‹"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2584,6 +2576,10 @@ msgid "Go to previously opened scene."
msgstr "以å‰ã«é–‹ã„ãŸã‚·ãƒ¼ãƒ³ã«ç§»å‹•ã™ã‚‹ã€‚"
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "テキストをコピー"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "次ã®ã‚¿ãƒ–"
@@ -2611,6 +2607,10 @@ msgstr "æ–°ã—ã„継承ã—ãŸã‚·ãƒ¼ãƒ³..."
msgid "Open Scene..."
msgstr "シーンを開ã..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "最近開ã„ãŸã‚·ãƒ¼ãƒ³ã‚’é–‹ã"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "シーンをä¿å­˜"
@@ -2620,14 +2620,6 @@ msgid "Save All Scenes"
msgstr "å…¨ã¦ã®ã‚·ãƒ¼ãƒ³ã‚’ä¿å­˜"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "シーンを閉ã˜ã‚‹"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "最近開ã„ãŸã‚·ãƒ¼ãƒ³ã‚’é–‹ã"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "変æ›..."
@@ -2657,25 +2649,37 @@ msgstr "シーンを元ã«æˆ»ã™"
msgid "Miscellaneous project or scene-wide tools."
msgstr "ãã®ä»–ã®ãƒ—ロジェクトã¾ãŸã¯ã‚·ãƒ¼ãƒ³å…¨ä½“ã®ãƒ„ール。"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "プロジェクト"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "プロジェクト設定"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ツール"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "エクスãƒãƒ¼ãƒˆ"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Androidビルドテンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "プロジェクトã®ãƒ‡ãƒ¼ã‚¿ãƒ•ã‚©ãƒ«ãƒ€ã‚’é–‹ã"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ツール"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Androidビルドテンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "孤立リソース エクスプローラー"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2772,12 +2776,13 @@ msgstr ""
"るよã†ã«ãªã‚Šã¾ã™ã€‚\n"
"リモート実行ã®å ´åˆã€ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ã‚’使ã†ã¨ã‚ˆã‚ŠåŠ¹æžœçš„ã§ã™ã€‚"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "エディタ"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "エディタ設定"
#: editor/editor_node.cpp
@@ -2785,32 +2790,20 @@ msgid "Editor Layout"
msgstr "エディタレイアウト"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "シーンをルートã«ã™ã‚‹"
+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 "次ã®ã‚¨ãƒ‡ã‚£ã‚¿ã‚’é–‹ã"
+msgstr "スクリーンショットã¯Editor Data / Settingsフォルダã«ä¿å­˜ã•ã‚Œã¦ã„ã¾ã™ã€‚"
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
msgstr "フルスクリーン切り替ãˆ"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Toggle System Console"
-msgstr "分割モード切り替ãˆ"
+msgstr "システムコンソールã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2826,14 +2819,15 @@ msgstr "エディタ設定ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é–‹ã"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
-msgstr "エクスãƒãƒ¼ãƒˆãƒ†ãƒ³ãƒ—レートã®ç®¡ç†"
+msgid "Manage Editor Features..."
+msgstr "エディタ機能ã®ç®¡ç†"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "エクスãƒãƒ¼ãƒˆãƒ†ãƒ³ãƒ—レートã®ç®¡ç†"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "ヘルプ"
@@ -2841,12 +2835,13 @@ msgstr "ヘルプ"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "検索"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "オンラインドキュメント"
@@ -2920,19 +2915,16 @@ msgid "Spins when the editor window redraws."
msgstr "エディタ ウィンドウã®å†æ画時ã«ã‚¹ãƒ”ンã—ã¾ã™ã€‚"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "継続的"
+msgstr "継続的ã«æ›´æ–°"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
msgstr "変更時ã«æ›´æ–°"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "アップデートスピナーを無効化"
+msgstr "アップデートスピナーをéžè¡¨ç¤º"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -2965,9 +2957,8 @@ msgstr ""
"ãã ã•ã„。"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "エクスãƒãƒ¼ãƒˆãƒ†ãƒ³ãƒ—レートã®ç®¡ç†"
+msgstr "テンプレートã®ç®¡ç†"
#: editor/editor_node.cpp
msgid ""
@@ -3128,6 +3119,10 @@ msgstr "時間"
msgid "Calls"
msgstr "呼出ã—"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "テキストを編集:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "オン"
@@ -3299,7 +3294,8 @@ msgid "Import From Node:"
msgstr "ノードã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "å†ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
#: editor/export_template_manager.cpp
@@ -3308,7 +3304,7 @@ msgstr "アンインストール"
#: editor/export_template_manager.cpp
msgid "(Installed)"
-msgstr "(インストール済)"
+msgstr "(インストール済)"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3316,12 +3312,16 @@ msgid "Download"
msgstr "ダウンロード"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(見ã¤ã‹ã‚Šã¾ã›ã‚“)"
#: editor/export_template_manager.cpp
msgid "(Current)"
-msgstr "(ç¾åœ¨ã®ï¼‰"
+msgstr "(ç¾åœ¨)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
@@ -3379,12 +3379,10 @@ msgid "No response."
msgstr "応答ãŒã‚ã‚Šã¾ã›ã‚“。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "リクエストã¯å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "リダイレクトã®ãƒ«ãƒ¼ãƒ—。"
@@ -3398,15 +3396,22 @@ msgid "Download Complete."
msgstr "ダウンロードãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "ファイルã«ãƒ†ãƒ¼ãƒžã‚’ä¿å­˜ã§ãã¾ã›ã‚“:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"テンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ å•é¡Œã®ãƒ†ãƒ³ãƒ—レートã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–㯠"
"'%s' ã«ã‚ã‚Šã¾ã™ã€‚"
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "URL リクエストã®ã‚¨ãƒ©ãƒ¼: "
#: editor/export_template_manager.cpp
@@ -3456,9 +3461,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:"
@@ -3477,7 +3481,6 @@ msgid "Remove Template"
msgstr "テンプレートを除去"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select Template File"
msgstr "テンプレートファイルをé¸æŠž"
@@ -3493,23 +3496,11 @@ msgstr "テンプレートをダウンロード"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "リストã‹ã‚‰ãƒŸãƒ©ãƒ¼ã‚’é¸æŠž: (Shift+クリック: ブラウザã§é–‹ã)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"書ã出ã—時ã«file_type_cache.cchを確èªã§ãã¾ã›ã‚“。ファイルタイプã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’"
-"ä¿å­˜ã§ãã¾ã›ã‚“!\n"
-"ファイルタイプキャッシュをä¿å­˜ã›ãšã« file_type_cache.cch を書込ã¿ç”¨ã«é–‹ãã“ã¨"
-"ã¯ã§ãã¾ã›ã‚“ï¼"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "ãŠæ°—ã«å…¥ã‚Š"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "ファイルシステム上㧠'%s' を見ã¤ã‘られãªã„ãŸã‚移動ã§ãã¾ã›ã‚“ï¼"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"ステータス: ファイルã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚ファイルを修正ã—ã¦æ‰‹å‹•ã§å†ã‚¤"
@@ -3540,12 +3531,7 @@ msgid "No name provided."
msgstr "åå‰ãŒä»˜ã„ã¦ã„ã¾ã›ã‚“。"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Provided name contains invalid characters."
-msgstr "åå‰ã«ä½¿ç”¨ã§ããªã„文字ãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
-
-#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
msgstr "åå‰ã«ä½¿ç”¨ã§ããªã„文字ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"
#: editor/filesystem_dock.cpp
@@ -3553,6 +3539,10 @@ msgid "A file or folder with this name already exists."
msgstr "åŒåã®ãƒ•ã‚¡ã‚¤ãƒ«ã¾ãŸã¯ãƒ•ã‚©ãƒ«ãƒ€ãŒã‚ã‚Šã¾ã™ã€‚"
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "åå‰ã«ä½¿ç”¨ã§ããªã„文字ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "ファイルåを変更:"
@@ -3569,12 +3559,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 "シーンを開ã"
@@ -3583,12 +3571,10 @@ msgid "Instance"
msgstr "インスタンス"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
msgstr "ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ "
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Remove from Favorites"
msgstr "ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å‰Šé™¤"
@@ -3612,6 +3598,11 @@ msgstr "複製..."
msgid "Move To..."
msgstr "移動..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "æ–°è¦ã‚·ãƒ¼ãƒ³"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "æ–°è¦ã‚¹ã‚¯ãƒªãƒ—ト..."
@@ -3638,14 +3629,12 @@ 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"
@@ -3680,6 +3669,11 @@ msgstr "ã“ã®ãƒ‘スã«ã¯ã€æ—¢ã«åŒåã®ãƒ•ã‚¡ã‚¤ãƒ«ã‹ãƒ•ã‚©ãƒ«ãƒ€ãŒã‚ã‚Š
msgid "Overwrite"
msgstr "上書ã"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "シーンã‹ã‚‰ç”Ÿæˆ"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "スクリプト作æˆ"
@@ -3730,7 +3724,7 @@ msgstr "ç½®æ›: "
#: editor/find_in_files.cpp
msgid "Replace all (no undo)"
-msgstr "ã™ã¹ã¦ç½®æ›ï¼ˆã€Œå…ƒã«æˆ»ã™ã€ä¸å¯ï¼‰"
+msgstr "ã™ã¹ã¦ç½®æ› (å…ƒã«æˆ»ã›ã¾ã›ã‚“)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -3741,6 +3735,14 @@ msgid "Search complete"
msgstr "検索完了"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "グループã«è¿½åŠ "
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "グループã‹ã‚‰é™¤åŽ»"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "グループåãŒæ—¢ã«ã‚ã‚Šã¾ã™ã€‚"
@@ -3748,12 +3750,23 @@ msgstr "グループåãŒæ—¢ã«ã‚ã‚Šã¾ã™ã€‚"
msgid "Invalid group name."
msgstr "無効ãªã‚°ãƒ«ãƒ¼ãƒ—åã§ã™ã€‚"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "グループã®ç®¡ç†"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "レイアウトã®å‰Šé™¤"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "グループ"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "グループã«ãªã„ノード"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3766,12 +3779,13 @@ msgid "Nodes in Group"
msgstr "グループ内ノード"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "グループã«è¿½åŠ "
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "グループã‹ã‚‰é™¤åŽ»"
+#, fuzzy
+msgid "Group Editor"
+msgstr "スクリプトエディタ"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3879,9 +3893,8 @@ msgid "Reimport"
msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save scenes, re-import and restart"
-msgstr "シーンをä¿å­˜ã—ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•"
+msgstr "シーンをä¿å­˜ã—ã¦ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•ã—ã¦ãã ã•ã„"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -3980,7 +3993,8 @@ msgid "MultiNode Set"
msgstr "マルãƒãƒŽãƒ¼ãƒ‰ セット"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "シグナルã¨ã‚°ãƒ«ãƒ¼ãƒ—を編集ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã‚’é¸æŠžã€‚"
#: editor/plugin_config_dialog.cpp
@@ -4070,19 +4084,16 @@ msgstr "読ã¿è¾¼ã‚€.."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Move Node Point"
-msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’移動"
+msgstr "ノードãƒã‚¤ãƒ³ãƒˆã‚’移動"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Limits"
-msgstr "ブレンド時間ã®å¤‰æ›´"
+msgstr "BlendSpace1Dã®åˆ¶é™ã‚’変更ã™ã‚‹"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace1D Labels"
-msgstr "ブレンド時間ã®å¤‰æ›´"
+msgstr "BlendSpace1Dã®ãƒ©ãƒ™ãƒ«ã‚’変更ã™ã‚‹"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4092,20 +4103,17 @@ msgstr "ã“ã®ã‚¿ã‚¤ãƒ—ã®ãƒŽãƒ¼ãƒ‰ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。ルートノード
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Node Point"
-msgstr "ノードを追加"
+msgstr "ノードãƒã‚¤ãƒ³ãƒˆã‚’追加"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Animation Point"
-msgstr "アニメーションを追加"
+msgstr "アニメーションãƒã‚¤ãƒ³ãƒˆã‚’追加"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace1D Point"
-msgstr "パスã®ãƒã‚¤ãƒ³ãƒˆã‚’除去"
+msgstr "BlendSpace1Dã®ãƒã‚¤ãƒ³ãƒˆã‚’削除"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
@@ -4151,34 +4159,28 @@ 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
-#, fuzzy
msgid "Add Triangle"
-msgstr "変数を追加"
+msgstr "三角形を追加"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Limits"
-msgstr "ブレンド時間ã®å¤‰æ›´"
+msgstr "BlendSpace2Dã®åˆ¶é™ã‚’変更ã™ã‚‹"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Labels"
-msgstr "ブレンド時間ã®å¤‰æ›´"
+msgstr "BlendSpace2Dã®ãƒ©ãƒ™ãƒ«ã‚’変更ã™ã‚‹"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Point"
-msgstr "パスã®ãƒã‚¤ãƒ³ãƒˆã‚’除去"
+msgstr "BlendSpace2Dã®ãƒã‚¤ãƒ³ãƒˆã‚’削除ã™ã‚‹"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Triangle"
-msgstr "無効ãªã‚­ãƒ¼ã‚’削除"
+msgstr "BlendSpace2D三角形を削除ã™ã‚‹"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "BlendSpace2D does not belong to an AnimationTree node."
@@ -4211,9 +4213,8 @@ msgid "Blend:"
msgstr "ブレンド:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Parameter Changed"
-msgstr "マテリアルã®å¤‰æ›´"
+msgstr "パラメータãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4225,9 +4226,8 @@ msgid "Output node can't be added to the blend tree."
msgstr "出力ノードをブレンドツリーã«è¿½åŠ ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Add Node to BlendTree"
-msgstr "シーンã‹ã‚‰ã®ãƒŽãƒ¼ãƒ‰"
+msgstr "BlendTreeã«ãƒŽãƒ¼ãƒ‰ã‚’追加"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4252,13 +4252,11 @@ msgid "Nodes Disconnected"
msgstr "切断ã•ã‚Œã¾ã—ãŸ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "æ–°è¦ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³"
+msgstr "アニメーションを設定"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
msgstr "ノードを削除"
@@ -4268,14 +4266,12 @@ msgid "Delete Node(s)"
msgstr "ノードを削除"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Filter On/Off"
-msgstr "ã“ã®ãƒˆãƒ©ãƒƒã‚¯ã® オン/オフ を切り替ãˆã€‚"
+msgstr "フィルター㮠オン/オフ を切り替ãˆ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Change Filter"
-msgstr "ブレンドã™ã‚‹æ™‚間を変更"
+msgstr "フィルターを変更"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4297,9 +4293,8 @@ msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "ノードå"
+msgstr "ノードã®åå‰ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4312,7 +4307,6 @@ msgid "Edit Filtered Tracks:"
msgstr "フィルタリング済トラックã®ç·¨é›†:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
msgstr "フィルタリングを有効化"
@@ -4448,9 +4442,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"
@@ -4525,14 +4518,12 @@ msgid "Cross-Animation Blend Times"
msgstr "アニメーション間ã®ãƒ–レンド時間"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "追加ã—ãŸã‚­ãƒ¼ã‚’移動"
+msgstr "ノードを移動"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "翻訳を追加"
+msgstr "トランジションを追加"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -4568,14 +4559,12 @@ msgid "No playback resource set at path: %s."
msgstr "パス( %s )ã«å†ç”Ÿãƒªã‚½ãƒ¼ã‚¹ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Removed"
-msgstr "å–り除ã„ãŸã®ã¯:"
+msgstr "ノードãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "トランジション ノード"
+msgstr "トランジションãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
@@ -4604,11 +4593,10 @@ msgid "Remove selected node or transition."
msgstr "é¸æŠžã—ãŸãƒŽãƒ¼ãƒ‰ã¾ãŸã¯ãƒˆãƒ©ãƒ³ã‚¸ã‚·ãƒ§ãƒ³ã‚’除去。"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
-"ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†ç”Ÿã‚’ã€ã‚¹ã‚¿ãƒ¼ãƒˆã€ãƒªã‚¹ã‚¿ãƒ¼ãƒˆã€ã‚¼ãƒ­ã«ã‚·ãƒ¼ã‚¯ã«åˆ‡ã‚Šæ›¿ãˆ"
-"る。"
+"ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†ç”Ÿã®é–‹å§‹ã€å†èµ·å‹•ã€ã¾ãŸã¯ã‚¼ãƒ­ã¸ã®ã‚·ãƒ¼ã‚¯ã‚’切り替ãˆã¾"
+"ã™ã€‚"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
@@ -4766,10 +4754,6 @@ msgid "View Files"
msgstr "ファイルを表示"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "ホストåを解決ã§ãã¾ã›ã‚“:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "接続エラー。å†è©¦è¡Œã—ã¦ãã ã•ã„。"
@@ -4782,14 +4766,47 @@ msgid "No response from host:"
msgstr "ホストã‹ã‚‰å¿œç­”ãŒã‚ã‚Šã¾ã›ã‚“:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "ホストåを解決ã§ãã¾ã›ã‚“:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "リクエスト失敗。リターンコード:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "リクエストã¯å¤±æ•—ã—ã¾ã—ãŸã€‚"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "ファイルã«ãƒ†ãƒ¼ãƒžã‚’ä¿å­˜ã§ãã¾ã›ã‚“:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "リクエスト失敗。リダイレクトéŽå¤š"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "リダイレクトã®ãƒ«ãƒ¼ãƒ—。"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "リクエスト失敗。リターンコード:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "時間"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
"ダウンロードãƒãƒƒã‚·ãƒ¥ãŒä¸æ­£ã§ã™ã€‚ファイルãŒæ”¹ã–ã‚“ ã•ã‚Œã¦ã„ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。"
@@ -4831,6 +4848,10 @@ msgid "Idle"
msgstr "å¾…æ©Ÿ"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "インストール..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "å†è©¦è¡Œ"
@@ -4859,13 +4880,17 @@ msgid "Last"
msgstr "最後"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "ã™ã¹ã¦"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "プラグイン"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4873,8 +4898,8 @@ msgid "Sort:"
msgstr "ソート:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "逆"
+msgid "Reverse sorting."
+msgstr "逆順ソート。"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4886,7 +4911,8 @@ msgid "Site:"
msgstr "サイト:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "サãƒãƒ¼ãƒˆ..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4898,6 +4924,11 @@ msgid "Testing"
msgstr "テスト中"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "読ã¿è¾¼ã‚€.."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "アセットã®zipファイル"
@@ -4955,31 +4986,31 @@ msgid "Rotation Step:"
msgstr "回転ã®ã‚¹ãƒ†ãƒƒãƒ—:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr "垂直ガイドを移動"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "垂直ガイドを作æˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "垂直ガイドを削除"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "水平ガイドを移動"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "水平ガイドを作æˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "水平ガイドを削除"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr "水平垂直ガイドを作æˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4999,9 +5030,8 @@ msgid "Resize CanvasItem"
msgstr "CanvasItemをリサイズ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem"
-msgstr "キャンãƒã‚¹ã‚¢ã‚¤ãƒ†ãƒ ã®ç·¨é›†"
+msgstr "キャンãƒã‚¹ã‚¢ã‚¤ãƒ†ãƒ ã®æ‹¡å¤§/縮å°"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move CanvasItem"
@@ -5040,27 +5070,23 @@ 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"
@@ -5068,13 +5094,16 @@ msgstr "ãƒãƒ¼ã‚ºã‚’貼り付ã‘"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "ボーンをクリアã™ã‚‹"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
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"
@@ -5097,6 +5126,7 @@ msgid "Zoom Reset"
msgstr "ズームをリセット"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰"
@@ -5109,26 +5139,27 @@ msgid "Alt+Drag: Move"
msgstr "Alt+ドラッグ: 移動"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
msgstr ""
-"vキーを押ã™ã¨ãƒ”ボットã®å¤‰æ›´ã€'Shift+v' ã§ãƒ”ボットをドラッグ(移動中ã§ã‚‚)"
+"ピボットを変更ã™ã‚‹ã«ã¯ 'v' ã€ãƒ”ボットをドラッグã™ã‚‹ã«ã¯ 'Shift+v' を押ã—ã¾ã™"
+"(移動中)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+RMB: Depth list selection"
-msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: デプス(深ã•ï¼‰ãƒªã‚¹ãƒˆã®é¸æŠž"
+msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
-msgstr "追加ã—ãŸã‚­ãƒ¼ã‚’移動"
+msgstr "移動モード"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "回転モード"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "スケールモード"
@@ -5154,6 +5185,7 @@ msgid "Toggle snapping."
msgstr "スナッピングを切り替ãˆã‚‹ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "スナップを使ã†"
@@ -5162,7 +5194,6 @@ msgid "Snapping Options"
msgstr "スナッピングオプション"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Grid"
msgstr "グリッドã«ã‚¹ãƒŠãƒƒãƒ—"
@@ -5171,11 +5202,6 @@ msgid "Use Rotation Snap"
msgstr "回転スナップを使ã†"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "スナップã®è¨­å®š..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "相対スナップ"
@@ -5184,37 +5210,35 @@ 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
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "スナップã®è¨­å®š..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "親ã«ã‚¹ãƒŠãƒƒãƒ—"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, 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 "ガイドã«ã‚¹ãƒŠãƒƒãƒ—"
@@ -5289,14 +5313,12 @@ msgid "Show Group And Lock Icons"
msgstr "グループアイコンã¨ãƒ­ãƒƒã‚¯ã‚¢ã‚¤ã‚³ãƒ³ã‚’表示"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Selection"
-msgstr "é¸æŠžå¯¾è±¡ã‚’中央ã«"
+msgstr "センターé¸æŠž"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Frame Selection"
-msgstr "é¸æŠžå¯¾è±¡ã‚’フレームã®ä¸­å¤®ã«"
+msgstr "フレームé¸æŠž"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -5315,9 +5337,8 @@ msgid "Scale mask for inserting keys."
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 ""
@@ -5332,14 +5353,12 @@ msgstr ""
"åˆã‚ã¦ã‚­ãƒ¼ã‚’手動ã§æŒ¿å…¥ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Auto Insert Key"
-msgstr "アニメーションキーを挿入"
+msgstr "自動挿入キー"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Insert Key (Existing Tracks)"
-msgstr "キーを (既存ã®ãƒˆãƒ©ãƒƒã‚¯ã«) 挿入"
+msgstr "(既存ã®ãƒˆãƒ©ãƒƒã‚¯ã«)キーを挿入"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Copy Pose"
@@ -5381,14 +5400,12 @@ msgstr "ノードを生æˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Error instancing scene from %s"
-msgstr "%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 ""
@@ -5411,22 +5428,11 @@ msgid "Edit Poly (Remove Point)"
msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
-#, fuzzy
msgid "Set Handle"
msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’設定ã™ã‚‹"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "ç”»åƒèª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "ç”»åƒå†…ã«é€æ˜Žåº¦ãŒ128以上ã®ãƒ”クセルãŒã‚ã‚Šã¾ã›ã‚“..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
#, fuzzy
msgid "Load Emission Mask"
msgstr "発光(Emission)マスクを読ã¿è¾¼ã‚€"
@@ -5435,9 +5441,8 @@ msgstr "発光(Emission)マスクを読ã¿è¾¼ã‚€"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "今ã™ãå†èµ·å‹•"
+msgstr "å†èµ·å‹•"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5463,9 +5468,8 @@ msgstr "発光(Emission)マスク"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Capture from Pixel"
-msgstr "ピクセルã‹ã‚‰å–å¾—"
+msgstr "ピクセルã‹ã‚‰ã‚­ãƒ£ãƒ—ãƒãƒ£"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5487,12 +5491,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"
@@ -5522,14 +5524,12 @@ msgid "Load Curve Preset"
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
@@ -5542,9 +5542,8 @@ 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"
@@ -5591,14 +5590,12 @@ msgid "Create Static Trimesh Body"
msgstr "スタティック(ä¸å¤‰ï¼‰ä¸‰è§’形メッシュ ボディを作æˆ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Static Convex Body"
-msgstr "スタティック(ä¸å¤‰ï¼‰å‡¸çŠ¶ãƒœãƒ‡ã‚£ã‚’生æˆ"
+msgstr "é™çš„凸状ボディを生æˆ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "This doesn't work on scene root!"
-msgstr "シーンã®ãƒ«ãƒ¼ãƒˆã§ã¯æ©Ÿèƒ½ã—ã¾ã›ã‚“!"
+msgstr "シーンã®ãƒ«ãƒ¼ãƒˆã§ã¯ç„¡åŠ¹ã§ã™!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -5610,9 +5607,8 @@ msgid "Failed creating shapes!"
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"
@@ -5636,9 +5632,8 @@ msgid "Model has no UV in this layer"
msgstr "モデルã«ã¯ã“ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã«UVãŒã‚ã‚Šã¾ã›ã‚“"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "MeshInstance lacks a Mesh!"
-msgstr "メッシュインスタンスã®ãƒ¡ãƒƒã‚·ãƒ¥ãŒå­˜åœ¨ã—ã¾ã›ã‚“"
+msgstr "メッシュインスタンスã«ãƒ¡ãƒƒã‚·ãƒ¥ãŒä¸è¶³ã—ã¦ã„ã¾ã™!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
@@ -5661,9 +5656,8 @@ msgid "Mesh"
msgstr "メッシュ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Trimesh Static Body"
-msgstr "スタティック(ä¸å¤‰ï¼‰ä¸‰è§’形メッシュ ボディを作æˆ"
+msgstr "é™çš„三角形メッシュボディを作æˆ"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Collision Sibling"
@@ -5720,10 +5714,10 @@ msgid "Update from Scene"
msgstr "シーンã‹ã‚‰ã‚¢ãƒƒãƒ—デート"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "No mesh source specified (and no MultiMesh set in node)."
msgstr ""
-"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“(MultiMesh setã‚‚ node内ã«å­˜åœ¨ã—ã¾ã›ã‚“)"
+"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“(ノードã«MultiMeshãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›"
+"ん)。"
#: editor/plugins/multimesh_editor_plugin.cpp
#, fuzzy
@@ -5761,16 +5755,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "無効ãªã‚µãƒ¼ãƒ•ã‚§ã‚¹ã‚½ãƒ¼ã‚¹ã§ã™ (é¢ãŒã‚ã‚Šã¾ã›ã‚“)。"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
-msgid "Parent has no solid faces to populate."
-msgstr "åˆæœŸå€¤ã‚’設定ã™ã‚‹å¡—ã‚Šã¤ã¶ã—é¢ãŒã€è¦ªã«ã‚ã‚Šã¾ã›ã‚“."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
-msgid "Couldn't map area."
-msgstr "エリアをマッピングã§ãã¾ã›ã‚“"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "ソースメッシュをé¸æŠž:"
@@ -5784,9 +5768,8 @@ msgid "Populate Surface"
msgstr "サーフェスã«åˆæœŸå€¤ã‚’設定"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "Populate MultiMesh"
-msgstr "マルãƒãƒ¡ãƒƒã‚·ãƒ¥ã«åˆæœŸå€¤ã‚’設定"
+msgstr "マルãƒãƒ¡ãƒƒã‚·ãƒ¥ã®è¨­å®š"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Target Surface:"
@@ -5814,19 +5797,16 @@ msgid "Mesh Up Axis:"
msgstr "メッシュã®ã‚¢ãƒƒãƒ—軸:"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "Random Rotation:"
msgstr "ランダムãªå›žè»¢:"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "Random Tilt:"
-msgstr "ランダムãªãƒ†ã‚£ãƒ«ãƒˆ:"
+msgstr "ランダムãªå‚¾ã:"
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "Random Scale:"
-msgstr "縮尺をランダムã«å¤‰æ›´:"
+msgstr "ランダムãªç¸®å°º:"
#: editor/plugins/multimesh_editor_plugin.cpp
#, fuzzy
@@ -5855,7 +5835,7 @@ msgstr "å¯è¦–性ã®çŸ©å½¢ã‚’生æˆ"
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Can only set point into a ParticlesMaterial process material"
-msgstr ""
+msgstr "ParticlesMaterialプロセスマテリアルã«ã®ã¿ç‚¹ã‚’設定ã§ãã¾ã™"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -5863,21 +5843,27 @@ msgid "Generation Time (sec):"
msgstr "生æˆæ™‚é–“ (秒):"
#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
-msgid "Faces contain no area!"
-msgstr "é¢ã«ã‚¨ãƒªã‚¢ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“!"
+msgid "The geometry doesn't contain any faces."
+msgstr "ノードã¯ã‚¸ã‚ªãƒ¡ãƒˆãƒªãƒ¼ (é¢) ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“。"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "é¢ãŒã‚ã‚Šã¾ã›ã‚“!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "ノードã¯ã‚¸ã‚ªãƒ¡ãƒˆãƒªãƒ¼ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“。"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "ノードã¯ã‚¸ã‚ªãƒ¡ãƒˆãƒªãƒ¼ (é¢) ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“。"
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "ノードã¯ã‚¸ã‚ªãƒ¡ãƒˆãƒªãƒ¼ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“。"
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
@@ -5893,9 +5879,8 @@ msgid "Surface Points"
msgstr "表é¢ã®ç‚¹"
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Surface Points+Normal (Directed)"
-msgstr "サーフェスãƒã‚¤ãƒ³ãƒˆï¼‹Normal(指å‘性)"
+msgstr "サーフェスãƒã‚¤ãƒ³ãƒˆï¼‹Normal(指å‘性)"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
@@ -5928,40 +5913,33 @@ msgid "Remove Point from Curve"
msgstr "曲線ã‹ã‚‰ãƒã‚¤ãƒ³ãƒˆã‚’除去"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Out-Control from Curve"
-msgstr "Out-ãƒãƒ³ãƒ‰ãƒ«ã‚’曲線ã‹ã‚‰é™¤åŽ»"
+msgstr "曲線ã‹ã‚‰Out-Controlを削除"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove In-Control from Curve"
-msgstr "In-ãƒãƒ³ãƒ‰ãƒ«ã‚’曲線ã‹ã‚‰é™¤åŽ»"
+msgstr "曲線ã‹ã‚‰In-Controlを削除"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Add Point to Curve"
-msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’曲線ã«è¿½åŠ "
+msgstr "点を曲線ã«è¿½åŠ "
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Split Curve"
-msgstr "曲線を閉ã˜ã‚‹"
+msgstr "曲線を分割ã™ã‚‹"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Point in Curve"
-msgstr "曲線ã®ãƒã‚¤ãƒ³ãƒˆã‚’移動"
+msgstr "曲線内ã®ãƒã‚¤ãƒ³ãƒˆã‚’移動"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move In-Control in Curve"
-msgstr "曲線ã®In-ãƒãƒ³ãƒ‰ãƒ«ã‚’移動ã™ã‚‹"
+msgstr "曲線内ã®In-Controlを移動ã™ã‚‹"
#: editor/plugins/path_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Out-Control in Curve"
-msgstr "曲線ã®Out-ãƒãƒ³ãƒ‰ãƒ«ã‚’移動ã™ã‚‹"
+msgstr "曲線内ã®Out-Controlを移動ã™ã‚‹"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -5970,9 +5948,8 @@ msgstr "点をé¸æŠž"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Shift+Drag: Select Control Points"
-msgstr "Shift+ドラッグ:コントロールãƒã‚¤ãƒ³ãƒˆã‚’é¸æŠž"
+msgstr "Shift + ドラッグ:コントロールãƒã‚¤ãƒ³ãƒˆã‚’é¸æŠž"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -5980,9 +5957,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
@@ -6035,7 +6011,7 @@ msgstr "カーブãƒã‚¤ãƒ³ãƒˆã®ä½ç½®ã‚’設定"
#: editor/plugins/path_editor_plugin.cpp
#, fuzzy
msgid "Set Curve In Position"
-msgstr "曲線ã®In-ãƒãƒ³ãƒ‰ãƒ«ã®ä½ç½®ã‚’指定"
+msgstr "曲線ã®ä½ç½®ã‚’設定"
#: editor/plugins/path_editor_plugin.cpp
#, fuzzy
@@ -6043,7 +6019,6 @@ msgid "Set Curve Out Position"
msgstr "曲線ã®Out-ãƒãƒ³ãƒ‰ãƒ«ã®ä½ç½®ã‚’指定"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Split Path"
msgstr "パスを分割"
@@ -6060,12 +6035,10 @@ msgid "Remove In-Control Point"
msgstr "曲線ã®In-ãƒãƒ³ãƒ‰ãƒ«ã‚’除去"
#: editor/plugins/path_editor_plugin.cpp
-#, fuzzy
msgid "Split Segment (in curve)"
-msgstr "分割ã™ã‚‹(曲線を)"
+msgstr "セグメントを分割ã™ã‚‹(曲線内)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
msgstr "ジョイントを移動"
@@ -6125,9 +6098,8 @@ 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"
@@ -6158,7 +6130,6 @@ msgid "Bones"
msgstr "ボーン"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Points"
msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’移動"
@@ -6183,7 +6154,6 @@ msgid "Rotate Polygon"
msgstr "ãƒãƒªã‚´ãƒ³ã‚’回転"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Scale Polygon"
msgstr "ãƒãƒªã‚´ãƒ³ã®ç¸®å°ºã‚’変更"
@@ -6212,12 +6182,10 @@ msgid "Radius:"
msgstr "åŠå¾„:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Polygon->UV"
msgstr "ãƒãƒªã‚´ãƒ³->UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "UV->Polygon"
msgstr "UV->ãƒãƒªã‚´ãƒ³"
@@ -6230,7 +6198,6 @@ msgid "Grid Settings"
msgstr "スナップã®è¨­å®š"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "スナップ"
@@ -6263,9 +6230,8 @@ msgid "Grid Step Y:"
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!"
@@ -6285,9 +6251,8 @@ msgid "Delete Resource"
msgstr "リソースを削除"
#: editor/plugins/resource_preloader_editor_plugin.cpp
-#, fuzzy
msgid "Resource clipboard is empty!"
-msgstr "リソースã®ã‚¯ãƒªãƒƒãƒ—ボードã¯ç©ºã§ã™!"
+msgstr "リソースクリップボードãŒç©ºã§ã™!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Paste Resource"
@@ -6301,9 +6266,8 @@ msgstr "インスタンス:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Type:"
-msgstr "åž‹(Type):"
+msgstr "åž‹:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
@@ -6315,9 +6279,8 @@ msgid "Load Resource"
msgstr "リソースを読ã¿è¾¼ã‚€"
#: editor/plugins/resource_preloader_editor_plugin.cpp
-#, fuzzy
msgid "ResourcePreloader"
-msgstr "リソースã®ãƒ‘ス"
+msgstr "リソースプリローダー"
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "AnimationTree has no path set to an AnimationPlayer"
@@ -6340,40 +6303,33 @@ msgid "Error writing TextFile:"
msgstr "テキストファイルã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "エラー: ファイルを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚"
-
-#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error could not load file."
-msgstr "フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+msgid "Could not load file at:"
+msgstr "タイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
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
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "æ–°è¦ãƒ†ã‚­ã‚¹ãƒˆãƒ•ã‚¡ã‚¤ãƒ«..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6389,9 +6345,8 @@ msgid "Import Theme"
msgstr "テーマã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme"
-msgstr "テーマをä¿å­˜ã™ã‚‹é€”中ã§ã®ã‚¨ãƒ©ãƒ¼"
+msgstr "テーマã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving"
@@ -6402,9 +6357,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
@@ -6412,18 +6366,16 @@ msgid "Find Next"
msgstr "次を検索"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "フィルタプロパティ"
+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 "フィルターモード:"
+msgstr "フィルタメソッド"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6458,6 +6410,11 @@ msgid "Open..."
msgstr "é–‹ã..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "スクリプトを開ã"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "ã™ã¹ã¦ä¿å­˜"
@@ -6495,13 +6452,13 @@ msgid "Save Theme"
msgstr "テーマをä¿å­˜"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "ドキュメントを閉ã˜ã‚‹"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "ã™ã¹ã¦é–‰ã˜ã‚‹"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "ドキュメントを閉ã˜ã‚‹"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "実行"
@@ -6536,9 +6493,8 @@ 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"
@@ -6566,12 +6522,11 @@ msgid "Discard"
msgstr "破棄"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?:"
msgstr ""
-"次ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã€ã‚ˆã‚Šæ–°ã—ã„版ãŒãƒ‡ã‚£ã‚¹ã‚¯ã«å­˜åœ¨ã—ã¾ã™\n"
+"以下ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚ˆã‚Šæ–°ã—ã„ã‚‚ã®ãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å­˜åœ¨ã—ã¾ã™ã€‚\n"
"ã©ã†ã—ã¾ã™ã‹?:"
#: editor/plugins/script_editor_plugin.cpp
@@ -6592,36 +6547,37 @@ msgstr "デãƒãƒƒã‚¬"
msgid "Search Results"
msgstr "検索çµæžœ"
-#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "最近開ã„ãŸã‚·ãƒ¼ãƒ³ã®å±¥æ­´ã‚’クリア"
+
+#: editor/plugins/script_text_editor.cpp
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 "シグナル"
#: 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)"
@@ -6664,6 +6620,7 @@ msgid "Syntax Highlighter"
msgstr "シンタックスãƒã‚¤ãƒ©ã‚¤ãƒˆ"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6673,9 +6630,8 @@ msgid "Bookmarks"
msgstr "ブックマーク"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "点を作æˆã™ã‚‹ã€‚"
+msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6699,26 +6655,6 @@ msgid "Toggle Comment"
msgstr "コメントã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "フリールックã®åˆ‡ã‚Šæ›¿ãˆ"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "次ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "å‰ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "ã™ã¹ã¦ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’除去"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "行を折りãŸãŸã‚€/展開ã™ã‚‹"
@@ -6739,6 +6675,11 @@ msgid "Complete Symbol"
msgstr "シンボルを補完"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "スケールã®é¸æŠž"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "末尾ã®ç©ºç™½ã‚’å–り除ã"
@@ -6755,29 +6696,32 @@ msgid "Auto Indent"
msgstr "自動インデント"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’切り替ãˆ"
+msgid "Find Previous"
+msgstr "å‰ã‚’検索"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "ã™ã¹ã¦ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã‚’消去"
+msgid "Find in Files..."
+msgstr "複数ファイル内を検索..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "次ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
+msgid "Contextual Help"
+msgstr "コンテキストヘルプ"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "å‰ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
+msgid "Toggle Bookmark"
+msgstr "ブックマークã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "å‰ã‚’検索"
+msgid "Go to Next Bookmark"
+msgstr "次ã®ãƒ–ックマークã«ç§»å‹•"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "複数ファイル内を検索..."
+msgid "Go to Previous Bookmark"
+msgstr "å‰ã®ãƒ–ックマークã«ç§»å‹•"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "ã™ã¹ã¦ã®ãƒ–ックマークを削除"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6788,18 +6732,29 @@ msgid "Go to Line..."
msgstr "è¡Œã«ç§»å‹•..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Contextual Help"
-msgstr "文脈å‚照ヘルプ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’切り替ãˆ"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "ã™ã¹ã¦ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã‚’消去"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "次ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "å‰ã®ãƒ–レークãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•"
#: editor/plugins/shader_editor_plugin.cpp
-#, 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"
@@ -6810,18 +6765,16 @@ msgid "This skeleton has no bones, create some children Bone2D nodes."
msgstr "ã“ã®skeletonã«ã¯ãƒœãƒ¼ãƒ³ãŒã‚ã‚Šã¾ã›ã‚“。å­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 "ボーンã¸ãƒ¬ã‚¹ãƒˆãƒ»ãƒãƒ¼ã‚ºã‚’設定ã™ã‚‹"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton2D"
-msgstr "スケルトン..."
+msgstr "スケルトン2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
@@ -6832,24 +6785,20 @@ msgid "Set Bones to Rest Pose"
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 "アウトラインを生æˆ"
+msgstr "物ç†ã‚¹ã‚±ãƒ«ãƒˆãƒ³ã‚’作æˆã™ã‚‹"
#: editor/plugins/skeleton_ik_editor_plugin.cpp
-#, fuzzy
msgid "Play IK"
-msgstr "実行"
+msgstr "IK(Inverse kinematics)を実行ã™ã‚‹"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
@@ -6860,9 +6809,8 @@ msgid "Perspective"
msgstr "é€è¦–投影"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Transform Aborted."
-msgstr "トランスフォームã¯ä¸­æ­¢ã•ã‚Œã¾ã—ãŸ."
+msgstr "変æ›ã¯ä¸­æ­¢ã•ã‚Œã¾ã—ãŸ."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "X-Axis Transform."
@@ -6881,9 +6829,8 @@ msgid "View Plane Transform."
msgstr "ビュー平é¢ãƒˆãƒ©ãƒ³ã‚¹ãƒ•ã‚©ãƒ¼ãƒ ."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scaling: "
-msgstr "縮尺:"
+msgstr "縮尺: "
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -6899,9 +6846,8 @@ msgid "Keying is disabled (no key inserted)."
msgstr "キーã¯ç„¡åŠ¹åŒ–ã•ã‚Œã¦ã„ã¾ã™ï¼ˆã‚­ãƒ¼ã¯æŒ¿å…¥ã•ã‚Œã¦ã„ã¾ã›ã‚“)."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Animation Key Inserted."
-msgstr "アニメーションã®ã‚­ãƒ¼ãŒæŒ¿å…¥ã•ã‚Œã¦ã„ã¾ã™."
+msgstr "アニメーションキーãŒæŒ¿å…¥ã•ã‚Œã¾ã—ãŸã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pitch"
@@ -6980,19 +6926,20 @@ msgid "Rear"
msgstr "後é¢"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Align with View"
-msgstr "シーンビューã«ã‚«ãƒ¡ãƒ©ã‚’åˆã‚ã›ã‚‹ï¼ˆAlign With View)"
+msgid "Align Transform with View"
+msgstr "変æ›ã‚’ビューã«åˆã‚ã›ã‚‹"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "回転をビューã«åˆã‚ã›ã‚‹"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "No parent to instance a child at."
msgstr "å­ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’生æˆã™ã‚‹ãŸã‚ã®è¦ªãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "This operation requires a single selected node."
-msgstr "一ã¤ãƒŽãƒ¼ãƒ‰ã‚’指定ã—ãªã„ã¨ã€ã“ã®æ“作ã¯ã§ãã¾ã›ã‚“"
+msgstr "å˜ä¸€ã®é¸æŠžã•ã‚ŒãŸãƒŽãƒ¼ãƒ‰ãŒãªã„ã¨ã€ã“ã®æ“作ã¯è¡Œãˆã¾ã›ã‚“"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7040,13 +6987,12 @@ msgstr "オーディオリスナー"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Doppler Enable"
-msgstr "有効ã«ã™ã‚‹"
+msgid "Enable Doppler"
+msgstr "フィルタリングを有効化"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Cinematic Preview"
-msgstr "メッシュライブラリを生æˆ"
+msgstr "ã‚·ãƒãƒžãƒ†ã‚£ãƒƒã‚¯ãƒ—レビュー"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
@@ -7100,42 +7046,25 @@ msgid "Snap Nodes To Floor"
msgstr "Snapモード:"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid ""
"Drag: Rotate\n"
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
-msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: デプス(深ã•ï¼‰ãƒªã‚¹ãƒˆã®é¸æŠž"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "移動モード (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "回転モード (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "スケールモード (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "ローカル座標系"
+msgstr ""
+"ドラッグ:回転\n"
+"Alt+ドラッグ:移動\n"
+"Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ãリストã®é¸æŠž"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "ローカル空間モード (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "スナップモード (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "下é¢å›³"
@@ -7160,9 +7089,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"
@@ -7177,34 +7105,13 @@ msgid "Focus Selection"
msgstr "é¸æŠžã«ãƒ•ã‚©ãƒ¼ã‚«ã‚¹"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "é¸æŠžã‚’ビューã«æ•´åˆ—"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "é¸æŠžãƒ„ール"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "移動ツール"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "回転ツール"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "スケールツール"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "フリールックã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform"
-msgstr "トランスフォーム"
+msgstr "変æ›"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7212,9 +7119,8 @@ msgid "Snap Object to Floor"
msgstr "オブジェクトを底é¢ã«ã‚¹ãƒŠãƒƒãƒ—"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Transform Dialog..."
-msgstr "トランスフォームã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°..."
+msgstr "変æ›ã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
@@ -7254,7 +7160,8 @@ msgstr "ビューã®ã‚°ãƒªãƒƒãƒ‰"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "設定"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7270,9 +7177,8 @@ msgid "Rotate Snap (deg.):"
msgstr "スナップã®å›žè»¢ï¼ˆåº¦ï¼‰:"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale Snap (%):"
-msgstr "スナップã®å¤§ãã•(%):"
+msgstr "スナップã®æ‹¡å¤§/縮å°(%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
@@ -7284,11 +7190,11 @@ msgstr "視野角(度):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Near:"
-msgstr ""
+msgstr "Z-Nearを表示:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Far:"
-msgstr ""
+msgstr "Z-Farを表示:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Change"
@@ -7304,9 +7210,8 @@ msgid "Rotate (deg.):"
msgstr "回転(度):"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale (ratio):"
-msgstr "縮尺(比):"
+msgstr "縮尺(比):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Type"
@@ -7325,29 +7230,24 @@ msgid "Nameless gizmo"
msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Mesh2D"
-msgstr "アウトラインメッシュを生æˆ"
+msgstr "メッシュ2Dを作æˆ"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon2D"
-msgstr "Polygon3Dを生æˆ"
+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 "スプライトã¯ç©ºã§ã™!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
@@ -7358,36 +7258,32 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "ジオメトリãŒç„¡åŠ¹ã§ã™ã€‚メッシュã«ç½®ãæ›ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Mesh2D"
-msgstr "2Dメッシュã«å¤‰æ›"
+msgstr "メッシュ2Dã«å¤‰æ›"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
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 "ジオメトリãŒç„¡åŠ¹ã§ã™ã€‚è¡çªãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。"
#: 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 "ジオメトリãŒç„¡åŠ¹ã§ã™ã€‚ライトオクールダーを作æˆã§ãã¾ã›ã‚“。"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create LightOccluder2D Sibling"
-msgstr "オクルーダーãƒãƒªã‚´ãƒ³ã‚’生æˆ"
+msgstr "LightOccluder2Dã®å…„弟を作æˆã™ã‚‹"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
@@ -7398,9 +7294,8 @@ msgid "Simplification: "
msgstr "簡略化:"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Grow (Pixels): "
-msgstr "スナップ機能(ピクセルå˜ä½ï¼‰:"
+msgstr "拡大(ピクセル): "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Update Preview"
@@ -7411,28 +7306,24 @@ 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"
msgstr "フレームを追加"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "ERROR: Couldn't load frame resource!"
msgstr "エラー:フレームリソースを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Resource clipboard is empty or not a texture!"
-msgstr "リソースクリップボードã¯ç©ºã‹ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ä»¥å¤–ã§ã™!"
+msgstr "リソースクリップボードã¯ç©ºã‹ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ä»¥å¤–ã®ã‚‚ã®ã§ã™!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
@@ -7471,9 +7362,8 @@ msgid "Animation Frames:"
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"
@@ -7488,19 +7378,16 @@ msgid "Insert Empty (After)"
msgstr "空を挿入 (後)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move (Before)"
-msgstr "ノードを除去"
+msgstr "移動(å‰)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move (After)"
-msgstr "å·¦ã«ç§»å‹•"
+msgstr "移動(後)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "スタックフレーム"
+msgstr "フレームをé¸æŠž"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
@@ -7512,29 +7399,24 @@ msgid "Vertical:"
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
-#, fuzzy
msgid "SpriteFrames"
-msgstr "スタックフレーム"
+msgstr "スプライトフレーム"
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "Set Region Rect"
-msgstr "テクスãƒãƒ£ã€€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³"
+msgstr "矩形ã®é ˜åŸŸã‚’設定"
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "Set Margin"
-msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’設定ã™ã‚‹"
+msgstr "マージンを設定ã™ã‚‹"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
@@ -7571,13 +7453,8 @@ msgid "Sep.:"
msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "TextureRegion"
-msgstr "テクスãƒãƒ£ã€€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³"
-
-#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "ファイルã«ãƒ†ãƒ¼ãƒžã‚’ä¿å­˜ã§ãã¾ã›ã‚“:"
+msgstr "テクスãƒãƒ£é ˜åŸŸ"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
@@ -7596,9 +7473,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."
@@ -7621,28 +7497,24 @@ msgid "Create Empty Editor Template"
msgstr "空ã®ã‚¨ãƒ‡ã‚£ã‚¿ãƒ†ãƒ³ãƒ—レートを生æˆ"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Create From Current Editor Theme"
-msgstr "空ã®ã‚¨ãƒ‡ã‚£ã‚¿ãƒ†ãƒ³ãƒ—レートを生æˆ"
+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"
@@ -7672,13 +7544,13 @@ msgstr "サブメニュー"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
-msgstr "アイテム"
+msgid "Subitem 1"
+msgstr "アイテム 1"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
-msgstr "アイテム"
+msgid "Subitem 2"
+msgstr "アイテム 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -7689,9 +7561,8 @@ msgid "Many"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled LineEdit"
-msgstr "無効"
+msgstr "ライン編集を無効ã«ã™ã‚‹"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -7706,9 +7577,8 @@ 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"
@@ -7720,9 +7590,8 @@ msgid "Has,Many,Options"
msgstr "オプション"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Data Type:"
-msgstr "データã®åž‹(Type):"
+msgstr "データã®åž‹:"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Icon"
@@ -7745,29 +7614,25 @@ msgid "Constant"
msgstr "コンスタント"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Erase Selection"
-msgstr "é¸æŠžã‚’消去"
+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"
msgstr "タイルマップを塗る"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Line Draw"
-msgstr "等速"
+msgstr "ç›´ç·šã‚’æç”»"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rectangle Paint"
@@ -7782,9 +7647,8 @@ msgid "Erase TileMap"
msgstr "タイルマップを消去"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "タイルを探ã™"
+msgstr "タイルを検索ã™ã‚‹"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -7792,31 +7656,22 @@ msgid "Transpose"
msgstr "転置"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "ミラーX"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-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"
msgstr "タイルを塗る"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+å³ãƒžã‚¦ã‚¹ãƒœã‚¿ãƒ³:ç·šã®æç”»\n"
"Shift+Ctrl+å³ãƒžã‚¦ã‚¹ãƒœã‚¿ãƒ³:矩形ペイント"
@@ -7826,14 +7681,12 @@ 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"
@@ -7844,19 +7697,16 @@ msgid "Flip Vertically"
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 "テクスãƒãƒ£ã‚’タイルセットã«è¿½åŠ ã™ã‚‹"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "パスã®ãƒã‚¤ãƒ³ãƒˆã‚’除去"
+msgstr "é¸æŠžã—ãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’タイルセットã‹ã‚‰å‰Šé™¤ã™ã‚‹"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -7867,27 +7717,24 @@ 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 "次ã®ã‚·ã‚§ã‚¤ãƒ—ã€ã‚µãƒ–タイルã€ã¾ãŸã¯ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚"
#: 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 "å‰ã®ã‚·ã‚§ã‚¤ãƒ—ã€ã‚µãƒ–タイルã€ã¾ãŸã¯ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "実行モード:"
+msgstr "領域モード"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -7895,34 +7742,28 @@ msgid "Collision Mode"
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."
@@ -7933,9 +7774,8 @@ msgid "Paste bitmask."
msgstr "ビットマスクを貼り付ã‘。"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Erase bitmask."
-msgstr "点を消ã™ã€‚"
+msgstr "ビットマスクを消去"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -7948,7 +7788,7 @@ msgstr "æ–°è¦ãƒãƒªã‚´ãƒ³ã‚’生æˆã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
-msgstr ""
+msgstr "領域Rect内ã«ãƒãƒªã‚´ãƒ³ã‚’ä¿æŒã—ã¾ã™ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
@@ -7974,14 +7814,12 @@ msgstr ""
"シーンã‹ã‚‰ä½œæˆã—ã¾ã™ã‹?ã“ã‚Œã«ã‚ˆã‚Šã€ç¾åœ¨ã®ã™ã¹ã¦ã®ã‚¿ã‚¤ãƒ«ãŒä¸Šæ›¸ãã•ã‚Œã¾ã™ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
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."
@@ -7992,31 +7830,36 @@ msgid ""
"Drag handles to edit Rect.\n"
"Click on another Tile to edit it."
msgstr ""
+"四角形を編集ã™ã‚‹ãŸã‚ãƒãƒ³ãƒ‰ãƒ«ã‚’ドラッグã—ã¾ã™ã€‚編集ã®ãŸã‚別ã®ã‚¿ã‚¤ãƒ«ã‚’クリック"
+"ã—ã¾ã™ã€‚"
#: 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
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 "ç¾åœ¨ç·¨é›†ä¸­ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å­˜ã™ã‚‹"
+msgstr ""
+"左クリック:ビットをオンã«è¨­å®šã—ã¾ã™ã€‚\n"
+"å³ã‚¯ãƒªãƒƒã‚¯:ビットをオフã«ã—ã¾ã™ã€‚\n"
+"Shift+左クリック:ワイルドカード・ビットを設定ã—ã¾ã™ã€‚\n"
+"別ã®ã‚¿ã‚¤ãƒ«ã‚’クリックã—ã¦ç·¨é›†ã—ã¾ã™ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8037,16 +7880,16 @@ 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
msgid "Create Tile"
@@ -8061,9 +7904,8 @@ msgid "Edit Tile Bitmask"
msgstr "タイル ビットマスクを編集"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Collision Polygon"
-msgstr "既存ã®ãƒãƒªã‚´ãƒ³ã‚’編集:"
+msgstr "コリジョンãƒãƒªã‚´ãƒ³ã®ç·¨é›†"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Occlusion Polygon"
@@ -8096,9 +7938,8 @@ msgid "Remove Tile"
msgstr "タイルを除去"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Collision Polygon"
-msgstr "ãƒãƒªã‚´ãƒ³ã¨ç‚¹ã‚’除去"
+msgstr "コリジョンãƒãƒªã‚´ãƒ³ã‚’削除"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Occlusion Polygon"
@@ -8129,104 +7970,95 @@ msgid "This property can't be changed."
msgstr "ã“ã®ãƒ—ロパティã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "タイルセット..."
+msgstr "タイルセット"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(GLES3ã®ã¿)"
#: 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 "\\ Vector"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
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 "出力ãƒãƒ¼ãƒˆã‚’追加"
#: 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"
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 "ノードを複製"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "ノードを貼り付ã‘"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "ノードを削除"
@@ -8239,9 +8071,8 @@ msgid "Vertex"
msgstr "頂点"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Fragment"
-msgstr "引数:"
+msgstr "フラグメント"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8250,22 +8081,24 @@ msgstr "å³å´é¢"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "シェーダーノードã®ä½œæˆ"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
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 "Color演算å­ã€‚"
#: 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."
@@ -8276,34 +8109,32 @@ msgid "Converts RGB vector to HSV equivalent."
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 "Burn演算å­ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Darken演算å­ã€‚"
#: 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 "Dodge演算å­ã€‚"
#: 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 "Lighten演算å­ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
@@ -8311,16 +8142,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Screen演算å­ã€‚"
#: 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
@@ -8328,6 +8158,22 @@ msgid "Color uniform."
msgstr "トランスフォーム"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "2ã¤ã®ãƒ‘ラメータ間㮠%s 比較ã®ãƒ–ールçµæžœã‚’è¿”ã—ã¾ã™ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "ç­‰ã—ã„(==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "より大ãã„(>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "より大ãã„ã‹ç­‰ã—ã„(>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8337,14 +8183,47 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "INFã¨ã‚¹ã‚«ãƒ©ãƒ‘ラメータã®æ¯”較ã®çµæžœã‚’ブール値ã§è¿”ã—ã¾ã™ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr "NaNã¨ã‚¹ã‚«ãƒ©ãƒ‘ラメータã®æ¯”較ã®çµæžœã‚’ブール値ã§è¿”ã—ã¾ã™ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "よりå°ã•ã„(<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "ãれ以下(<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "ç­‰ã—ããªã„(!=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
"指定ã•ã‚ŒãŸãƒ–ール値ãŒtrueã¾ãŸã¯falseã®å ´åˆã€é–¢é€£ä»˜ã‘られãŸãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "2ã¤ã®ãƒ‘ラメータ間ã®æ¯”較ã®çµæžœã‚’ブール値ã§è¿”ã—ã¾ã™ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr "INF(ã¾ãŸã¯NaN)ã¨ã‚¹ã‚«ãƒ©ãƒ‘ラメータã¨ã®æ¯”較ã®ãƒ–ールçµæžœã‚’è¿”ã—ã¾ã™ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
-msgstr "ベクトル定数を変更"
+msgstr "ブール定数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
@@ -8352,12 +8231,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "ã™ã¹ã¦ã®ã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ãƒ¢ãƒ¼ãƒ‰ã® '%s' 入力パラメーター。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "親ã«ã‚¹ãƒŠãƒƒãƒ—"
+msgstr "入力パラメータ。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
@@ -8365,65 +8243,63 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "フラグメントモードã¨ãƒ©ã‚¤ãƒˆã‚·ã‚§ãƒ¼ãƒ€ãƒ¢ãƒ¼ãƒ‰ã® '%s' 入力パラメーター。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "フラグメントシェーダーモード㮠'%s' 入力パラメーター。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "ライトシェーダーモード㮠'%s' 入力パラメータ。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "頂点シェーダモード㮠'%s' 入力パラメータ。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, 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 "Sqrt2定数(1.414214)。2ã®å¹³æ–¹æ ¹ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
@@ -8434,16 +8310,16 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "パラメータã®é€†ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "パラメータã®é€†åŒæ›²ç·šä½™å¼¦ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "パラメータã®é€†ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "パラメータã®åŒæ›²ç·šé€†ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8454,8 +8330,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "複数パラメータã®é€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "パラメータã®åŒæ›²ç·šé€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8471,8 +8347,8 @@ msgid "Returns the cosine of the parameter."
msgstr "パラメータã®ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "パラメータã®åŒæ›²ç·šã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8540,12 +8416,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / スカラー"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã«æœ€ã‚‚è¿‘ã„整数を検索ã—ã¾ã™ã€‚"
+msgid "Finds the nearest integer to the parameter."
+msgstr "パラメータã«æœ€ã‚‚è¿‘ã„整数を検索ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã«æœ€ã‚‚è¿‘ã„å¶æ•°ã®æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚"
+msgid "Finds the nearest even integer to the parameter."
+msgstr "パラメータã«æœ€ã‚‚è¿‘ã„å¶æ•°ã®æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -8560,18 +8436,19 @@ msgid "Returns the sine of the parameter."
msgstr "パラメータã®ç¬¦å·ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "パラメータã®åŒæ›²ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "パラメータã®å¹³æ–¹æ ¹ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8582,10 +8459,11 @@ msgstr ""
"ã•ã‚Œã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step関数( scalar(edge)ã€scalar(x))。\n"
"\n"
@@ -8596,12 +8474,12 @@ msgid "Returns the tangent of the parameter."
msgstr "パラメータã®ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "パラメータã®åŒæ›²ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr "(GLES3ã®ã¿)パラメータã®ãƒˆãƒ©ãƒ³ã‚±ãƒ¼ãƒˆã•ã‚ŒãŸå€¤ã‚’検索ã—ã¾ã™ã€‚"
+msgid "Finds the truncated value of the parameter."
+msgstr "パラメータã®ãƒˆãƒ©ãƒ³ã‚±ãƒ¼ãƒˆã•ã‚ŒãŸå€¤ã‚’検索ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8624,9 +8502,8 @@ msgid "Subtracts scalar from scalar."
msgstr "スカラーã‹ã‚‰ã‚¹ã‚«ãƒ©ãƒ¼ã‚’減算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar constant."
-msgstr "スカラ定数を変更"
+msgstr "スカラー定数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8643,12 +8520,17 @@ msgstr "テクスãƒãƒ£ãƒ»ãƒ«ãƒƒã‚¯ã‚¢ãƒƒãƒ—を実行ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr "テクスãƒãƒ£Uniformを変更"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup."
msgstr "テクスãƒãƒ£Uniformを変更"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr "テクスãƒãƒ£Uniformを変更"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8657,8 +8539,9 @@ msgid "Transform function."
msgstr "トランスフォームã®ãƒ€ã‚¤ã‚¢ãƒ­ã‚°..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8682,16 +8565,16 @@ msgid "Decomposes transform to four vectors."
msgstr "変æ›ã‚’4ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã«åˆ†è§£ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr "(GLES3ã®ã¿)変æ›ã®è¡Œåˆ—å¼ã‚’計算ã—ã¾ã™ã€‚"
+msgid "Calculates the determinant of a transform."
+msgstr "変æ›ã®è¡Œåˆ—å¼ã‚’計算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(GLES3ã®ã¿)変æ›ã®é€†é–¢æ•°ã‚’計算ã—ã¾ã™ã€‚"
+msgid "Calculates the inverse of a transform."
+msgstr "変æ›ã®é€†è¡Œåˆ—を計算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(GLES3ã®ã¿)変æ›ã®è»¢ç½®ã‚’計算ã—ã¾ã™ã€‚"
+msgid "Calculates the transpose of a transform."
+msgstr "変æ›ã®è»¢ç½®ã‚’計算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8712,14 +8595,12 @@ msgid "Transform uniform."
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."
@@ -8742,8 +8623,9 @@ msgid "Calculates the dot product of two vectors."
msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã®å†…ç©ã‚’計算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8762,6 +8644,11 @@ msgid "Linear interpolation between two vectors."
msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«é–“ã®ãƒªãƒ‹ã‚¢è£œé–“。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«é–“ã®ãƒªãƒ‹ã‚¢è£œé–“。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "ベクトルã®æ­£è¦åŒ–ç©ã‚’計算ã—ã¾ã™ã€‚"
@@ -8774,20 +8661,22 @@ msgid "1.0 / vector"
msgstr "1.0 / ベクトル"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+msgid "Returns the vector that points in the direction of refraction."
msgstr "屈折ã®æ–¹å‘を指ã™ãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8798,10 +8687,11 @@ msgstr ""
"ã•ã‚Œã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8812,20 +8702,22 @@ msgstr ""
"ã•ã‚Œã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step関数( scalar(edge)ã€vector(x))。\n"
"\n"
@@ -8852,9 +8744,8 @@ msgid "Subtracts vector from vector."
msgstr "ベクトルã«ãƒ™ã‚¯ãƒˆãƒ«ã‚’減算ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector constant."
-msgstr "ベクトル定数を変更"
+msgstr "ベクトル定数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8880,75 +8771,77 @@ msgstr ""
"è¿”ã—ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
-msgstr "(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)スカラー導関数。"
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(フラグメント/ライトモードã®ã¿)スカラー導関数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr "(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)ベクトル導関数。"
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(フラグメント/ライトモードã®ã¿)ベクトル導関数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル)ローカル差分を使用ã—㦠"
-"'x' ã§å¾®åˆ†ã—ã¾ã™ã€‚"
+"(フラグメント/ライトモードã®ã¿)(ベクトル)ローカル差分を使用ã—㦠'x' ã§å¾®åˆ†ã—"
+"ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー)ローカル差分を使用ã—㦠"
-"'x' ã§å¾®åˆ†ã—ã¾ã™ã€‚"
+"(フラグメント/ライトモードã®ã¿)(スカラー)ローカル差分を使用ã—㦠'x' ã§å¾®åˆ†ã—"
+"ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル)ローカル差分を使用ã—㦠"
-"'y' ã§å¾®åˆ†ã—ã¾ã™ã€‚"
+"(フラグメント/ライトモードã®ã¿)(ベクトル)ローカル差分を使用ã—㦠'y' ã§å¾®åˆ†ã—"
+"ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー)ローカル差分を使用ã—㦠"
-"'y' ã§å¾®åˆ†ã—ã¾ã™ã€‚"
+"(フラグメント/ライトモードã®ã¿)(スカラー)ローカル差分を使用ã—㦠'y' ã§å¾®åˆ†ã—"
+"ã¾ã™ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル) 'x' 㨠'y' ã®çµ¶å¯¾å°Žé–¢æ•°"
-"ã®åˆè¨ˆã€‚"
+"(フラグメント/ライトモードã®ã¿)(ベクトル) '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'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
-"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー) 'x' 㨠'y' ã®çµ¶å¯¾å°Žé–¢æ•°"
-"ã®åˆè¨ˆã€‚"
+"(フラグメント/ライトモードã®ã¿)(スカラー) 'x' 㨠'y' ã®çµ¶å¯¾å°Žé–¢æ•°ã®åˆè¨ˆã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "VisualShader"
-msgstr "シェーダー"
+msgstr "ビジュアルシェーダー"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "タイル プロパティを編集"
+msgstr "ビジュアルプロパティã®ç·¨é›†"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Visual Shader Mode Changed"
-msgstr "シェーダーã®å¤‰æ›´"
+msgstr "ビジュアルシェーダモードãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
#: editor/project_export.cpp
msgid "Runnable"
@@ -8986,14 +8879,12 @@ msgid "Release"
msgstr "離ã—ãŸ"
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "%sã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆä¸­"
+msgstr "ã™ã¹ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "存在ã—ãªã„パスã§ã™ã€‚"
+msgstr "指定ã•ã‚ŒãŸã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãƒ‘スãŒå­˜åœ¨ã—ã¾ã›ã‚“:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
@@ -9030,9 +8921,8 @@ msgid "Export selected resources (and dependencies)"
msgstr "é¸æŠžã—ãŸãƒªã‚½ãƒ¼ã‚¹ï¼ˆã¨ä¾å­˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®ï¼‰ã‚’エクスãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Mode:"
-msgstr "エクスãƒãƒ¼ãƒˆã®ãƒ¢ãƒ¼ãƒ‰:"
+msgstr "エクスãƒãƒ¼ãƒˆãƒ¢ãƒ¼ãƒ‰:"
#: editor/project_export.cpp
msgid "Resources to export:"
@@ -9059,9 +8949,8 @@ msgid "Make Patch"
msgstr "パッãƒç”Ÿæˆ"
#: editor/project_export.cpp
-#, fuzzy
msgid "Features"
-msgstr "テクスãƒãƒ£"
+msgstr "特徴"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9085,9 +8974,8 @@ msgid "Text"
msgstr "テキスト"
#: editor/project_export.cpp
-#, fuzzy
msgid "Compiled"
-msgstr "圧縮"
+msgstr "コンパイル"
#: editor/project_export.cpp
msgid "Encrypted (Provide Key Below)"
@@ -9106,6 +8994,7 @@ msgid "Export PCK/Zip"
msgstr "PCK/Zipã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/project_export.cpp
+#, fuzzy
msgid "Export mode?"
msgstr "エクスãƒãƒ¼ãƒˆ モード?"
@@ -9118,6 +9007,10 @@ msgid "Export templates for this platform are missing:"
msgstr "ã“ã®ãƒ—ラットフォームã«å¯¾ã™ã‚‹ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ テンプレートãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "エクスãƒãƒ¼ãƒˆãƒ†ãƒ³ãƒ—レートã®ç®¡ç†"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "デãƒãƒƒã‚°ä»˜ãエクスãƒãƒ¼ãƒˆ"
@@ -9168,9 +9061,8 @@ msgid "It would be a good idea to name your project."
msgstr "プロジェクトã«åå‰ã‚’付ã‘ã¦ãã ã•ã„."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid project path (changed anything?)."
-msgstr "ä¸æ­£ãªãƒ—ロジェクトã®ãƒ‘ス(何ã‹å¤‰ãˆã¾ã—ãŸã‹ï¼Ÿï¼‰"
+msgstr "プロジェクトパスãŒç„¡åŠ¹ã§ã™(何ã‹ã‚’変更ã—ã¾ã—ãŸã‹?)。"
#: editor/project_manager.cpp
msgid ""
@@ -9278,6 +9170,15 @@ msgid "Unnamed Project"
msgstr "åç„¡ã—ã®ãƒ—ロジェクト"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "既存ã®ãƒ—ロジェクトをインãƒãƒ¼ãƒˆ"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "次ã®å ´æ‰€ã®ãƒ—ロジェクトを開ã‘ã¾ã›ã‚“ '%s'。"
@@ -9286,7 +9187,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"
@@ -9298,16 +9198,15 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
-"以下ã®ãƒ—ロジェクト設定ファイルã¯ã€å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã‚Šç”Ÿæˆã•ã‚Œã¦ãŠ"
-"ã‚Šã€ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç”¨ã«å¤‰æ›ãŒå¿…è¦ã§ã™:\n"
+"次ã®ãƒ—ロジェクト設定ファイルã«ã¯ã€ä½œæˆã«ä½¿ç”¨ã—ãŸGodotã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯æŒ‡å®šã•ã‚Œã¦"
+"ã„ã¾ã›ã‚“。\n"
"\n"
"%s\n"
"\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"
@@ -9335,15 +9234,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 ""
-"é¸æŠžã—ãŸã‚·ãƒ¼ãƒ³ '%s' ã¯ã€ã‚·ãƒ¼ãƒ³ ファイルã§ã¯ã‚ã‚Šã¾ã›ã‚“ã€æœ‰åŠ¹ãªã‚‚ã®ã‚’é¸æŠžã—ã¦ã„"
-"ã¾ã™ã‹ï¼Ÿ\n"
-"'アプリケーション' カテゴリã®ä¸‹ã®'プロジェクト設定'ã§å¤‰æ›´ã§ãã¾ã™ã€‚"
+"プロジェクトを実行ã§ãã¾ã›ã‚“:メインシーンãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+"プロジェクトを編集ã—ã€ã€Œã‚¢ãƒ—リケーションã€ã‚«ãƒ†ã‚´ãƒªå†…ã®ã€Œãƒ—ロジェクト設定ã€ã§"
+"メインシーンを設定ã—ã¦ãã ã•ã„。"
#: editor/project_manager.cpp
msgid ""
@@ -9354,42 +9252,42 @@ 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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"一覧ã‹ã‚‰ãƒ—ロジェクトを削除ã—ã¾ã™ã‹ï¼Ÿï¼ˆãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®å†…容ã¯å¤‰æ›´ã•ã‚Œã¾ã›ã‚“)"
+"%d プロジェクトを一覧ã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹?\n"
+"プロジェクトフォルダã®å†…容ã¯å¤‰æ›´ã•ã‚Œã¾ã›ã‚“。"
#: 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
msgid ""
@@ -9404,8 +9302,9 @@ msgid "Project Manager"
msgstr "プロジェクトマãƒãƒ¼ã‚¸ãƒ£ãƒ¼"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "プロジェクト一覧"
+#, fuzzy
+msgid "Projects"
+msgstr "プロジェクト"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9420,19 +9319,14 @@ msgid "New Project"
msgstr "æ–°è¦ãƒ—ロジェクト"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’除去"
+msgstr "存在ã—ãªã„ã‚‚ã®ã‚’削除"
#: editor/project_manager.cpp
msgid "Templates"
msgstr "テンプレート"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "終了"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "今ã™ãå†èµ·å‹•"
@@ -9441,7 +9335,6 @@ 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?"
@@ -9454,14 +9347,12 @@ msgid "Key "
msgstr "キー "
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Joy Button"
-msgstr "ジョイスティックã®ãƒœã‚¿ãƒ³"
+msgstr "ゲームパッドã®ãƒœã‚¿ãƒ³"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Joy Axis"
-msgstr "ジョイスティックã®è»¸"
+msgstr "ゲームパッドã®æ–¹å‘キー/スティック"
#: editor/project_settings_editor.cpp
msgid "Mouse Button"
@@ -9476,19 +9367,16 @@ 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
-#, fuzzy
msgid "Rename Input Action Event"
msgstr "入力アクションイベントã®åå‰ã‚’変更ã™ã‚‹"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "アニメーションã®åå‰ã‚’変更:"
+msgstr "アクションデッドゾーンã®å¤‰æ›´"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
@@ -9535,56 +9423,46 @@ msgid "Middle Button"
msgstr "中央ボタン"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Up Button"
-msgstr "ホイールupボタン"
+msgstr "ホイール上ボタン"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Down Button"
-msgstr "ホイールDownボタン"
+msgstr "ホイール下ボタン"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Left Button"
-msgstr "ホイールupボタン"
+msgstr "ホイール左ボタン"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Right Button"
-msgstr "å³ãƒœã‚¿ãƒ³"
+msgstr "ホイールå³ãƒœã‚¿ãƒ³"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 1"
-msgstr "ボタン6"
+msgstr "Xボタン1"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 2"
-msgstr "ボタン6"
+msgstr "Xボタン2"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Joypad Axis Index:"
-msgstr "ジョイパッド軸ã®Index:"
+msgstr "ジョイパッドã®æ–¹å‘キー/スティックã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹:"
#: editor/project_settings_editor.cpp
msgid "Axis"
msgstr "アナログ"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Joypad Button Index:"
-msgstr "ジョイパッドã®ãƒœã‚¿ãƒ³ã®Index:"
+msgstr "ジョイパッドã®ãƒœã‚¿ãƒ³ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹:"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Erase Input Action"
-msgstr "入力アクションイベントを消去"
+msgstr "入力アクションを消去"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Erase Input Action Event"
msgstr "入力アクションイベントを消去"
@@ -9618,18 +9496,16 @@ msgid "Wheel Down."
msgstr "マウスホイールを下."
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Add Global Property"
-msgstr "プロパティã«getter(get method)を作る"
+msgstr "グローãƒãƒ«ãƒ—ロパティã®è¿½åŠ "
#: editor/project_settings_editor.cpp
msgid "Select a setting item first!"
msgstr "設定項目をé¸æŠžã—ã¦ãã ã•ã„!"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "No property '%s' exists."
-msgstr "プロパティ:"
+msgstr "プロパティ '%s' ã¯å­˜åœ¨ã—ã¾ã›ã‚“。"
#: editor/project_settings_editor.cpp
msgid "Setting '%s' is internal, and it can't be deleted."
@@ -9648,9 +9524,8 @@ msgstr ""
"ãã¾ã›ã‚“。"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Add Input Action"
-msgstr "入力アクションを追加"
+msgstr "入力アクションã®è¿½åŠ "
#: editor/project_settings_editor.cpp
msgid "Error saving settings."
@@ -9687,9 +9562,8 @@ msgid "Change Resource Remap Language"
msgstr "リソースリマップ言語を変更"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Remove Resource Remap"
-msgstr "リソースã®ãƒªãƒžãƒƒãƒ—を除去"
+msgstr "リソースã®ãƒªãƒžãƒƒãƒ—を削除"
#: editor/project_settings_editor.cpp
#, fuzzy
@@ -9697,9 +9571,8 @@ msgid "Remove Resource Remap Option"
msgstr "リソースã®ãƒªãƒžãƒƒãƒ—オプションを除去"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Changed Locale Filter"
-msgstr "ブレンドã™ã‚‹æ™‚間を変更"
+msgstr "ロケールフィルタã®å¤‰æ›´"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter Mode"
@@ -9718,9 +9591,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"
@@ -9779,12 +9651,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 "é¸æŠžã—ãŸãƒ­ã‚±ãƒ¼ãƒ«ã®ã¿è¡¨ç¤º"
@@ -9800,6 +9670,10 @@ msgstr "ロケール:"
msgid "AutoLoad"
msgstr "自動読ã¿è¾¼ã¿"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "プラグイン"
+
#: editor/property_editor.cpp
#, fuzzy
msgid "Zero"
@@ -9834,36 +9708,24 @@ msgid "Error loading file: Not a resource!"
msgstr "ファイル読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: リソースã§ã¯ã‚ã‚Šã¾ã›ã‚“!"
#: editor/property_editor.cpp
-#, fuzzy
msgid "Pick a Node"
-msgstr "ノードã¸ã®ãƒ‘ス:"
+msgstr "ノードをé¸æŠžã™ã‚‹"
#: editor/property_editor.cpp
msgid "Bit %d, val %d."
msgstr "ビット %d, 値 %d."
#: editor/property_selector.cpp
-#, fuzzy
msgid "Select Property"
-msgstr "ã™ã¹ã¦é¸æŠž"
+msgstr "プロパティã®é¸æŠž"
#: editor/property_selector.cpp
-#, fuzzy
msgid "Select Virtual Method"
-msgstr "ã™ã¹ã¦é¸æŠž"
+msgstr "Virtualメソッドをé¸æŠž"
#: editor/property_selector.cpp
-#, fuzzy
msgid "Select Method"
-msgstr "ã™ã¹ã¦é¸æŠž"
-
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "PVRTCツールを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "PVRTCツールを使用ã—ã¦å¤‰æ›ã•ã‚ŒãŸã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“:"
+msgstr "メソッドã®é¸æŠž"
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
@@ -9879,9 +9741,8 @@ msgid "Suffix"
msgstr "サフィックス"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "アニメーションã®ã‚ªãƒ—ション"
+msgstr "高度ãªã‚ªãƒ—ション"
#: editor/rename_dialog.cpp
msgid "Substitute"
@@ -9896,9 +9757,8 @@ msgid "Node's parent name, if available"
msgstr "ノードã®è¦ªã®åå‰ (使用å¯èƒ½ãªå ´åˆ)"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "ノードタイプを探ã™"
+msgstr "ノードタイプ"
#: editor/rename_dialog.cpp
msgid "Current scene name"
@@ -9938,7 +9798,7 @@ msgstr "å„ノードã®ã‚«ã‚¦ãƒ³ã‚¿ã®å¢—分é‡"
#: editor/rename_dialog.cpp
msgid "Padding"
-msgstr ""
+msgstr "パディング"
#: editor/rename_dialog.cpp
msgid ""
@@ -9949,9 +9809,8 @@ msgstr ""
"欠è½ã—ãŸæ•°å­—ã¯ã€å…ˆé ­ã«ã‚¼ãƒ­ãŒåŸ‹ã‚è¾¼ã¾ã‚Œã¾ã™ã€‚"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expressions"
-msgstr "å¼ã‚’変更"
+msgstr "æ­£è¦è¡¨ç¾"
#: editor/rename_dialog.cpp
msgid "Post-Process"
@@ -9963,11 +9822,11 @@ msgstr "ä¿æŒ"
#: editor/rename_dialog.cpp
msgid "CamelCase to under_scored"
-msgstr ""
+msgstr "キャメルケースをアンダースコアã«"
#: editor/rename_dialog.cpp
msgid "under_scored to CamelCase"
-msgstr ""
+msgstr "アンダースコアをキャメルケースã«"
#: editor/rename_dialog.cpp
msgid "Case"
@@ -10014,7 +9873,6 @@ msgid "Current Scene"
msgstr "ç¾åœ¨ã®ã‚·ãƒ¼ãƒ³"
#: editor/run_settings_dialog.cpp
-#, fuzzy
msgid "Main Scene"
msgstr "メインシーン"
@@ -10031,18 +9889,16 @@ msgid "No parent to instance the scenes at."
msgstr "シーンをインスタンス化ã™ã‚‹è¦ªãŒã‚ã‚Šã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Error loading scene from %s"
msgstr "シーンを%sã‹ã‚‰èª­ã¿è¾¼ã‚€éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç”Ÿã˜ã¾ã—ãŸ"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid ""
"Cannot instance the scene '%s' because the current scene exists within one "
"of its nodes."
msgstr ""
"ã“ã®ã‚·ãƒ¼ãƒ³ã¯è‡ªèº«ã®ãƒŽãƒ¼ãƒ‰ã®ã†ã¡ã®ä¸€ã¤ã®å†…ã«ã‚ã‚‹ãŸã‚〠'%s'シーンをインスタンス"
-"化ã§ãã¾ã›ã‚“"
+"化ã§ãã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
msgid "Instance Scene(s)"
@@ -10057,14 +9913,12 @@ msgid "Clear Script"
msgstr "スクリプトをクリア"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "This operation can't be done on the tree root."
-msgstr "ã“ã®å‡¦ç†ã¯ãƒ„リーã®ãƒ«ãƒ¼ãƒˆã§ã¯ã§ãã¾ã›ã‚“."
+msgstr "ã“ã®å‡¦ç†ã¯ãƒ„リーã®ãƒ«ãƒ¼ãƒˆã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Move Node In Parent"
-msgstr "親ã®ãƒŽãƒ¼ãƒ‰ã‚’移動"
+msgstr "ノードを親ã«ç§»å‹•"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10089,23 +9943,20 @@ msgid "Instantiated scenes can't become root"
msgstr "インスタンス化ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ã¯ãƒ«ãƒ¼ãƒˆã«ã§ãã¾ã›ã‚“"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make node as Root"
-msgstr "シーンをルートã«ã™ã‚‹"
+msgstr "ノードをルートã«ã™ã‚‹"
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)?"
msgstr "ノードを削除ã—ã¾ã™ã‹?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can not perform with the root node."
-msgstr "ルートノードãŒãªã„ã¨å‡¦ç†ã§ãã¾ã›ã‚“."
+msgstr "ルートノードã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "This operation can't be done on instanced scenes."
-msgstr "ã“ã®å‡¦ç†ã«ã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹åŒ–ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ãŒå¿…è¦ã§ã™."
+msgstr "ã“ã®å‡¦ç†ã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹åŒ–ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -10128,14 +9979,12 @@ msgid "Load As Placeholder"
msgstr "プレースホルダーã¨ã—ã¦ãƒ­ãƒ¼ãƒ‰"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Local"
-msgstr "ロケール"
+msgstr "ローカルã«ã™ã‚‹"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "New Scene Root"
-msgstr "シーンをルートã«ã™ã‚‹"
+msgstr "æ–°ã—ã„シーンã®ãƒ«ãƒ¼ãƒˆ"
#: editor/scene_tree_dock.cpp
msgid "Create Root Node:"
@@ -10154,19 +10003,16 @@ msgid "User Interface"
msgstr "ユーザーインターフェース"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Other Node"
-msgstr "ノードを削除"
+msgstr "ãã®ä»–ã®ãƒŽãƒ¼ãƒ‰"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't operate on nodes from a foreign scene!"
-msgstr "ç•°ãªã‚‹ã‚·ãƒ¼ãƒ³ã®ãƒŽãƒ¼ãƒ‰ã‚’処ç†ã§ãã¾ã›ã‚“!"
+msgstr "別ã®ã‚·ãƒ¼ãƒ³ã‹ã‚‰ãƒŽãƒ¼ãƒ‰ã‚’æ“作ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“!"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't operate on nodes the current scene inherits from!"
-msgstr "ç¾åœ¨ã®ã‚·ãƒ¼ãƒ³ãŒç¶™æ‰¿ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã‚’処ç†ã§ãã¾ã›ã‚“!"
+msgstr "ç¾åœ¨ã®ã‚·ãƒ¼ãƒ³ãŒç¶™æ‰¿ã—ã¦ã„るノードをæ“作ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“!"
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
@@ -10178,20 +10024,24 @@ msgstr "ノードを除去"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Change type of node(s)"
+msgstr "出力ãƒãƒ¼ãƒˆåã®å¤‰æ›´"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
msgstr ""
-"æ–°ã—ã„シーンをä¿å­˜ã§ãã¾ã›ã‚“。ä¾å­˜é–¢ä¿‚ã®å¯¾è±¡ãŒå®Œå‚™ã•ã‚Œã¦ã„ãªã„ã¨æ€ã‚ã‚Œã¾ã™"
+"æ–°ã—ã„シーンをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãä¾å­˜é–¢ä¿‚(インスタンス)を満ãŸã™ã“"
+"ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/scene_tree_dock.cpp
msgid "Error saving scene."
msgstr "シーンをä¿å­˜ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Error duplicating scene to save it."
-msgstr "ä¿å­˜ã®ãŸã‚シーンを複製ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿ."
+msgstr "ä¿å­˜ã®ãŸã‚シーンを複製ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
#: editor/scene_tree_dock.cpp
msgid "Sub-Resources"
@@ -10202,7 +10052,6 @@ msgid "Clear Inheritance"
msgstr "継承をクリア"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "ドキュメントを開ã"
@@ -10211,20 +10060,23 @@ msgid "Add Child Node"
msgstr "å­ãƒŽãƒ¼ãƒ‰ã‚’追加"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "ã™ã¹ã¦æŠ˜ã‚ŠãŸãŸã‚€"
+msgstr "ã™ã¹ã¦å±•é–‹/折りãŸãŸã¿"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Change Type"
-msgstr "型(type)を変更"
+msgstr "型を変更"
#: editor/scene_tree_dock.cpp
msgid "Extend Script"
msgstr "スクリプトを拡張"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "親ノードを変更"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "シーンをルートã«ã™ã‚‹"
@@ -10245,18 +10097,16 @@ msgid "Delete (No Confirm)"
msgstr "削除 (確èªãªã—)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "æ–°ã—ã„ノードを追加/生æˆ"
+msgstr "æ–°ã—ã„ノードを追加/作æˆã™ã‚‹ã€‚"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid ""
"Instance a scene file as a Node. Creates an inherited scene if no root node "
"exists."
msgstr ""
-"シーンファイルをノードã¨ã—ã¦ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹åŒ–. ã‚‚ã—ルートã®ï¼¾åº¦ãŒãªã‘ã‚Œã°ã€ç¶™æ‰¿"
-"ã—ãŸã‚·ãƒ¼ãƒ³ã‚’生æˆ"
+"シーンファイルをノードã¨ã—ã¦ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã«ã—ã¾ã™ã€‚ルートノードãŒå­˜åœ¨ã—ãªã„å ´"
+"åˆã¯ã€ç¶™æ‰¿ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ã‚’作æˆã—ã¾ã™ã€‚"
#: editor/scene_tree_dock.cpp
msgid "Attach a new or existing script for the selected node."
@@ -10276,44 +10126,41 @@ msgstr "ローカル"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance? (No Undo!)"
-msgstr "継承をクリアã—ã¾ã™ã‹?(「元ã«æˆ»ã™ã€ã§ãã¾ã›ã‚“!)"
+msgstr "継承をクリアã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“!)"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Toggle Visible"
-msgstr "å¯è¦–性ã®åˆ‡ã‚Šæ›¿ãˆ"
+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
-#, fuzzy
msgid "Node configuration warning:"
msgstr "ノードã®è¨­å®šã«é–¢ã™ã‚‹è­¦å‘Š:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"ノードã«æŽ¥ç¶šã¨ã‚°ãƒ«ãƒ¼ãƒ—ãŒã‚ã‚Šã¾ã™ã€‚\n"
"クリックã§ã‚·ã‚°ãƒŠãƒ« ドックを表示。"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"ノードã«æŽ¥ç¶šãŒã‚ã‚Šã¾ã™ã€‚\n"
@@ -10322,16 +10169,15 @@ msgstr ""
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
-"ノードã¯ã‚°ãƒ«ãƒ¼ãƒ—ã«å±žã—ã¦ã„ã¾ã™.\n"
-"クリックã—ã¦ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ‰ãƒƒã‚¯ã‚’表示ã—ã¦ãã ã•ã„."
+"ノードã¯ã‚°ãƒ«ãƒ¼ãƒ—ã«å±žã—ã¦ã„ã¾ã™ã€‚\n"
+"クリックã—ã¦ã‚°ãƒ«ãƒ¼ãƒ—ドックを表示ã—ã¦ãã ã•ã„。"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "スクリプトを開ã"
+msgstr "スクリプトを開ã:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -10342,13 +10188,12 @@ msgstr ""
"クリックã—ã¦ãƒ­ãƒƒã‚¯ã‚’外ã—ã¦ãã ã•ã„。"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid ""
"Children are not selectable.\n"
"Click to make selectable."
msgstr ""
"å­ã‚’é¸æŠžã§ãã¾ã›ã‚“.\n"
-"クリックã—ã¦é¸æŠžå¯èƒ½ã«ã—ã¦ãã ã•ã„"
+"クリックã—ã¦é¸æŠžå¯èƒ½ã«ã—ã¦ãã ã•ã„。"
#: editor/scene_tree_editor.cpp
msgid "Toggle Visibility"
@@ -10375,48 +10220,40 @@ msgid "Scene Tree (Nodes):"
msgstr "シーンツリー(ノード):"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Node Configuration Warning!"
-msgstr "ノードã®è¨­å®šã«é–¢ã™ã‚‹è­¦å‘Š:"
+msgstr "ノードã®è¨­å®šã«é–¢ã™ã‚‹è­¦å‘Š!"
#: editor/scene_tree_editor.cpp
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'"
@@ -10427,46 +10264,45 @@ msgid "Error - Could not create script in filesystem."
msgstr "エラー - ファイルシステムã«ã‚¹ã‚¯ãƒªãƒ—トを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Error loading script from %s"
-msgstr "フォント読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚"
+msgstr "%s ã‹ã‚‰ã®ã‚¹ã‚¯ãƒªãƒ—トã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "上書ã"
#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
#: 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 㨠_"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "使用å¯èƒ½: a-z, A-Z, 0-9 㨠."
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -10474,14 +10310,12 @@ msgid "Built-in script (into scene file)."
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"
@@ -10504,9 +10338,8 @@ msgid "Built-in Script"
msgstr "組ã¿è¾¼ã¿ã‚¹ã‚¯ãƒªãƒ—ト"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Attach Node Script"
-msgstr "ノードã«ã‚¹ã‚¯ãƒªãƒ—トを添付ã™ã‚‹"
+msgstr "ノードスクリプトを添付ã™ã‚‹"
#: editor/script_editor_debugger.cpp
msgid "Remote "
@@ -10537,14 +10370,12 @@ msgid "Copy Error"
msgstr "エラーをコピー"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Inspect Previous Instance"
-msgstr "å‰ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®å†…容を確èª"
+msgstr "å‰ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’調ã¹ã‚‹"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Inspect Next Instance"
-msgstr "次ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã®å†…容を確èª"
+msgstr "次ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’確èªã™ã‚‹"
#: editor/script_editor_debugger.cpp
msgid "Stack Frames"
@@ -10603,7 +10434,6 @@ msgid "Clicked Control:"
msgstr "クリックã•ã‚ŒãŸã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Clicked Control Type:"
msgstr "クリックã•ã‚ŒãŸã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã®ã‚¿ã‚¤ãƒ—:"
@@ -10620,19 +10450,20 @@ msgid "Export measures as CSV"
msgstr "数値データをCSVã¨ã—ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Erase Shortcut"
-msgstr "イージング(Ease Out)"
+msgstr "ショートカットã®æ¶ˆåŽ»"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Restore Shortcut"
-msgstr "ショートカット"
+msgstr "ショートカットã®å¾©å…ƒ"
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Change Shortcut"
-msgstr "アンカーを変更"
+msgstr "ショートカットを変更"
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "エディタ設定"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
@@ -10672,58 +10503,48 @@ msgid "Change Probe Extents"
msgstr "プローブã®ç¯„囲を変更"
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Sphere Shape Radius"
-msgstr "çƒå½¢çŠ¶ã®åŠå¾„変更"
+msgstr "çƒå½¢ã®åŠå¾„を変更"
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Box Shape Extents"
-msgstr "ボックス(箱)形状ã®Extent(範囲)を変更"
+msgstr "ボックスシェイプ範囲ã®å¤‰æ›´"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Change Capsule Shape Radius"
-msgstr "カプセル形状ã®åŠå¾„変更"
+msgstr "カプセルシェイプã®åŠå¾„を変更"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Change Capsule Shape Height"
-msgstr "カプセル形状ã®é«˜ã•å¤‰æ›´"
+msgstr "カプセル形状ã®é«˜ã•ã‚’変更ã™ã‚‹"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Shape Radius"
-msgstr "カプセル形状ã®åŠå¾„変更"
+msgstr "円柱シェイプã®åŠå¾„を変更"
#: editor/spatial_editor_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Shape Height"
-msgstr "カプセル形状ã®é«˜ã•å¤‰æ›´"
+msgstr "円柱シェイプã®é«˜ã•ã‚’変更"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Ray Shape Length"
msgstr "レイシェイプã®é•·ã•ã‚’変更"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Radius"
-msgstr "å…‰æºã®åŠå¾„を変更"
+msgstr "円柱ã®åŠå¾„を変更"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Cylinder Height"
-msgstr "カプセル形状ã®é«˜ã•å¤‰æ›´"
+msgstr "円柱ã®é«˜ã•ã‚’変更"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Torus Inner Radius"
-msgstr "çƒå½¢çŠ¶ã®åŠå¾„変更"
+msgstr "トーラスã®å†…径を変更"
#: modules/csg/csg_gizmos.cpp
-#, fuzzy
msgid "Change Torus Outer Radius"
-msgstr "å…‰æºã®åŠå¾„を変更"
+msgstr "トーラスã®å¤–径を変更"
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Select the dynamic library for this entry"
@@ -10734,9 +10555,8 @@ msgid "Select dependencies of the library for this entry"
msgstr "ã“ã®ã‚¨ãƒ³ãƒˆãƒªã®ãƒ©ã‚¤ãƒ–ラリã®ä¾å­˜é–¢ä¿‚ã‚’é¸æŠžã—ã¦ãã ã•ã„"
#: modules/gdnative/gdnative_library_editor_plugin.cpp
-#, fuzzy
msgid "Remove current entry"
-msgstr "パスã®ãƒã‚¤ãƒ³ãƒˆã‚’除去"
+msgstr "ç¾åœ¨ã®ã‚¨ãƒ³ãƒˆãƒªã‚’削除ã™ã‚‹"
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Double click to create a new entry"
@@ -10767,9 +10587,8 @@ msgid "Enabled GDNative Singleton"
msgstr "有効ãªGDNative Singleton"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
-#, fuzzy
msgid "Disabled GDNative Singleton"
-msgstr "アップデートスピナーを無効化"
+msgstr "無効ãªGDNativeシングルトン"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
@@ -10788,9 +10607,8 @@ msgid "GDNative"
msgstr "GDNative"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Step argument is zero!"
-msgstr "ステップ引数ã¯ã‚¼ãƒ­ã§ã™ï¼"
+msgstr "ステップ引数ã¯ã‚¼ãƒ­ã§ã™!"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not a script with an instance"
@@ -10805,24 +10623,20 @@ msgid "Not based on a resource file"
msgstr "リソースファイルã«åŸºã¥ã„ã¦ã„ã¾ã›ã‚“"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary format (missing @path)"
-msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™ ( @path ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“)"
+msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™(@pathãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“)"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary format (can't load script at @path)"
-msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™ (@path ã§ã‚¹ã‚¯ãƒªãƒ—トを読ã¿è¾¼ã‚ã¾ã›ã‚“)"
+msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™(@path ã§ã‚¹ã‚¯ãƒªãƒ—トを読ã¿è¾¼ã‚ã¾ã›ã‚“)"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary format (invalid script at @path)"
-msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™ (@path ã§ç„¡åŠ¹ãªã‚¹ã‚¯ãƒªãƒ—ト)"
+msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸å½¢å¼ã§ã™(@path ã§ç„¡åŠ¹ãªã‚¹ã‚¯ãƒªãƒ—ト)"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸ã§ã™ (無効ãªã‚µãƒ–クラス)"
+msgstr "無効ãªã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹è¾žæ›¸ã§ã™(無効ãªã‚µãƒ–クラス)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
@@ -10909,31 +10723,28 @@ msgid "Edit Z Axis"
msgstr "Z軸を編集"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cursor Rotate X"
-msgstr "Ctrl: 回転"
+msgstr "X軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’回転"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cursor Rotate Y"
-msgstr "Ctrl: 回転"
+msgstr "Y軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’回転"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cursor Rotate Z"
-msgstr "Ctrl: 回転"
+msgstr "Z軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’回転"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cursor Back Rotate X"
-msgstr ""
+msgstr "X軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’逆回転ã•ã›ã‚‹"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cursor Back Rotate Y"
-msgstr ""
+msgstr "Y軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’逆回転ã•ã›ã‚‹"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cursor Back Rotate Z"
-msgstr ""
+msgstr "Z軸ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’逆回転ã•ã›ã‚‹"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cursor Clear Rotation"
@@ -10998,45 +10809,40 @@ msgid "Eroding walkable area..."
msgstr "移動å¯èƒ½ãªé ˜åŸŸã‚’作æˆä¸­..."
#: modules/recast/navigation_mesh_generator.cpp
-#, fuzzy
msgid "Partitioning..."
-msgstr "警告"
+msgstr "パーティションを作æˆã—ã¦ã„ã¾ã™..."
#: modules/recast/navigation_mesh_generator.cpp
-#, fuzzy
msgid "Creating contours..."
-msgstr "八分木テクスãƒãƒ£ã‚’生æˆ"
+msgstr "輪郭を作æˆã—ã¦ã„ã¾ã™..."
#: modules/recast/navigation_mesh_generator.cpp
-#, fuzzy
msgid "Creating polymesh..."
-msgstr "アウトラインメッシュを生æˆ..."
+msgstr "ãƒãƒªãƒ¡ãƒƒã‚·ãƒ¥ã‚’作æˆã—ã¦ã„ã¾ã™..."
#: modules/recast/navigation_mesh_generator.cpp
-#, fuzzy
msgid "Converting to native navigation mesh..."
-msgstr "ナビメッシュ(ナビゲーションメッシュ)ã®ç”Ÿæˆ"
+msgstr "ãƒã‚¤ãƒ†ã‚£ãƒ–ナビゲーションメッシュã«å¤‰æ›ã—ã¦ã„ã¾ã™..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Navigation Mesh Generator Setup:"
msgstr "ナビメッシュ(ナビゲーションメッシュ)生æˆè¨­å®š:"
#: modules/recast/navigation_mesh_generator.cpp
-#, fuzzy
msgid "Parsing Geometry..."
-msgstr "ジオメトリーをパース"
+msgstr "ジオメトリを解æžã—ã¦ã„ã¾ã™..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Done!"
msgstr "完了!"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid ""
"A node yielded without working memory, please read the docs on how to yield "
"properly!"
msgstr ""
-"ノードã®ãƒ¡ãƒ¢ãƒªãƒ¼ä¸è¶³ã§ã™ã€‚ノードã«é–¢ã—ã¦ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’ãŠèª­ã¿ãã ã•ã„。"
+"作業メモリãªã—ã§ãƒŽãƒ¼ãƒ‰ãŒç”Ÿæˆã•ã‚Œã¾ã—ãŸã€‚æ­£ã—ã生æˆã™ã‚‹æ–¹æ³•ã«ã¤ã„ã¦ã¯ã€ãƒ‰ã‚­ãƒ¥"
+"メントをå‚ç…§ã—ã¦ãã ã•ã„!"
#: modules/visual_script/visual_script.cpp
msgid ""
@@ -11046,18 +10852,16 @@ msgstr ""
"ノードã¯ç”Ÿæˆã—ã¾ã—ãŸãŒã€æœ€åˆã®ä½œæ¥­ãƒ¡ãƒ¢ãƒªãƒ¼ã«é–¢æ•°çŠ¶æ…‹ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid ""
"Return value must be assigned to first element of node working memory! Fix "
"your node please."
msgstr ""
-"返り値ã¯ãƒŽãƒ¼ãƒ‰ã®ãƒ¯ãƒ¼ã‚­ãƒ³ã‚°ãƒ¡ãƒ¢ãƒªãƒ¼ã§æœ€åˆã®è¦ç´ ã«ã‚¢ã‚µã‚¤ãƒ³ã•ã‚Œã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Š"
-"ã¾ã™!ノードを修正ã—ã¦ãã ã•ã„!"
+"戻り値ã¯ãƒŽãƒ¼ãƒ‰ã®ä½œæ¥­ç”¨ãƒ¡ãƒ¢ãƒªã®æœ€åˆã®è¦ç´ ã«å‰²ã‚Šå½“ã¦ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“!ノードを"
+"修正ã—ã¦ãã ã•ã„。"
#: modules/visual_script/visual_script.cpp
-#, fuzzy
msgid "Node returned an invalid sequence output: "
-msgstr "ノードã¯ä¸æ­£ãªã‚·ãƒ¼ã‚¯ã‚¨ãƒ³ã‚¹å‡ºåŠ›ã‚’è¿”ã—ã¾ã—ãŸ: "
+msgstr "ノードã¯ç„¡åŠ¹ãªã‚·ãƒ¼ã‚¯ã‚¨ãƒ³ã‚¹å‡ºåŠ›ã‚’è¿”ã—ã¾ã—ãŸ: "
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
@@ -11074,24 +10878,30 @@ msgid "Change Signal Arguments"
msgstr "シグナルã®å¼•æ•°ã‚’変更"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Argument Type"
-msgstr "é…列ã®å€¤ã®ç¨®é¡žã®å¤‰æ›´"
+msgstr "引数ã®åž‹ã®å¤‰æ›´"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Argument name"
-msgstr "入力ã®åå‰ã‚’変更"
+msgstr "引数åã®å¤‰æ›´"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Set Variable Default Value"
-msgstr "è¦å®šå€¤ã‚’変更"
+msgstr "変数ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã‚’設定ã™ã‚‹"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Set Variable Type"
-msgstr "変数を編集:"
+msgstr "変数ã®åž‹ã‚’設定"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "既存ã®çµ„è¾¼ã¿åž‹åã¨é‡è¤‡ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "æ–°è¦ãƒŽãƒ¼ãƒ‰ã‚’作æˆã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
@@ -11099,8 +10909,17 @@ msgstr "変数を作æˆ:"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
+msgid "Create a new variable."
+msgstr "æ–°è¦ãƒŽãƒ¼ãƒ‰ã‚’作æˆã€‚"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "æ–°è¦ãƒãƒªã‚´ãƒ³ã‚’生æˆã€‚"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
-msgstr "ã“ã®åå‰ã¯ä¸æ­£ãªè­˜åˆ¥å­ã§ã™:"
+msgstr "ã“ã®åå‰ã¯ç„¡åŠ¹ãªè­˜åˆ¥å­ã§ã™:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
@@ -11179,24 +10998,20 @@ msgid "Add Preload Node"
msgstr "プリロードノードを追加"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Node(s) From Tree"
-msgstr "シーンã‹ã‚‰ã®ãƒŽãƒ¼ãƒ‰"
+msgstr "ツリーã‹ã‚‰ãƒŽãƒ¼ãƒ‰ã‚’追加"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Getter Property"
-msgstr "プロパティã«getter(get method)を作る"
+msgstr "ゲッタープロパティã®è¿½åŠ "
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Setter Property"
-msgstr "プロパティã«setter(set method)を作る"
+msgstr "セッタープロパティã®è¿½åŠ "
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type"
-msgstr "型(type)を変更"
+msgstr "基本ã®åž‹ã‚’変更"
#: modules/visual_script/visual_script_editor.cpp
msgid "Move Node(s)"
@@ -11207,38 +11022,32 @@ msgid "Remove VisualScript Node"
msgstr "VisualScriptノードを除去"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Nodes"
-msgstr "ノードã«æŽ¥ç¶šã—ã¾ã™:"
+msgstr "ノードã«æŽ¥ç¶š"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Data"
-msgstr "ノードã«æŽ¥ç¶šã—ã¾ã™:"
+msgstr "ノードデータã«æŽ¥ç¶š"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Node Sequence"
-msgstr "ノードã«æŽ¥ç¶šã—ã¾ã™:"
+msgstr "ノードシーケンスã«æŽ¥ç¶š"
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
msgstr "スクリプトã«é–¢æ•° '%s'ãŒæ—¢ã«ã‚ã‚Šã¾ã™"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Input Value"
-msgstr "入力ã®åå‰ã‚’変更"
+msgstr "入力値ã®å¤‰æ›´"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "CanvasItemをリサイズ"
+msgstr "コメントã®ã‚µã‚¤ã‚ºã‚’変更ã™ã‚‹"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Can't copy the function node."
-msgstr "'..'を処ç†ã§ãã¾ã›ã‚“"
+msgstr "ファンクションノードをコピーã§ãã¾ã›ã‚“。"
#: modules/visual_script/visual_script_editor.cpp
msgid "Clipboard is empty!"
@@ -11253,14 +11062,12 @@ msgid "Remove Function"
msgstr "関数を除去"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Variable"
-msgstr "無効ãªã‚­ãƒ¼ã‚’削除"
+msgstr "変数を削除"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Editing Variable:"
-msgstr "変数を編集中:"
+msgstr "編集中ã®å¤‰æ•°:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Signal"
@@ -11271,9 +11078,8 @@ msgid "Editing Signal:"
msgstr "シグナルを接続:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Base Type:"
-msgstr "基底型(Base Type):"
+msgstr "基本タイプ:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
@@ -11284,16 +11090,14 @@ 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"
msgstr "é¸æŠžæ¸ˆã¿ã‚’削除"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Find Node Type"
msgstr "ノードタイプを探ã™"
@@ -11306,35 +11110,26 @@ msgid "Cut Nodes"
msgstr "ノードを切りå–ã‚‹"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "ノードを貼り付ã‘"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "メンãƒãƒ¼ã‚’編集"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Input type not iterable: "
-msgstr "入力ã®åž‹ãŒã€ç¹°ã‚Šè¿”ã—処ç†ã§ãã¾ã›ã‚“(not iterable): "
+msgstr "入力タイプをå復ã§ãã¾ã›ã‚“: "
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Iterator became invalid"
-msgstr "イテレーターãŒä¸æ­£ã§ã™"
+msgstr "イテレータãŒç„¡åŠ¹ã«ãªã‚Šã¾ã—ãŸ"
#: modules/visual_script/visual_script_flow_control.cpp
-#, fuzzy
msgid "Iterator became invalid: "
-msgstr "イテレーターãŒä¸æ­£ã§ã™: "
+msgstr "イテレーターãŒç„¡åŠ¹ã«ãªã‚Šã¾ã—ãŸ: "
#: modules/visual_script/visual_script_func_nodes.cpp
-#, fuzzy
msgid "Invalid index property name."
-msgstr "インデックスã®ãƒ—ロパティåãŒä¸æ­£ã§ã™."
+msgstr "インデックスプロパティåãŒç„¡åŠ¹ã§ã™ã€‚"
#: modules/visual_script/visual_script_func_nodes.cpp
-#, fuzzy
msgid "Base object is not a Node!"
msgstr "ベースオブジェクトã¯ãƒŽãƒ¼ãƒ‰ã§ã¯ã‚ã‚Šã¾ã›ã‚“!"
@@ -11344,7 +11139,6 @@ msgid "Path does not lead Node!"
msgstr "パスãŒãƒŽãƒ¼ãƒ‰ã«é”ã—ã¾ã›ã‚“!"
#: modules/visual_script/visual_script_func_nodes.cpp
-#, fuzzy
msgid "Invalid index property name '%s' in node %s."
msgstr "ノード%sã®ä¸æ­£ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ãƒ—ロパティå'%s' ."
@@ -11357,28 +11151,24 @@ msgid ": Invalid arguments: "
msgstr ": 無効ãªå¼•æ•°: "
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableGet not found in script: "
-msgstr "変数ã®get(VariableGet)ãŒã‚¹ã‚¯ãƒªãƒ—トã«ç„¡ã„: "
+msgstr "VariableGetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚ã‚Šã¾ã›ã‚“: "
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "VariableSet not found in script: "
-msgstr "変数ã®set(VariableSet)ãŒã‚¹ã‚¯ãƒªãƒ—トã«ç„¡ã„: "
+msgstr "VariableSetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚ã‚Šã¾ã›ã‚“: "
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid "Custom node has no _step() method, can't process graph."
-msgstr "カスタムノードã«_step() メソッドãŒç„¡ã„ãŸã‚ã€ã‚°ãƒ©ãƒ•ã‚’処ç†ã§ãã¾ã›ã‚“."
+msgstr "カスタムノードã«_step() メソッドãŒç„¡ã„ãŸã‚ã€ã‚°ãƒ©ãƒ•ã‚’処ç†ã§ãã¾ã›ã‚“。"
#: modules/visual_script/visual_script_nodes.cpp
-#, fuzzy
msgid ""
"Invalid return value from _step(), must be integer (seq out), or string "
"(error)."
msgstr ""
-"_step()ã®ä¸æ­£ãªè¿”り値 integer (seq out)ã¾ãŸã¯string (error)ã§ãªã„ã¨ã„ã‘ã¾ã›"
-"ã‚“."
+"_step()ã®ç„¡åŠ¹ãªæˆ»ã‚Šå€¤ã€€integer (seq out)ã¾ãŸã¯string (error)ã§ãªã„ã¨ã„ã‘ã¾ã›"
+"ん。"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
@@ -11539,18 +11329,16 @@ msgid "Could not write file:"
msgstr "ファイルを書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export:"
-msgstr "エクスãƒãƒ¼ãƒˆã™ã‚‹ãƒ†ãƒ³ãƒ—レートを開ã‘ã¾ã›ã‚“:\n"
+msgstr "エクスãƒãƒ¼ãƒˆç”¨ã®ãƒ†ãƒ³ãƒ—レートを開ã‘ã¾ã›ã‚“ã§ã—ãŸ:"
#: platform/javascript/export/export.cpp
msgid "Invalid export template:"
msgstr "無効ãªã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ テンプレート:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not read custom HTML shell:"
-msgstr "ファイルを読ã‚ã¾ã›ã‚“ã§ã—ãŸ:\n"
+msgstr "カスタムHTMLシェルを読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ:"
#: platform/javascript/export/export.cpp
msgid "Could not read boot splash image file:"
@@ -11561,9 +11349,8 @@ msgid "Using default boot splash image."
msgstr "デフォルトã®ãƒ–ートスプラッシュ画åƒã‚’使用ã—ã¾ã™ã€‚"
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package unique name."
-msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚"
+msgstr "パッケージã®ä¸€æ„ã®åå‰ãŒç„¡åŠ¹ã§ã™ã€‚"
#: platform/uwp/export/export.cpp
msgid "Invalid product GUID."
@@ -11642,7 +11429,6 @@ msgstr ""
"ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。"
#: scene/2d/collision_polygon_2d.cpp
-#, fuzzy
msgid ""
"CollisionPolygon2D only serves to provide a collision shape to a "
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
@@ -11651,23 +11437,21 @@ msgstr ""
"CollisionPolygon2D ã¯ã€CollisionObject2D 派生ノードã«è¡çªã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™ã‚‹ãŸ"
"ã‚ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚2Dã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—)を付与ã™ã‚‹ãŸã‚ã«ã¯ Area2Dã€"
"StaticBody2Dã€RigidBody2Dã€KinematicBody2D ãªã©ã®å­ã‚ªãƒ–ジェクトã¨ã—ã¦åˆ©ç”¨ã—ã¦"
-"ãã ã•ã„"
+"ãã ã•ã„。"
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "空㮠CollisionPolygon2D ã¯ã€è¡çªåˆ¤å®šã‚’æŒã¡ã¾ã›ã‚“。"
#: scene/2d/collision_shape_2d.cpp
-#, fuzzy
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
-"CollisionShape2D ã¯ã€CollisionObject2D 派生ノードã«ã‚³ãƒªã‚¸ãƒ§ãƒ³ã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™"
-"ã‚‹ãŸã‚ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚ï¼’Dã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—)を付与ã™ã‚‹ãŸã‚ã«ã¯ Area2Dã€"
-"StaticBody2Dã€RigidBody2Dã€KinematicBody2D ãªã©ã®å­ã‚ªãƒ–ジェクトã¨ã—ã¦åˆ©ç”¨ã—ã¦"
-"ãã ã•ã„."
+"CollisionShape2D ã¯ã€CollisionObject2D派生ノードã«è¡çªã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™ã‚‹å ´åˆ"
+"ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚Area2Dã€staticBody2Dã€RigidBody2Dã€KinematicBody2Dãªã©ã®å­"
+"ã¨ã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„。"
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -11738,13 +11522,12 @@ msgstr ""
"to CPUParticles\" オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
-#, fuzzy
msgid ""
"A material to process the particles is not assigned, so no behavior is "
"imprinted."
msgstr ""
-"パーティクルを処ç†ã™ã‚‹ãŸã‚ã®ãƒžãƒ†ãƒªã‚¢ãƒ«ã¯æŒ‡å®šã•ã‚Œã¦ãŠã‚‰ãšã€ãã®æŒ¯ã‚‹èˆžã„ã¯æœªæŒ‡"
-"示ã§ã™."
+"パーティクルを処ç†ã™ã‚‹ãƒžãƒ†ãƒªã‚¢ãƒ«ã¯å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€å‹•ä½œã¯ã‚¤ãƒ³ãƒ—リン"
+"トã•ã‚Œã¾ã›ã‚“。"
#: scene/2d/particles_2d.cpp
msgid ""
@@ -11792,19 +11575,16 @@ 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 派生ノードã«ã‚³ãƒªã‚¸ãƒ§ãƒ³ã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™"
-"ã‚‹ãŸã‚ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚ï¼’Dã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—)を付与ã™ã‚‹ãŸã‚ã«ã¯ Area2Dã€"
-"StaticBody2Dã€RigidBody2Dã€KinematicBody2D ãªã©ã®å­ã‚ªãƒ–ジェクトã¨ã—ã¦åˆ©ç”¨ã—ã¦"
-"ãã ã•ã„."
+"親を使用ã™ã‚‹ã‚¿ã‚¤ãƒ«ãƒžãƒƒãƒ—ã«ã¯ã€ã‚·ã‚§ã‚¤ãƒ—を指定ã™ã‚‹ã«ã¯è¦ªCollisionObjectObject2D"
+"ãŒå¿…è¦ã§ã™ã€‚Area2Dã€StaticBody2Dã€RigidBody2D〠KinematicBody2Dãªã©ã®å­ã¨ã—ã¦"
+"使用ã—ã¦ãã ã•ã„。"
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
@@ -11813,14 +11593,12 @@ msgstr ""
"é©ã§ã™ã€‚"
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCameraã¯ARVROriginノードを親ã«æŒã¤å¿…è¦ãŒã‚ã‚Šã¾ã™"
+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
msgid ""
@@ -11831,9 +11609,8 @@ msgstr ""
"コントローラã«ãƒã‚¤ãƒ³ãƒ‰ã•ã‚Œã¾ã›ã‚“。"
#: 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
msgid ""
@@ -11844,9 +11621,8 @@ msgstr ""
"ã«ãƒã‚¤ãƒ³ãƒ‰ã•ã‚Œã¾ã›ã‚“。"
#: 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%%"
@@ -11857,9 +11633,8 @@ msgid "(Time Left: %d:%02d s)"
msgstr "(Time Left: %d分%02d秒)"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Plotting Meshes: "
-msgstr "イメージをé…ç½®(Blit)"
+msgstr "メッシュã®ãƒ—ロット: "
#: scene/3d/baked_lightmap.cpp
#, fuzzy
@@ -11871,9 +11646,8 @@ msgid "Finishing Plot"
msgstr "プロット完了"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Lighting Meshes: "
-msgstr "イメージをé…ç½®(Blit)"
+msgstr "ライティングメッシュ: "
#: scene/3d/collision_object.cpp
msgid ""
@@ -11887,30 +11661,28 @@ msgstr ""
"ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。"
#: scene/3d/collision_polygon.cpp
-#, fuzzy
msgid ""
"CollisionPolygon only serves to provide a collision shape to a "
"CollisionObject derived node. Please only use it as a child of Area, "
"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
msgstr ""
-"CollisionPolygon ã¯ã€CollisionObject 派生ノードã«ã‚³ãƒªã‚¸ãƒ§ãƒ³ã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™ã‚‹"
-"ãŸã‚ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚Areaã€StaticBodyã€RigidBodyã€KinematicBody ã®å­ã¨ã—ã¦ã®"
-"ã¿åˆ©ç”¨ã—ã¦ãã ã•ã„。"
+"CollisionPolygonã¯ã€CollisionObject派生ノードã«è¡çªã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™ã‚‹å ´åˆã«ã®"
+"ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚Areaã€StaticBodyã€RigidBodyã€KinematicBodyãªã©ã®å­ã¨ã—ã¦ä½¿ç”¨ã—"
+"ã¦ãã ã•ã„。"
#: scene/3d/collision_polygon.cpp
msgid "An empty CollisionPolygon has no effect on collision."
msgstr "空㮠CollisionPolygon ã¯ã€è¡çªåˆ¤å®šã‚’æŒã¡ã¾ã›ã‚“。"
#: scene/3d/collision_shape.cpp
-#, fuzzy
msgid ""
"CollisionShape only serves to provide a collision shape to a CollisionObject "
"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
"KinematicBody, etc. to give them a shape."
msgstr ""
-"CollisionShape ã¯è¡çªç‰©ç”±æ¥ã®ãƒŽãƒ¼ãƒ‰ã«è¡çªå½¢çŠ¶ã‚’æä¾›ã™ã‚‹ã®ã«å½¹ç«‹ã¡ã¾ã™ã€‚唯一ã®"
-"彼らã«å½¢çŠ¶ã‚’与ãˆã‚‹ã“ã¨ãªã©ã‚¨ãƒªã‚¢ã€é™ãƒœãƒ‡ã‚£ã€RigidBodyã€ã‚­ãƒãƒžãƒ†ã‚£ãƒƒã‚¯ãƒœãƒ‡ã‚£ã®"
-"å­ã¨ã—ã¦ãれを使用ã—ã¦ãã ã•ã„。"
+"CollisionShapeã¯ã€CollisionObject派生ノードã«è¡çªã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™ã‚‹å ´åˆã«ã®ã¿"
+"機能ã—ã¾ã™ã€‚Areaã€StaticBodyã€RigidBodyã€KinematicBodyãªã©ã®å­ã¨ã—ã¦ä½¿ç”¨ã—ã¦"
+"ãã ã•ã„。"
#: scene/3d/collision_shape.cpp
#, fuzzy
@@ -11930,9 +11702,8 @@ msgstr ""
"ã„ã§ãã ã•ã„。"
#: scene/3d/cpu_particles.cpp
-#, fuzzy
msgid "Nothing is visible because no mesh has been assigned."
-msgstr "æ画パスã®ãŸã‚ã®ãƒ¡ãƒƒã‚·ãƒ¥ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“ã®ã§è¦‹ãˆã¾ã›ã‚“"
+msgstr "メッシュãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ä½•ã‚‚表示ã•ã‚Œã¾ã›ã‚“。"
#: scene/3d/cpu_particles.cpp
msgid ""
@@ -11943,9 +11714,8 @@ msgstr ""
"定ã•ã‚Œã¦ã„ã‚‹SpatialMaterialを使用ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
#: scene/3d/gi_probe.cpp
-#, fuzzy
msgid "Plotting Meshes"
-msgstr "イメージをé…ç½®(Blit)"
+msgstr "メッシュã®ãƒ—ロット"
#: scene/3d/gi_probe.cpp
msgid ""
@@ -11957,7 +11727,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "90度を超ãˆã‚‹è§’度ã®ã‚¹ãƒãƒƒãƒˆãƒ©ã‚¤ãƒˆã¯ã€ã‚·ãƒ£ãƒ‰ã‚¦ã‚’投影ã§ãã¾ã›ã‚“。"
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11984,10 +11754,9 @@ msgstr ""
"CPUParticles\"オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
#: scene/3d/particles.cpp
-#, fuzzy
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
-msgstr "æ画パスã®ãŸã‚ã®ãƒ¡ãƒƒã‚·ãƒ¥ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“ã®ã§è¦‹ãˆã¾ã›ã‚“"
+msgstr "æ画パスã«ãƒ¡ãƒƒã‚·ãƒ¥ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ä½•ã‚‚表示ã•ã‚Œã¾ã›ã‚“。"
#: scene/3d/particles.cpp
msgid ""
@@ -12067,12 +11836,11 @@ msgid ""
msgstr ""
#: scene/3d/world_environment.cpp
-#, fuzzy
msgid ""
"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
msgstr ""
-"WorldEnvironment ã¯ã€ã‚·ãƒ¼ãƒ³ (ã¾ãŸã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹åŒ–ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ã®ã‚»ãƒƒãƒˆ) ã”ã¨ã«"
-"1ã¤ã ã‘許å¯ã•ã‚Œã¾ã™ã€‚"
+"シーン(ã¾ãŸã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹åŒ–ã•ã‚ŒãŸã‚·ãƒ¼ãƒ³ã®ã‚»ãƒƒãƒˆ)ã”ã¨ã«è¨±å¯ã•ã‚Œã‚‹"
+"WorldEnvironmentã¯1ã¤ã ã‘ã§ã™ã€‚"
#: scene/3d/world_environment.cpp
#, fuzzy
@@ -12100,9 +11868,8 @@ msgid "Invalid animation: '%s'."
msgstr "無効ãªã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³: '%s'。"
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "'%s' ã‚’ '%s' ã«æŽ¥ç¶š"
+msgstr "ノード 'ï¼…s'ã®å…¥åŠ› 'ï¼…s'ã«æŽ¥ç¶šã•ã‚Œã¦ã„ã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“。"
#: scene/animation/animation_tree.cpp
#, fuzzy
@@ -12119,9 +11886,8 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
msgstr "AnimationPlayerã«è¨­å®šã•ã‚ŒãŸãƒ‘スã‹ã‚‰AnimationPlayerノードãŒè¾¿ã‚Œã¾ã›ã‚“。"
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "アニメーションツリーã«å•é¡ŒãŒã‚ã‚Šã¾ã™."
+msgstr "AnimationPlayerルートノードãŒæœ‰åŠ¹ãªãƒŽãƒ¼ãƒ‰ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -12137,18 +11903,16 @@ msgid "HSV"
msgstr ""
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "ヨー"
+msgstr "ロー"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
msgstr "16進数ã¨ã‚³ãƒ¼ãƒ‰å€¤ã‚’切り替ãˆã¾ã™ã€‚"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Add current color as a preset."
-msgstr "ç¾åœ¨ã®è‰²ã‚’プリセットã¨ã—ã¦è¿½åŠ "
+msgstr "ç¾åœ¨ã®è‰²ã‚’プリセットã¨ã—ã¦è¿½åŠ ã—ã¾ã™ã€‚"
#: scene/gui/container.cpp
#, fuzzy
@@ -12167,6 +11931,9 @@ 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!"
@@ -12177,20 +11944,18 @@ 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, but they will hide upon "
"running."
msgstr ""
-"ãƒãƒƒãƒ—アップã¯ã€popup() ã¾ãŸã¯ popup*() 関数ã®ã„ãšã‚Œã‹ã‚’呼ã³å‡ºã™å ´åˆã‚’除ãã€"
-"既定ã§ã¯éžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚編集ã®ãŸã‚ã«ãれらをå¯è¦–化ã™ã‚‹ã“ã¨ã¯å¯èƒ½ã§ã™ãŒã€å½¼"
-"らã¯å®Ÿè¡Œæ™‚ã«éžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚"
+"デフォルトã§ã¯ã€popup()ã¾ãŸã¯popup*()関数を呼ã³å‡ºã•ãªã„é™ã‚Šã€ãƒãƒƒãƒ—アップã¯éž"
+"表示ã«ãªã‚Šã¾ã™ã€‚編集用ã«è¡¨ç¤ºã—ã¦ã‚‚å•é¡Œã‚ã‚Šã¾ã›ã‚“ãŒã€å®Ÿè¡Œæ™‚ã«ã¯éžè¡¨ç¤ºã«ãªã‚Šã¾"
+"ã™ã€‚"
#: scene/gui/range.cpp
-#, fuzzy
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr "exp_edit ãŒtrueã®å ´åˆã€min_value ã¯0より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+msgstr "「Exp Editã€ãŒtrueã®å ´åˆã€ã€ŒMin Valueã€ã¯0より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
#: scene/gui/scroll_container.cpp
#, fuzzy
@@ -12208,13 +11973,12 @@ msgid "(Other)"
msgstr "(ãã®ä»–)"
#: scene/main/scene_tree.cpp
-#, fuzzy
msgid ""
"Default Environment as specified in Project Settings (Rendering -> "
"Environment -> Default Environment) could not be loaded."
msgstr ""
-"プロジェクトã®è¨­å®š (レンダリング-> ビューãƒãƒ¼ãƒˆ -> 既定ã®ç’°å¢ƒ) ã§æ—¢å®šã¨ã•ã‚Œã¦"
-"ã„る環境(Environment)ã¯èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ."
+"プロジェクト設定ã§æŒ‡å®šã•ã‚Œã¦ã„る既定ã®ç’°å¢ƒ (レンダリング -> 環境 -> 既定ã®ç’°"
+"境) を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚"
#: scene/main/viewport.cpp
#, fuzzy
@@ -12229,35 +11993,22 @@ msgstr ""
"ãã‚Šã¾ã™ã€‚ãれ以外ã®å ´åˆã€ãƒ¬ãƒ³ãƒ€ãƒ¼ ターゲットã—ã€ãã®å†…部ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£è¡¨ç¤ºã®ã„"
"ãã¤ã‹ã®ãƒŽãƒ¼ãƒ‰ã«å‰²ã‚Šå½“ã¦ã¾ã™ã€‚"
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "FreeType ã®åˆæœŸåŒ–エラー。"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "ä¸æ˜Žãªãƒ•ã‚©ãƒ³ãƒˆå½¢å¼ã§ã™ã€‚"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "フォント読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚"
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "入力"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "無効ãªã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã®ã‚½ãƒ¼ã‚¹ã§ã™ã€‚"
+msgstr "プレビューã®ã‚½ãƒ¼ã‚¹ãŒç„¡åŠ¹ã§ã™ã€‚"
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "無効ãªã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã®ã‚½ãƒ¼ã‚¹ã§ã™ã€‚"
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "ãã®ã‚¿ã‚¤ãƒ—ã®æ¯”較関数ã¯ç„¡åŠ¹ã§ã™ã€‚"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "関数ã¸ã®å‰²ã‚Šå½“ã¦ã€‚"
@@ -12275,6 +12026,131 @@ msgstr "Varyingã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
msgid "Constants cannot be modified."
msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
+#~ msgid "No Matches"
+#~ msgstr "一致ãªã—"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "書ã出ã—時ã«file_type_cache.cchを確èªã§ãã¾ã›ã‚“。ファイルタイプã®ã‚­ãƒ£ãƒƒ"
+#~ "シュをä¿å­˜ã§ãã¾ã›ã‚“!\n"
+#~ "ファイルタイプキャッシュをä¿å­˜ã›ãšã« file_type_cache.cch を書込ã¿ç”¨ã«é–‹ã"
+#~ "ã“ã¨ã¯ã§ãã¾ã›ã‚“ï¼"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "ファイルシステム上㧠'%s' を見ã¤ã‘られãªã„ãŸã‚移動ã§ãã¾ã›ã‚“ï¼"
+
+#~ msgid "Error loading image:"
+#~ msgstr "ç”»åƒèª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "ç”»åƒå†…ã«é€æ˜Žåº¦ãŒ128以上ã®ãƒ”クセルãŒã‚ã‚Šã¾ã›ã‚“..."
+
+#, fuzzy
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "åˆæœŸå€¤ã‚’設定ã™ã‚‹å¡—ã‚Šã¤ã¶ã—é¢ãŒã€è¦ªã«ã‚ã‚Šã¾ã›ã‚“."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "エリアをマッピングã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "é¢ã«ã‚¨ãƒªã‚¢ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“!"
+
+#~ msgid "No faces!"
+#~ msgstr "é¢ãŒã‚ã‚Šã¾ã›ã‚“!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "エラー: ファイルを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#~ msgid "Error could not load file."
+#~ msgstr "エラー:ファイルを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "ドップラーを有効ã«ã™ã‚‹"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "移動モード (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "回転モード (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "スケールモード (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "ローカル座標系"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "スナップモード (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "é¸æŠžãƒ„ール"
+
+#~ msgid "Tool Move"
+#~ msgstr "移動ツール"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "回転ツール"
+
+#~ msgid "Tool Scale"
+#~ msgstr "スケールツール"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "一覧ã«ãªã„プロジェクトをã™ã¹ã¦å‰Šé™¤ã—ã¾ã™ã‹?(フォルダã®å†…容ã¯å¤‰æ›´ã•ã‚Œã¾ã›"
+#~ "ã‚“)"
+
+#~ msgid "Project List"
+#~ msgstr "プロジェクト一覧"
+
+#~ msgid "Exit"
+#~ msgstr "終了"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "PVRTCツールを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "PVRTCツールを使用ã—ã¦å¤‰æ›ã•ã‚ŒãŸã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "FreeType ã®åˆæœŸåŒ–エラー。"
+
+#~ msgid "Unknown font format."
+#~ msgstr "ä¸æ˜Žãªãƒ•ã‚©ãƒ³ãƒˆå½¢å¼ã§ã™ã€‚"
+
+#~ msgid "Error loading font."
+#~ msgstr "フォント読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚"
+
+#~ msgid "Invalid font size."
+#~ msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚"
+
+#~ msgid "Previous Folder"
+#~ msgstr "å‰ã®ãƒ•ã‚©ãƒ«ãƒ€"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "次ã®åºŠé¢"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "スクリーンショットを自動的ã«é–‹ã"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "外部ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã‚¨ãƒ‡ã‚£ã‚¿ã§é–‹ãã¾ã™ã€‚"
+
+#~ msgid "Reverse"
+#~ msgstr "逆"
+
+#~ msgid "Mirror X"
+#~ msgstr "ミラーX"
+
+#~ msgid "Mirror Y"
+#~ msgstr "ミラーY"
+
#, fuzzy
#~ msgid "Generating solution..."
#~ msgstr "八分木テクスãƒãƒ£ã‚’生æˆ"
@@ -12889,10 +12765,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
#~ msgstr "é¸æŠžã‚’消去"
#, fuzzy
-#~ msgid "Could not find tile:"
-#~ msgstr "タイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ:"
-
-#, fuzzy
#~ msgid "Item name or ID:"
#~ msgstr "アイテムã®åå‰ã‹ID:"
@@ -13172,10 +13044,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
#~ msgstr "インフォーメーション"
#, fuzzy
-#~ msgid "Re-Import..."
-#~ msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ..."
-
-#, fuzzy
#~ msgid "No bit masks to import!"
#~ msgstr "インãƒãƒ¼ãƒˆã™ã‚‹ãƒ“ットマスクãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“!"
@@ -13654,9 +13522,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
#~ msgid "Stereo"
#~ msgstr "ステレオ音声"
-#~ msgid "Window"
-#~ msgstr "ウィンドウ"
-
#, fuzzy
#~ msgid "Scaling to %s%%."
#~ msgstr "拡大縮å°æ¯”率%s%%."
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 960bcd13b7..7129447aef 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -61,7 +61,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "თáƒáƒ•áƒ˜áƒ¡áƒ£áƒ¤áƒáƒšáƒ˜"
@@ -134,6 +133,31 @@ msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ძáƒáƒ®áƒ˜áƒšáƒ˜áƒ¡ ცვლილებá
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბური კáƒáƒ“რის დრáƒáƒ˜áƒ¡ ცვლილებáƒ"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ›áƒáƒ›áƒ•áƒšáƒáƒ‘ის შეცვლáƒ"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ცვლილებáƒ"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბური კáƒáƒ“რის მნიშვნელáƒáƒ‘ის ცვლილებáƒ"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ ძáƒáƒ®áƒ˜áƒšáƒ˜áƒ¡ ცვლილებáƒ"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "áƒáƒœáƒ˜áƒ› სიგრძის შეცვლáƒ"
@@ -654,17 +678,18 @@ msgid "Line Number:"
msgstr "ხáƒáƒ–ის ნáƒáƒ›áƒ”რი:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "შეცვლილირ%d დáƒáƒ›áƒ—ხვევები."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "áƒáƒ  áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს ტáƒáƒšáƒ˜"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "შეცვლილირ%d დáƒáƒ›áƒ—ხვევები."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "სáƒáƒ¥áƒ›áƒ˜áƒ¡ დáƒáƒ›áƒ—ხვევáƒ"
@@ -900,8 +925,7 @@ msgstr "სáƒáƒ§áƒ•áƒáƒ áƒšáƒ”ბი:"
msgid "Recent:"
msgstr "ბáƒáƒšáƒ:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1004,7 +1028,7 @@ msgstr ""
"ფáƒáƒ˜áƒšáƒ”ბი რáƒáƒ›áƒšáƒ”ბსáƒáƒª შლით სáƒáƒ­áƒ˜áƒ áƒáƒ სხვრრესურსებისთვის რáƒáƒ› იმუშáƒáƒáƒœ.\n"
"წáƒáƒ•áƒ¨áƒáƒšáƒáƒ— áƒáƒ›áƒ˜áƒ¡ მიუხედáƒáƒ•áƒáƒ“? (შეუძლებელირუკáƒáƒœ დáƒáƒ‘რუნებáƒ)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "ვერ წáƒáƒ•áƒ¨áƒšáƒ˜áƒ—:"
@@ -1042,7 +1066,7 @@ msgstr "სáƒáƒ›áƒ£áƒ“áƒáƒ›áƒáƒ“ წáƒáƒ•áƒ¨áƒáƒšáƒáƒ— %d ნივთეá
msgid "Show Dependencies"
msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებები"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "áƒáƒ‘áƒáƒšáƒ˜ რესურსების მáƒáƒ«áƒ˜áƒ”ბელი"
@@ -1131,14 +1155,16 @@ msgid "License"
msgstr "ლიცენზიáƒ"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "მესáƒáƒ›áƒ” პირის ლიზენციáƒ"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot ძრáƒáƒ•áƒ˜ დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულირმესáƒáƒ›áƒ” პირის უფáƒáƒ¡áƒ დრღირკáƒáƒ“ის ბიბლიáƒáƒ—ეკებზე, "
@@ -1159,7 +1185,8 @@ msgid "Licenses"
msgstr "ლიცენზიები"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "შეცდáƒáƒ›áƒ პáƒáƒ™áƒ”ტის გáƒáƒ®áƒ¡áƒœáƒ˜áƒ¡áƒáƒ¡, უნდრიყáƒáƒ¡ zip ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜."
#: editor/editor_asset_installer.cpp
@@ -1177,7 +1204,6 @@ msgid "Success!"
msgstr "წáƒáƒ áƒ›áƒáƒ¢áƒ”ბáƒ!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "დáƒáƒ§áƒ”ნებáƒ"
@@ -1653,12 +1679,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1722,7 +1747,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1773,7 +1798,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1798,23 +1823,30 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "წინáƒáƒ›áƒ“ებáƒáƒ áƒ” ნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to next folder."
+msgstr "მáƒáƒ›áƒ“ევნრნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "ძებნáƒ:"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2058,6 +2090,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2355,6 +2391,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "გáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2449,6 +2494,11 @@ msgstr ""
msgid "Close Tab"
msgstr "დáƒáƒ®áƒ£áƒ áƒ•áƒ"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "დáƒáƒ®áƒ£áƒ áƒ•áƒ"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2503,6 +2553,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•áƒœáƒ˜áƒ¡ მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2530,20 +2585,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2576,16 +2627,20 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2593,11 +2648,16 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები"
-#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "áƒáƒ‘áƒáƒšáƒ˜ რესურსების მáƒáƒ«áƒ˜áƒ”ბელი"
+
+#: editor/editor_node.cpp
msgid "Quit to Project List"
msgstr ""
@@ -2674,13 +2734,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ”ბი"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2695,14 +2756,6 @@ 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 ""
@@ -2723,14 +2776,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2738,12 +2791,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3016,6 +3070,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•áƒœáƒ˜áƒ¡ მრუდის ცვლილებáƒ"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3179,7 +3238,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3196,6 +3255,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3257,12 +3320,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3276,14 +3337,20 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "ვერ წáƒáƒ•áƒ¨áƒšáƒ˜áƒ—:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
-msgstr ""
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "ჩáƒáƒ¢áƒ•áƒ˜áƒ áƒ—ვის შეცდáƒáƒ›áƒ:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3369,20 +3436,12 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "სáƒáƒ§áƒ•áƒáƒ áƒšáƒ”ბი:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3415,11 +3474,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3481,6 +3540,11 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "რესურსი"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3547,6 +3611,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "შექმნáƒ"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3610,6 +3679,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3618,12 +3695,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "წáƒáƒ¨áƒšáƒ"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3636,12 +3723,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ áƒ”ბელი"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3847,7 +3935,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4612,10 +4700,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4628,14 +4712,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "ვერ წáƒáƒ•áƒ¨áƒšáƒ˜áƒ—:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4676,6 +4789,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "დáƒáƒ§áƒ”ნებáƒ"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4704,13 +4822,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4718,7 +4838,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4731,7 +4851,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4743,6 +4863,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "ძებნáƒ:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4793,31 +4918,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "შექმნáƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ გáƒáƒ¡áƒáƒ¦áƒ”ბების მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "კვáƒáƒœáƒ«áƒ—áƒáƒœ დáƒáƒ™áƒáƒ•áƒ¨áƒ˜áƒ áƒ”ბáƒ:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ გáƒáƒ¡áƒáƒ¦áƒ”ბების მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4899,6 +5028,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ცვლილებáƒ"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4929,6 +5063,7 @@ msgid "Zoom Reset"
msgstr "ზუმის დáƒáƒžáƒáƒ¢áƒáƒ áƒáƒ•áƒ”ბáƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4949,14 +5084,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "მáƒáƒ¡áƒ¨áƒ¢áƒáƒ‘ის თáƒáƒœáƒáƒ¤áƒáƒ áƒ“áƒáƒ‘áƒ:"
@@ -4981,6 +5119,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4997,11 +5136,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5014,6 +5148,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5226,16 +5365,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5552,14 +5681,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5643,19 +5764,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5987,7 +6112,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6093,11 +6217,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6126,7 +6246,7 @@ msgid "Error Importing"
msgstr "ჩáƒáƒ¢áƒ•áƒ˜áƒ áƒ—ვის შეცდáƒáƒ›áƒ:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6209,6 +6329,11 @@ msgid "Open..."
msgstr "გáƒáƒ®áƒ¡áƒœáƒ˜áƒšáƒ˜"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ áƒ”ბელი"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6246,11 +6371,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6339,6 +6464,10 @@ msgstr ""
msgid "Search Results"
msgstr "ძებნáƒ:"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6411,6 +6540,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6446,24 +6576,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "მáƒáƒ›áƒ“ევნრნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "წინáƒáƒ›áƒ“ებáƒáƒ áƒ” ნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6484,6 +6596,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•áƒœáƒ˜áƒ¡ მáƒáƒ¡áƒ¨áƒ¢áƒáƒ‘ის ცვლილებáƒ"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6500,30 +6617,33 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Go to Next Bookmark"
msgstr "მáƒáƒ›áƒ“ევნრნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr "წინáƒáƒ›áƒ“ებáƒáƒ áƒ” ნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
@@ -6537,9 +6657,24 @@ msgid "Go to Line..."
msgstr "ხáƒáƒ–ზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "მáƒáƒ›áƒ“ევნრნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "წინáƒáƒ›áƒ“ებáƒáƒ áƒ” ნáƒáƒ‘იჯზე გáƒáƒ“áƒáƒ¡áƒ•áƒšáƒ"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6715,7 +6850,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6771,8 +6910,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "áƒáƒœáƒ˜áƒ› სიგრძის შეცვლáƒ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6825,7 +6965,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6836,27 +6976,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6900,26 +7020,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6974,7 +7074,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7278,10 +7378,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7368,11 +7464,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7479,14 +7575,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7500,8 +7588,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7801,6 +7889,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7883,6 +7975,11 @@ msgid "Duplicate Nodes"
msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "წáƒáƒ¨áƒšáƒ"
@@ -7905,6 +8002,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "კვáƒáƒœáƒ«áƒ—áƒáƒœ დáƒáƒ™áƒáƒ•áƒ¨áƒ˜áƒ áƒ”ბáƒ:"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "კვáƒáƒœáƒ«áƒ—áƒáƒœ დáƒáƒ™áƒáƒ•áƒ¨áƒ˜áƒ áƒ”ბáƒ:"
@@ -7982,6 +8084,22 @@ msgid "Color uniform."
msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ áƒ“áƒáƒ¥áƒ›áƒœáƒ˜áƒ¡ ცვლილებáƒ"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7989,10 +8107,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8082,7 +8234,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8090,7 +8242,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8102,7 +8254,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8119,7 +8271,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8188,11 +8340,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8208,7 +8360,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8219,7 +8371,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8228,7 +8380,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8236,11 +8388,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8281,11 +8433,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8295,7 +8451,7 @@ msgstr "შექმნáƒ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8313,15 +8469,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8373,7 +8529,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8388,6 +8544,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8401,19 +8561,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8422,7 +8582,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8431,14 +8591,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8483,47 +8643,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8690,6 +8857,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8836,6 +9007,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8905,8 +9084,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8926,8 +9105,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8951,10 +9131,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9291,6 +9467,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9343,14 +9523,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9641,6 +9813,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9684,6 +9860,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9757,19 +9938,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9865,6 +10046,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9894,7 +10079,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10055,6 +10240,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10468,10 +10657,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "შექმნáƒ"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10658,10 +10866,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11400,22 +11604,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "უცნáƒáƒ‘ი ფáƒáƒœáƒ¢áƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "შეცდáƒáƒ›áƒ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ჩáƒáƒ¢áƒ•áƒ˜áƒ áƒ—ვისáƒáƒ¡."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11430,6 +11618,11 @@ msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
msgid "Invalid source for shader."
msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11446,6 +11639,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Unknown font format."
+#~ msgstr "უცნáƒáƒ‘ი ფáƒáƒœáƒ¢áƒ˜áƒ¡ ფáƒáƒ áƒ›áƒáƒ¢áƒ˜."
+
+#~ msgid "Error loading font."
+#~ msgstr "შეცდáƒáƒ›áƒ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ჩáƒáƒ¢áƒ•áƒ˜áƒ áƒ—ვისáƒáƒ¡."
+
+#~ msgid "Invalid font size."
+#~ msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
+
#~ msgid "Path to Node:"
#~ msgstr "გზრკვáƒáƒœáƒ«áƒáƒ›áƒ“ე:"
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index fa3b289864..dec3ae7dd8 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-07-09 10:47+0000\n"
+"PO-Revision-Date: 2019-08-04 14:23+0000\n"
"Last-Translator: 송태섭 <xotjq237@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
@@ -32,13 +32,13 @@ msgstr ""
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
msgstr ""
-"convert()하기 위한 ì¸ìˆ˜ íƒ€ìž…ì´ ìœ íš¨í•˜ì§€ 않습니다, TYPE_* ìƒìˆ˜ë¥¼ 사용하세요."
+"convert()하기 위한 ì¸ìˆ˜ íƒ€ìž…ì´ ì˜¬ë°”ë¥´ì§€ 않습니다, TYPE_* ìƒìˆ˜ë¥¼ 사용하세요."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "디코딩할 ë°”ì´íŠ¸ê°€ 모ìžë¼ê±°ë‚˜, 유효하지 ì•Šì€ í˜•ì‹ìž…니다."
+msgstr "디코딩할 ë°”ì´íŠ¸ê°€ 모ìžë¼ê±°ë‚˜, 올바르지 ì•Šì€ í˜•ì‹ìž…니다."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -50,26 +50,25 @@ msgstr "ì¸ìŠ¤í„´ìŠ¤ê°€ 비어있기 ë•Œë¬¸ì— Self를 사용할 수 없습니ë‹
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "ì—°ì‚°ìž %s, %s 그리고 %sì˜ ì—°ì‚° 대ìƒì´ 유효하지 않습니다."
+msgstr "ì—°ì‚°ìž %s, %s 그리고 %sì˜ ì—°ì‚° 대ìƒì´ 올바르지 않습니다."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr "ë² ì´ìŠ¤ 타입 %sì— ìœ íš¨í•˜ì§€ ì•Šì€ ì¸ë±ìŠ¤ 타입 %s"
+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'"
-msgstr "'%s'ì„(를) êµ¬ì„±í•˜ê¸°ì— ìœ íš¨í•˜ì§€ ì•Šì€ ì¸ìˆ˜"
+msgstr "'%s'ì„(를) êµ¬ì„±í•˜ê¸°ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ì¸ìˆ˜"
#: core/math/expression.cpp
msgid "On call to '%s':"
msgstr "'%s'ì„(를) 호출 ì‹œ:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "ìžìœ "
@@ -138,6 +137,26 @@ msgid "Anim Change Call"
msgstr "애니메ì´ì…˜ 호출 변경"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "애니메ì´ì…˜ 여러 키프레임 시간 변경"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "애니메ì´ì…˜ 여러 전환 변경"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "애니메ì´ì…˜ 여러 변형 변경"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "애니메ì´ì…˜ 여러 키프레임 ê°’ 변경"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "애니메ì´ì…˜ 여러 호출 변경"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "애니메ì´ì…˜ ê¸¸ì´ ë³€ê²½"
@@ -380,7 +399,7 @@ msgstr "베지어 트랙 추가"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr "트랙 경로가 유효하지 않습니다, 키를 추가하실 수 없습니다."
+msgstr "트랙 경로가 올바르지 않습니다, 키를 추가할 수 없습니다."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
@@ -396,7 +415,7 @@ msgstr "트랙 키 추가"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr "트랙 경로가 유효하지 않습니다, 메서드 키를 추가하실 수 없습니다."
+msgstr "트랙 경로가 올바르지 않습니다, 메서드 키를 추가할 수 없습니다."
#: editor/animation_track_editor.cpp
msgid "Add Method Track Key"
@@ -567,7 +586,7 @@ msgstr "최ì í™”"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr "유효하지 ì•Šì€ í‚¤ ì‚­ì œ"
+msgstr "올바르지 ì•Šì€ í‚¤ ì‚­ì œ"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
@@ -635,16 +654,18 @@ msgid "Line Number:"
msgstr "ë¼ì¸ 번호:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d ê°œì˜ ë°œìƒì„ êµì²´í–ˆìŠµë‹ˆë‹¤."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "ì¼ì¹˜ ê²°ê³¼ ì—†ìŒ"
+#, fuzzy
+msgid "%d match."
+msgstr "%d 개가 ì¼ì¹˜í•©ë‹ˆë‹¤."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d 회 êµì²´ë¨."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "%d 개가 ì¼ì¹˜í•©ë‹ˆë‹¤."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -704,7 +725,7 @@ msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"ëŒ€ìƒ ë©”ì„œë“œë¥¼ ì°¾ì„ ìˆ˜ 없습니다! 유효한 메서드를 지정하거나, ëŒ€ìƒ ë…¸ë“œì— ìŠ¤í¬"
+"ëŒ€ìƒ ë©”ì„œë“œë¥¼ ì°¾ì„ ìˆ˜ 없습니다! 올바른 메서드를 지정하거나, ëŒ€ìƒ ë…¸ë“œì— ìŠ¤í¬"
"립트를 붙ì´ì„¸ìš”."
#: editor/connections_dialog.cpp
@@ -792,7 +813,6 @@ msgid "Connect"
msgstr "ì—°ê²°"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "시그ë„:"
@@ -870,8 +890,7 @@ msgstr "ì¦ê²¨ì°¾ê¸°:"
msgid "Recent:"
msgstr "최근:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -938,7 +957,7 @@ msgstr "깨진 종ì†ì„± 수정"
#: editor/dependency_editor.cpp
msgid "Dependency Editor"
-msgstr "ì¢…ì† ê´€ê³„ ì—디터"
+msgstr "ì¢…ì† ê´€ê³„ 편집기"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
@@ -959,9 +978,8 @@ msgid "Owners Of:"
msgstr "소유ìž:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "프로ì íŠ¸ì—ì„œ ì„ íƒëœ 파ì¼ë“¤ì„ 삭제하시겠습니까? (ë˜ëŒë¦¬ê¸° 불가)"
+msgstr "프로ì íŠ¸ì—ì„œ ì„ íƒí•œ 파ì¼ì„ 삭제하시겠습니까? (ë˜ëŒë¦¬ê¸° 불가)"
#: editor/dependency_editor.cpp
msgid ""
@@ -972,7 +990,7 @@ msgstr ""
"삭제하려고 하는 파ì¼ë“¤ì€ 다른 ë¦¬ì†ŒìŠ¤ë“¤ì´ ì •ìƒë™ìž‘하기 위해 필요합니다.\n"
"ì •ë§ë¡œ 삭제하시겠습니까? (ë˜ëŒë¦¬ê¸° 불가)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "삭제할 수 없습니다:"
@@ -1008,7 +1026,7 @@ msgstr "%dê°œ í•­ëª©ì„ ì˜êµ¬ì ìœ¼ë¡œ 삭제하시겠습니까? (ë˜ëŒë¦¬ê¸°
msgid "Show Dependencies"
msgstr "ì¢…ì† ê´€ê³„ ë³´ì´ê¸°"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "미사용 리소스 íƒìƒ‰ê¸°"
@@ -1097,14 +1115,16 @@ msgid "License"
msgstr "ë¼ì´ì„ ìŠ¤"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "서드파티 ë¼ì´ì„ ìŠ¤"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engineì€ MIT ë¼ì´ì„ ìŠ¤ì™€ 호환ë˜ëŠ” ìˆ˜ë§Žì€ ì„œë“œíŒŒí‹° ìžìœ  오픈소스 ë¼ì´ë¸ŒëŸ¬"
@@ -1124,12 +1144,13 @@ msgid "Licenses"
msgstr "ë¼ì´ì„ ìŠ¤"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "패키지 파ì¼ì„ 여는 ë° ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. zip 형ì‹ì´ 아닙니다."
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
-msgstr "ì—ì…‹ 압축해제"
+msgstr "애셋 압축해제"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1141,7 +1162,6 @@ msgid "Success!"
msgstr "성공!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "설치"
@@ -1318,11 +1338,11 @@ msgstr "새로운 버스 ë ˆì´ì•„ì›ƒì„ ë§Œë“­ë‹ˆë‹¤."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr "유효하지 ì•Šì€ ì´ë¦„."
+msgstr "올바르지 ì•Šì€ ì´ë¦„."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
-msgstr "유효한 문ìž:"
+msgstr "올바른 문ìž:"
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing engine class name."
@@ -1511,18 +1531,20 @@ msgstr "í…œí”Œë¦¿ì„ ì°¾ì„ ìˆ˜ 없습니다:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"32 비트 환경ì—ì„œ ë‚´ìž¥ëœ PCK를 내보내려면 4 GiB(기가 ì´ì§„ ë°”ì´íŠ¸)보다 작아야 "
+"합니다."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
-msgstr "3D ì—디터"
+msgstr "3D 편집기"
#: editor/editor_feature_profile.cpp
msgid "Script Editor"
-msgstr "스í¬ë¦½íŠ¸ ì—디터"
+msgstr "스í¬ë¦½íŠ¸ 편집기"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr "ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬"
+msgstr "ì• ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -1554,7 +1576,7 @@ msgstr "ì´ ì´ë¦„ì„ ê°€ì§„ í”„ë¡œí•„ì´ ì´ë¯¸ 존재합니다."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr "(ì—디터 비활성화ë¨, ì†ì„± 비활성화ë¨)"
+msgstr "(편집기 비활성화ë¨, ì†ì„± 비활성화ë¨)"
#: editor/editor_feature_profile.cpp
msgid "(Properties Disabled)"
@@ -1562,7 +1584,7 @@ msgstr "(ì†ì„± 비활성화ë¨)"
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled)"
-msgstr "(ì—디터 비활성화ë¨)"
+msgstr "(편집기 비활성화ë¨)"
#: editor/editor_feature_profile.cpp
msgid "Class Options:"
@@ -1570,7 +1592,7 @@ msgstr "í´ëž˜ìŠ¤ 옵션:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
-msgstr "컨í…스트 ì—디터 활성화"
+msgstr "컨í…스트 편집기 활성화"
#: editor/editor_feature_profile.cpp
msgid "Enabled Properties:"
@@ -1618,12 +1640,11 @@ msgid "New"
msgstr "새 것"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "가져오기"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "내보내기"
@@ -1653,7 +1674,7 @@ msgstr "프로필 내보내기"
#: editor/editor_feature_profile.cpp
msgid "Manage Editor Feature Profiles"
-msgstr "ì—디터 기능 프로필 관리"
+msgstr "편집기 기능 프로필 관리"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1684,7 +1705,7 @@ msgstr "íŒŒì¼ íƒìƒ‰ê¸°ì—ì„œ 보기"
msgid "New Folder..."
msgstr "새 í´ë”..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "새로고침"
@@ -1735,7 +1756,7 @@ msgstr "앞으로 가기"
msgid "Go Up"
msgstr "위로 가기"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "숨김 íŒŒì¼ í† ê¸€"
@@ -1760,24 +1781,28 @@ msgid "Move Favorite Down"
msgstr "ì¦ê²¨ì°¾ê¸° 아래로 ì´ë™"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "ì´ì „ í´ë”"
+msgid "Go to previous folder."
+msgstr "ì´ì „ í´ë”ë¡œ ì´ë™í•©ë‹ˆë‹¤."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "ë‹¤ìŒ í´ë”"
+msgid "Go to next folder."
+msgstr "ë‹¤ìŒ í´ë”ë¡œ ì´ë™í•©ë‹ˆë‹¤."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "부모 í´ë”ë¡œ ì´ë™í•©ë‹ˆë‹¤."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "파ì¼ì„ 새로고침합니다."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "현재 í´ë”를 ì¦ê²¨ì°¾ê¸° (안) 합니다."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
-msgstr "숨김 íŒŒì¼ ê°€ì‹œì„± 토글하기."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "ê°ì¶˜ 파ì¼ì˜ 표시 여부 토글하기."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1803,7 +1828,7 @@ msgstr "파ì¼:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Must use a valid extension."
-msgstr "유효한 확장ìžë¥¼ 사용해야 합니다."
+msgstr "올바른 확장ìžë¥¼ 사용해야 합니다."
#: editor/editor_file_system.cpp
msgid "ScanSources"
@@ -1819,7 +1844,7 @@ msgstr ""
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr "ì—ì…‹ (다시) 가져오기"
+msgstr "애셋 (다시) 가져오기"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
@@ -1883,7 +1908,7 @@ msgstr "ì´ë„˜ "
#: editor/editor_help.cpp
msgid "Constants"
-msgstr "ìƒìˆ˜"
+msgstr "ìƒìˆ˜(Constant)"
#: editor/editor_help.cpp
msgid "Constants:"
@@ -2018,6 +2043,11 @@ msgstr "지우기"
msgid "Clear Output"
msgstr "출력 지우기"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "윈ë„ìš°"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "프로ì íŠ¸ 내보내기가 오류 코드 %d ë¡œ 실패했습니다."
@@ -2137,7 +2167,7 @@ msgstr "ë ˆì´ì•„웃 저장 ì‹œë„ ì¤‘ 오류!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr "ì—디터 기본 ë ˆì´ì•„ì›ƒì´ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
+msgstr "편집기 기본 ë ˆì´ì•„ì›ƒì´ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2304,7 +2334,7 @@ msgstr "종료"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr "ì—디터를 종료하시겠습니까?"
+msgstr "편집기를 종료하시겠습니까?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
@@ -2335,6 +2365,15 @@ msgid "Pick a Main Scene"
msgstr "ë©”ì¸ ì”¬ ì„ íƒ"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "씬 닫기"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "씬 닫기"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "애드온 플러그ì¸ì„ 활성화할 수 없습니다: '%s' 구성 구문 ë¶„ì„ ì‹¤íŒ¨."
@@ -2444,6 +2483,11 @@ msgstr "ì´ ì”¬ì„ ì‹¤í–‰"
msgid "Close Tab"
msgstr "탭 닫기"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "탭 닫기"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "다른 탭 닫기"
@@ -2497,6 +2541,10 @@ msgid "Go to previously opened scene."
msgstr "ì´ì „ì— ì—´ì—ˆë˜ ì”¬ìœ¼ë¡œ 가기."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "ë¬¸ìž ë³µì‚¬"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "ë‹¤ìŒ íƒ­"
@@ -2524,6 +2572,10 @@ msgstr "새 ìƒì† 씬..."
msgid "Open Scene..."
msgstr "씬 열기..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "최근 ì—´ì—ˆë˜ í•­ëª©"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "씬 저장"
@@ -2533,14 +2585,6 @@ msgid "Save All Scenes"
msgstr "모든 씬 저장"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "씬 닫기"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "최근 ì—´ì—ˆë˜ í•­ëª©"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "변환..."
@@ -2570,25 +2614,36 @@ msgstr "씬 ë˜ëŒë¦¬ê¸°"
msgid "Miscellaneous project or scene-wide tools."
msgstr "프로ì íŠ¸ ë˜ëŠ” 씬 관련 여러가지 ë„구들."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "프로ì íŠ¸"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "프로ì íŠ¸ 설정"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ë„구"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "내보내기..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "안드로ì´ë“œ 빌드 템플릿 설치하기"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "프로ì íŠ¸ ë°ì´í„° í´ë” 열기"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ë„구"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "안드로ì´ë“œ 빌드 템플릿 설치하기"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "미사용 리소스 íƒìƒ‰ê¸°"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2626,7 +2681,7 @@ msgid ""
msgstr ""
"ì´ ì˜µì…˜ì´ í™œì„±í™” ë˜ì–´ ìžˆì„ ê²½ìš°, 내보내기나 ë°°í¬ëŠ” ìµœì†Œí•œì˜ ì‹¤í–‰ 파ì¼ì„ ìƒì„±"
"합니다.\n"
-"íŒŒì¼ ì‹œìŠ¤í…œì€ ë„¤íŠ¸ì›Œí¬ë¥¼ 통해서 ì—디터 ìƒì˜ 프로ì íŠ¸ê°€ 제공합니다.\n"
+"íŒŒì¼ ì‹œìŠ¤í…œì€ ë„¤íŠ¸ì›Œí¬ë¥¼ 통해서 편집기 ìƒì˜ 프로ì íŠ¸ê°€ 제공합니다.\n"
"안드로ì´ë“œì˜ 경우, USB ì¼€ì´ë¸”ì„ ì‚¬ìš©í•˜ì—¬ ë°°í¬í•  경우 ë” ë¹ ë¥¸ í¼í¬ë¨¼ìŠ¤ë¥¼ 제공"
"합니다. ì´ ì˜µì…˜ì€ í° ì„¤ì¹˜ ìš©ëŸ‰ì„ ìš”êµ¬í•˜ëŠ” ê²Œìž„ì˜ í…ŒìŠ¤íŠ¸ë¥¼ 빠르게 í•  수 있습니"
"다."
@@ -2666,7 +2721,7 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
-"ì´ ì˜µì…˜ì´ í™œì„±í™” ë˜ì–´ ìžˆì„ ê²½ìš°, ì—디터 ìƒì˜ ì”¬ì˜ ë³€ê²½ì‚¬í•­ì´ ì‹¤í–‰ ì¤‘ì¸ ê²Œìž„"
+"ì´ ì˜µì…˜ì´ í™œì„±í™” ë˜ì–´ ìžˆì„ ê²½ìš°, 편집기 ìƒì˜ ì”¬ì˜ ë³€ê²½ì‚¬í•­ì´ ì‹¤í–‰ ì¤‘ì¸ ê²Œìž„"
"ì— ë°˜ì˜ë©ë‹ˆë‹¤.\n"
"ê¸°ê¸°ì— ì›ê²©ìœ¼ë¡œ 사용ë˜ëŠ” 경우, ë„¤íŠ¸ì›Œí¬ íŒŒì¼ ì‹œìŠ¤í…œê³¼ 함께하면 ë”ìš± 효과ì ìž…"
"니다."
@@ -2687,17 +2742,18 @@ msgstr ""
"ê¸°ê¸°ì— ì›ê²©ìœ¼ë¡œ 사용ë˜ëŠ” 경우, ë„¤íŠ¸ì›Œí¬ íŒŒì¼ ì‹œìŠ¤í…œê³¼ 함께하면 ë”ìš± 효과ì ìž…"
"니다."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr "ì—디터"
+msgstr "편집기"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr "ì—디터 설정"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "편집기 설정"
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr "ì—디터 ë ˆì´ì•„웃"
+msgstr "편집기 ë ˆì´ì•„웃"
#: editor/editor_node.cpp
msgid "Take Screenshot"
@@ -2708,14 +2764,6 @@ 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 "전체 화면 토글"
@@ -2725,25 +2773,27 @@ msgstr "시스템 콘솔 토글"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
-msgstr "ì—디터 ë°ì´í„°/설정 í´ë” 열기"
+msgstr "편집기 ë°ì´í„°/설정 í´ë” 열기"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr "ì—디터 ë°ì´í„° í´ë” 열기"
+msgstr "편집기 ë°ì´í„° í´ë” 열기"
#: editor/editor_node.cpp
msgid "Open Editor Settings Folder"
-msgstr "ì—디터 설정 í´ë” 열기"
+msgstr "편집기 설정 í´ë” 열기"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr "ì—디터 기능 관리"
+#, fuzzy
+msgid "Manage Editor Features..."
+msgstr "편집기 기능 관리"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "내보내기 템플릿 관리"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "ë„움ë§"
@@ -2751,12 +2801,13 @@ msgstr "ë„움ë§"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "검색"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "온ë¼ì¸ 문서"
@@ -2818,7 +2869,7 @@ msgstr "커스텀 씬 실행"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr "비디오 ë“œë¼ì´ë²„를 변경하려면 ì—디터를 다시 시작해야 합니다."
+msgstr "비디오 ë“œë¼ì´ë²„를 변경하려면 편집기를 다시 시작해야 합니다."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
@@ -2827,7 +2878,7 @@ msgstr "저장 & 다시 시작"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr "ì—디터 윈ë„ìš°ê°€ 다시 그려질 ë•Œ 회전합니다."
+msgstr "편집기 ì°½ì´ ë‹¤ì‹œ 그려질 ë•Œ 회전합니다."
#: editor/editor_node.cpp
msgid "Update Continuously"
@@ -2929,27 +2980,27 @@ msgstr "ì„ íƒ"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr "2D ì—디터 열기"
+msgstr "2D 편집기 열기"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr "3D ì—디터 열기"
+msgstr "3D 편집기 열기"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "스í¬ë¦½íŠ¸ ì—디터 열기"
+msgstr "스í¬ë¦½íŠ¸ 편집기 열기"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
-msgstr "ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ 열기"
+msgstr "ì• ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ 열기"
#: editor/editor_node.cpp
msgid "Open the next Editor"
-msgstr "ë‹¤ìŒ ì—디터 열기"
+msgstr "ë‹¤ìŒ íŽ¸ì§‘ê¸° 열기"
#: editor/editor_node.cpp
msgid "Open the previous Editor"
-msgstr "ì´ì „ ì—디터 열기"
+msgstr "ì´ì „ 편집기 열기"
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
@@ -3033,6 +3084,10 @@ msgstr "시간"
msgid "Calls"
msgstr "호출"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "ë¬¸ìž íŽ¸ì§‘:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "사용"
@@ -3055,7 +3110,7 @@ msgstr "지정하기..."
#: editor/editor_properties.cpp
msgid "Invalid RID"
-msgstr "유효하지 ì•Šì€ RID"
+msgstr "올바르지 ì•Šì€ RID"
#: editor/editor_properties.cpp
msgid ""
@@ -3122,7 +3177,7 @@ msgstr "%s로 변환"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Open Editor"
-msgstr "ì—디터 열기"
+msgstr "편집기 열기"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
@@ -3202,7 +3257,8 @@ msgid "Import From Node:"
msgstr "노드ì—ì„œ 가져오기:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "다시 다운로드"
#: editor/export_template_manager.cpp
@@ -3219,6 +3275,10 @@ msgid "Download"
msgstr "다운로드"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(누ë½)"
@@ -3240,7 +3300,7 @@ msgstr "내보내기 템플릿 zip 파ì¼ì„ ì—´ 수 없습니다."
#: editor/export_template_manager.cpp
msgid "Invalid version.txt format inside templates: %s."
-msgstr "템플릿 ì•ˆì— version.txtê°€ 유효하지 ì•Šì€ í˜•ì‹ìž…니다: %s."
+msgstr "템플릿 안 version.txtê°€ 올바르지 ì•Šì€ í˜•ì‹ìž…니다: %s."
#: editor/export_template_manager.cpp
msgid "No version.txt found inside templates."
@@ -3282,12 +3342,10 @@ msgid "No response."
msgstr "ì‘답 ì—†ìŒ."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "요청 실패."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "리다ì´ë ‰íŠ¸ 루프."
@@ -3301,15 +3359,22 @@ msgid "Download Complete."
msgstr "다운로드 완료."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "테마를 파ì¼ë¡œ 저장할 수 없습니다:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"템플릿 ì„¤ì¹˜ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. 문제가 있는 템플릿 ì•„ì¹´ì´ë¸ŒëŠ” '%s' ì—ì„œ 확ì¸í•˜ì‹¤ "
"수 있습니다."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "url 요청 오류: "
#: editor/export_template_manager.cpp
@@ -3394,19 +3459,11 @@ msgstr "템플릿 다운로드"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "목ë¡ì—ì„œ 미러를 ì„ íƒí•˜ì„¸ìš”: (Shift+í´ë¦­: 브ë¼ìš°ì €ì—ì„œ 열기)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr "file_type_cache.cch를 열수 없어서, íŒŒì¼ íƒ€ìž… ìºì‰¬ë¥¼ 저장하지 않습니다!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "ì¦ê²¨ì°¾ê¸°"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "íŒŒì¼ ì‹œìŠ¤í…œì—ì„œ '%s'ì„(를) ì°¾ì„ ìˆ˜ 없습니다!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"ìƒíƒœ: íŒŒì¼ ê°€ì ¸ì˜¤ê¸° 실패. 파ì¼ì„ 수정하고 \"다시 가져오기\"를 수행하세요."
@@ -3437,17 +3494,17 @@ msgstr "ì´ë¦„ì´ ì œê³µë˜ì§€ 않았습니다."
#: editor/filesystem_dock.cpp
msgid "Provided name contains invalid characters."
-msgstr "ì œê³µëœ ì´ë¦„ì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžê°€ 있습니다."
-
-#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "ì´ë¦„ì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžê°€ 있습니다."
+msgstr "ì œê³µëœ ì´ë¦„ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ë¬¸ìžê°€ 있습니다."
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "파ì¼ì´ë‚˜ í´ë”ê°€ 해당 ì´ë¦„ì„ ì‚¬ìš©ì¤‘ìž…ë‹ˆë‹¤."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "ì´ë¦„ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ë¬¸ìžê°€ 있습니다."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "파ì¼ëª… 변경:"
@@ -3503,6 +3560,11 @@ msgstr "복제..."
msgid "Move To..."
msgstr "ì´ë™..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "새 씬"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "새 스í¬ë¦½íŠ¸..."
@@ -3568,6 +3630,11 @@ msgstr "ê°™ì€ ì´ë¦„ì˜ íŒŒì¼ì´ë‚˜ í´ë”ê°€ ì´ë¯¸ 존재합니다."
msgid "Overwrite"
msgstr "ë®ì–´ 쓰기"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "씬으로부터 만들기"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "스í¬ë¦½íŠ¸ 만들기"
@@ -3630,6 +3697,14 @@ msgid "Search complete"
msgstr "검색 완료"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "ê·¸ë£¹ì— ì¶”ê°€"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "그룹ì—ì„œ ì‚­ì œ"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "그룹 ì´ë¦„ì´ ì´ë¯¸ 존재합니다."
@@ -3637,12 +3712,23 @@ msgstr "그룹 ì´ë¦„ì´ ì´ë¯¸ 존재합니다."
msgid "Invalid group name."
msgstr "그룹 ì´ë¦„ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "그룹 관리"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "ì´ë¯¸ì§€ 그룹 ì‚­ì œ"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "그룹"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "ê·¸ë£¹ì— ìžˆì§€ ì•Šì€ ë…¸ë“œ"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3655,12 +3741,12 @@ msgid "Nodes in Group"
msgstr "ê·¸ë£¹ì— ìžˆëŠ” 노드"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "ê·¸ë£¹ì— ì¶”ê°€"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "그룹ì—ì„œ ì‚­ì œ"
+msgid "Group Editor"
+msgstr "그룹 편집기"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3734,7 +3820,7 @@ msgstr "가져오기 후 실행할 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 없습니다:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
msgstr ""
-"가져오기 후 실행할 스í¬ë¦½íŠ¸ê°€ 유효하지 않거나 깨져 있습니다 (콘솔 확ì¸):"
+"가져오기 후 실행할 스í¬ë¦½íŠ¸ê°€ 올바르지 않거나 깨져 있습니다 (콘솔 확ì¸):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
@@ -3774,13 +3860,13 @@ msgstr "씬 저장, 다시 가져오기 ë° ë‹¤ì‹œ 시작"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
-msgstr "가져온 파ì¼ì˜ íƒ€ìž…ì„ ë³€ê²½í•˜ë ¤ë©´ ì—디터를 다시 시작해야 합니다."
+msgstr "가져온 파ì¼ì˜ íƒ€ìž…ì„ ë³€ê²½í•˜ë ¤ë©´ 편집기를 다시 시작해야 합니다."
#: editor/import_dock.cpp
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
-"경고: ì´ ë¦¬ì†ŒìŠ¤ë¥¼ 사용하는 ì—ì…‹ì´ ì¡´ìž¬í•©ë‹ˆë‹¤, ì—ì…‹ì„ ë¶ˆëŸ¬ì˜¤ì§€ 못할 수 있습니"
+"경고: ì´ ë¦¬ì†ŒìŠ¤ë¥¼ 사용하는 ì• ì…‹ì´ ì¡´ìž¬í•©ë‹ˆë‹¤, ì• ì…‹ì„ ë¶ˆëŸ¬ì˜¤ì§€ 못할 수 있습니"
"다."
#: editor/inspector_dock.cpp
@@ -3869,7 +3955,8 @@ msgid "MultiNode Set"
msgstr "다중 노드 설정"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "시그ë„ê³¼ ê·¸ë£¹ì„ íŽ¸ì§‘í•  노드를 ì„ íƒí•˜ì„¸ìš”."
#: editor/plugin_config_dialog.cpp
@@ -4110,7 +4197,7 @@ msgstr "노드 ì´ë™ë¨"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
-msgstr "ì—°ê²°í•  수 없습니다, í¬íŠ¸ê°€ 사용 중ì´ê±°ë‚˜ 유효하지 않는 연결입니다."
+msgstr "ì—°ê²°í•  수 없습니다, í¬íŠ¸ê°€ 사용 중ì´ê±°ë‚˜ 올바르지 않는 연결입니다."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4151,7 +4238,7 @@ msgstr "설정한 애니메ì´ì…˜ 플레ì´ì–´ê°€ 없습니다, 트랙 ì´ë¦„ì„
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
msgstr ""
-"유효하지 않는 플레ì´ì–´ 경로 설정입니다, 트랙 ì´ë¦„ì„ ê²€ìƒ‰í•  수 없습니다."
+"올바르지 않는 플레ì´ì–´ 경로 설정입니다, 트랙 ì´ë¦„ì„ ê²€ìƒ‰í•  수 없습니다."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4159,7 +4246,7 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
-"애니메ì´ì…˜ 플레ì´ì–´ê°€ 유효한 루트 노드 경로를 가지고 있지 않습니다, 트랙 ì´ë¦„"
+"애니메ì´ì…˜ 플레ì´ì–´ê°€ 올바른 루트 노드 경로를 가지고 있지 않습니다, 트랙 ì´ë¦„"
"ì„ ê²€ìƒ‰í•  수 없습니다."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -4208,7 +4295,7 @@ msgstr "애니메ì´ì…˜ ì‚­ì œ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Invalid animation name!"
-msgstr "유효하지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜ ì´ë¦„!"
+msgstr "올바르지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜ ì´ë¦„!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation name already exists!"
@@ -4562,11 +4649,11 @@ msgstr "입력 삭제"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is valid."
-msgstr "애니메ì´ì…˜ 트리가 유효합니다."
+msgstr "애니메ì´ì…˜ 트리가 올바릅니다."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is invalid."
-msgstr "애니메ì´ì…˜ 트리가 유효하지 않습니다."
+msgstr "애니메ì´ì…˜ 트리가 올바르지 않습니다."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation Node"
@@ -4625,10 +4712,6 @@ msgid "View Files"
msgstr "íŒŒì¼ ë³´ê¸°"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "í˜¸ìŠ¤íŠ¸ëª…ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "ì—°ê²° 오류, 다시 ì‹œë„í•´ 주세요."
@@ -4641,14 +4724,47 @@ msgid "No response from host:"
msgstr "호스트로부터 ì‘답 ì—†ìŒ:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "í˜¸ìŠ¤íŠ¸ëª…ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "요청 실패, 리턴 코드:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "요청 실패."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "테마를 파ì¼ë¡œ 저장할 수 없습니다:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "너무 ë§Žì€ ë¦¬ë‹¤ì´ë ‰íŠ¸ë¡œ, 요청 실패"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "리다ì´ë ‰íŠ¸ 루프."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "요청 실패, 리턴 코드:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "시간"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "ìž˜ëª»ëœ ë‹¤ìš´ë¡œë“œ í•´ì‹œ, 파ì¼ì´ ë³€ê²½ëœ ê²ƒìœ¼ë¡œ 보입니다."
@@ -4666,7 +4782,7 @@ msgstr "sha256 í•´ì‹œ í™•ì¸ ì‹¤íŒ¨"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
-msgstr "ì—ì…‹ 다운로드 오류:"
+msgstr "애셋 다운로드 오류:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Downloading (%s / %s)..."
@@ -4689,6 +4805,10 @@ msgid "Idle"
msgstr "대기"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "설치하기..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "다시 ì‹œë„"
@@ -4698,7 +4818,7 @@ msgstr "다운로드 오류"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download for this asset is already in progress!"
-msgstr "ì´ ì—ì…‹ì˜ ë‹¤ìš´ë¡œë“œê°€ ì´ë¯¸ 진행중입니다!"
+msgstr "ì´ ì• ì…‹ì˜ ë‹¤ìš´ë¡œë“œê°€ ì´ë¯¸ 진행중입니다!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "First"
@@ -4717,13 +4837,17 @@ msgid "Last"
msgstr "ë으로"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "모ë‘"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "다시 가져오기..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "플러그ì¸"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4731,8 +4855,8 @@ msgid "Sort:"
msgstr "ì •ë ¬:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "뒤집기"
+msgid "Reverse sorting."
+msgstr "역순 정렬."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4744,7 +4868,8 @@ msgid "Site:"
msgstr "사ì´íŠ¸:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "지ì›..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4756,8 +4881,13 @@ msgid "Testing"
msgstr "테스팅"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "불러오기..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
-msgstr "ì—ì…‹ ZIP 파ì¼"
+msgstr "ì• ì…‹ ZIP 파ì¼"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -4811,32 +4941,32 @@ msgid "Rotation Step:"
msgstr "회전 스í…:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "세로 ê°€ì´ë“œ ì´ë™"
+msgid "Move Vertical Guide"
+msgstr "ìˆ˜ì§ ê°€ì´ë“œ ì´ë™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "새로운 세로 ê°€ì´ë“œ 만들기"
+msgid "Create Vertical Guide"
+msgstr "ìˆ˜ì§ ê°€ì´ë“œ 만들기"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "세로 ê°€ì´ë“œ ì‚­ì œ"
+msgid "Remove Vertical Guide"
+msgstr "ìˆ˜ì§ ê°€ì´ë“œ ì‚­ì œ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "가로 ê°€ì´ë“œ ì´ë™"
+msgid "Move Horizontal Guide"
+msgstr "ìˆ˜í‰ ê°€ì´ë“œ ì´ë™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "새로운 가로 ê°€ì´ë“œ 만들기"
+msgid "Create Horizontal Guide"
+msgstr "ìˆ˜í‰ ê°€ì´ë“œ 만들기"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "가로 ê°€ì´ë“œ ì‚­ì œ"
+msgid "Remove Horizontal Guide"
+msgstr "ìˆ˜í‰ ê°€ì´ë“œ ì‚­ì œ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "새 가로 세로 ê°€ì´ë“œ 만들기"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "ìˆ˜í‰ ë° ìˆ˜ì§ ê°€ì´ë“œ 만들기"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4915,6 +5045,11 @@ msgid "Paste Pose"
msgstr "í¬ì¦ˆ 붙여넣기"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "본 지우기"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "노드ì—ì„œ 커스텀 본 만들기"
@@ -4943,6 +5078,7 @@ msgid "Zoom Reset"
msgstr "배율 초기화"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "ì„ íƒ ëª¨ë“œ"
@@ -4963,14 +5099,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "알트+ìš°í´ë¦­: 겹친 ëª©ë¡ ì„ íƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "ì´ë™ 모드"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "회전 모드"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "규모 모드"
@@ -4996,6 +5135,7 @@ msgid "Toggle snapping."
msgstr "스냅 토글."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "스냅 사용"
@@ -5012,11 +5152,6 @@ msgid "Use Rotation Snap"
msgstr "회전 스냅 사용"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "스냅 설정..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "ìƒëŒ€ì ì¸ 스냅"
@@ -5029,6 +5164,11 @@ msgid "Smart Snapping"
msgstr "스마트 스냅"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "스냅 설정..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "ë¶€ëª¨ì— ìŠ¤ëƒ…"
@@ -5241,16 +5381,6 @@ msgstr "핸들 설정"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "ì´ë¯¸ì§€ 불러오기 오류:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "ì´ë¯¸ì§€ì— 투명ë„ê°€ 128보다 í° í”½ì…€ì´ ì—†ìŠµë‹ˆë‹¤..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "ì—미션 ë§ˆìŠ¤í¬ ë¶ˆëŸ¬ì˜¤ê¸°"
@@ -5388,7 +5518,7 @@ msgstr "항목"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item List Editor"
-msgstr "항목 ëª©ë¡ ì—디터"
+msgstr "항목 ëª©ë¡ íŽ¸ì§‘ê¸°"
#: editor/plugins/light_occluder_2d_editor_plugin.cpp
msgid "Create Occluder Polygon"
@@ -5534,15 +5664,15 @@ msgstr "소스 메시가 지정ë˜ì§€ 않았습니다 (그리고 MultiMeshì— ë©
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
-msgstr "소스 메시가 유효하지 않습니다 (유효하지 ì•Šì€ ê²½ë¡œ)."
+msgstr "소스 메시가 올바르지 않습니다 (올바르지 ì•Šì€ ê²½ë¡œ)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
-msgstr "소스 메시가 유효하지 않습니다 (MeshInstance가 아닙니다)."
+msgstr "소스 메시가 올바르지 않습니다 (MeshInstance가 아닙니다)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (contains no Mesh resource)."
-msgstr "소스 메시가 유효하지 않습니다 (메시 리소스가 없습니다)."
+msgstr "소스 메시가 올바르지 않습니다 (Mesh 리소스가 없습니다)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No surface source specified."
@@ -5550,23 +5680,15 @@ msgstr "서피스 소스가 지정ë˜ì§€ 않았습니다."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Surface source is invalid (invalid path)."
-msgstr "서피스 소스가 유효하지 않습니다 (유효하지 ì•Šì€ ê²½ë¡œ)."
+msgstr "서피스 소스가 올바르지 않습니다 (올바르지 ì•Šì€ ê²½ë¡œ)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Surface source is invalid (no geometry)."
-msgstr "서피스 소스가 유효하지 않습니다 (지오메트리 ì—†ìŒ)."
+msgstr "서피스 소스가 올바르지 않습니다 (지오메트리 ì—†ìŒ)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Surface source is invalid (no faces)."
-msgstr "서피스 소스가 유효하지 않습니다 (페ì´ìŠ¤ ì—†ìŒ)."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "부모노드가 솔리드 페ì´ìŠ¤ë¥¼ 가지고 있지 ì•Šì•„ ìƒì„±í•  수 없습니다."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "ì˜ì—­ì„ 매핑 í•  수 없습니다."
+msgstr "서피스 소스가 올바르지 않습니다 (페ì´ìŠ¤ ì—†ìŒ)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
@@ -5652,20 +5774,27 @@ msgid "Generation Time (sec):"
msgstr "ìƒì„± 시간 (ì´ˆ):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "페ì´ìŠ¤ê°€ ì˜ì—­ì„ 가지고 있지 않습니다!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "페ì´ìŠ¤ê°€ 없습니다!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "노드가 지오미트리를 í¬í•¨í•˜ê³  있지 않습니다 (페ì´ìŠ¤)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "노드가 지오미트리를 í¬í•¨í•˜ê³  있지 않습니다."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "노드가 지오미트리를 í¬í•¨í•˜ê³  있지 않습니다 (페ì´ìŠ¤)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "노드가 지오미트리를 í¬í•¨í•˜ê³  있지 않습니다."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -5882,7 +6011,7 @@ msgstr "내부 ê¼­ì§“ì  ì‚­ì œ"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Invalid Polygon (need 3 different vertices)"
-msgstr "유효하지 ì•Šì€ í´ë¦¬ê³¤ (3ê°œì˜ ë‹¤ë¥¸ 꼭짓ì ì´ 필요함)"
+msgstr "올바르지 ì•Šì€ í´ë¦¬ê³¤ (3ê°œì˜ ë‹¤ë¥¸ 꼭짓ì ì´ 필요함)"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Add Custom Polygon"
@@ -5906,11 +6035,11 @@ msgstr "본 무게 페ì¸íŠ¸"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Open Polygon 2D UV editor."
-msgstr "í´ë¦¬ê³¤ 2D UV ì—디터 열기."
+msgstr "í´ë¦¬ê³¤ 2D UV 편집기 열기."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
-msgstr "í´ë¦¬ê³¤ 2D UV ì—디터"
+msgstr "í´ë¦¬ê³¤ 2D UV 편집기"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV"
@@ -5997,7 +6126,6 @@ msgid "Grid Settings"
msgstr "ê²©ìž ì„¤ì •"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "스냅"
@@ -6072,7 +6200,7 @@ msgstr "타입:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
msgid "Open in Editor"
-msgstr "ì—디터ì—ì„œ 열기"
+msgstr "편집기ì—ì„œ 열기"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Load Resource"
@@ -6088,7 +6216,7 @@ msgstr "AnimationTree가 AnimationPlayer로 향하는 경로를 가지고 있지
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "Path to AnimationPlayer is invalid"
-msgstr "AnimationPlayer로 향하는 경로가 유효하지 않습니다"
+msgstr "AnimationPlayer로 향하는 경로가 올바르지 않습니다"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Files"
@@ -6103,12 +6231,9 @@ msgid "Error writing TextFile:"
msgstr "í…스트 íŒŒì¼ ì“°ê¸° 오류:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "오류: 파ì¼ì„ 불러올 수 ì—†ìŒ."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "오류로 파ì¼ì„ 불러올 수 ì—†ìŒ."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "타ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6131,7 +6256,8 @@ msgid "Error Importing"
msgstr "가져오는 중 오류 ë°œìƒ"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "새 í…스트 파ì¼..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6212,6 +6338,11 @@ msgid "Open..."
msgstr "열기..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "스í¬ë¦½íŠ¸ 열기"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "ëª¨ë‘ ì €ìž¥"
@@ -6249,13 +6380,13 @@ msgid "Save Theme"
msgstr "테마 저장"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "문서 닫기"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "ëª¨ë‘ ë‹«ê¸°"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "문서 닫기"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "실행"
@@ -6287,7 +6418,7 @@ msgstr "디버거 í•­ìƒ ì—´ì–´ë†“ê¸°"
#: editor/plugins/script_editor_plugin.cpp
msgid "Debug with External Editor"
-msgstr "외부 ì—디터로 디버깅"
+msgstr "외부 편집기로 디버깅"
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Godot online documentation."
@@ -6343,6 +6474,11 @@ msgstr "디버거"
msgid "Search Results"
msgstr "검색 결과"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "최근 씬 지우기"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "ë©”ì„œë“œì— ì—°ê²°:"
@@ -6411,8 +6547,9 @@ msgid "Syntax Highlighter"
msgstr "구문 강조"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "ì´ë™"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6420,9 +6557,8 @@ msgid "Bookmarks"
msgstr "ë¶ë§ˆí¬"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "í¬ì¸íŠ¸ 만들기."
+msgstr "중단ì "
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6446,22 +6582,6 @@ msgid "Toggle Comment"
msgstr "ì£¼ì„ í† ê¸€"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "ë¶ë§ˆí¬ 토글"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "ë‹¤ìŒ ë¶ë§ˆí¬ë¡œ ì´ë™"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "ì´ì „ ë¶ë§ˆí¬ë¡œ ì´ë™"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "모든 ë¶ë§ˆí¬ ì‚­ì œ"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "ë¼ì¸ 펼치기/접기"
@@ -6482,6 +6602,11 @@ msgid "Complete Symbol"
msgstr "ìžë™ 완성"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "ì„ íƒ í¬ê¸° ì¡°ì ˆ"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "후행 공백 ë¬¸ìž ì‚­ì œ"
@@ -6498,29 +6623,32 @@ msgid "Auto Indent"
msgstr "ìžë™ 들여쓰기"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "ì¤‘ë‹¨ì  í† ê¸€"
+msgid "Find Previous"
+msgstr "ì´ì „ 찾기"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "ì¤‘ë‹¨ì  ëª¨ë‘ ì‚­ì œ"
+msgid "Find in Files..."
+msgstr "파ì¼ì—ì„œ 찾기..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "ë‹¤ìŒ ì¤‘ë‹¨ì ìœ¼ë¡œ ì´ë™"
+msgid "Contextual Help"
+msgstr "ë„ì›€ë§ ë³´ê¸°"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "ì´ì „ 중단ì ìœ¼ë¡œ ì´ë™"
+msgid "Toggle Bookmark"
+msgstr "ë¶ë§ˆí¬ 토글"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "ì´ì „ 찾기"
+msgid "Go to Next Bookmark"
+msgstr "ë‹¤ìŒ ë¶ë§ˆí¬ë¡œ ì´ë™"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "파ì¼ì—ì„œ 찾기..."
+msgid "Go to Previous Bookmark"
+msgstr "ì´ì „ ë¶ë§ˆí¬ë¡œ ì´ë™"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "모든 ë¶ë§ˆí¬ ì‚­ì œ"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6531,8 +6659,21 @@ msgid "Go to Line..."
msgstr "ë¼ì¸ìœ¼ë¡œ ì´ë™..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "ë„ì›€ë§ ë³´ê¸°"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "ì¤‘ë‹¨ì  í† ê¸€"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "ì¤‘ë‹¨ì  ëª¨ë‘ ì‚­ì œ"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "ë‹¤ìŒ ì¤‘ë‹¨ì ìœ¼ë¡œ ì´ë™"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "ì´ì „ 중단ì ìœ¼ë¡œ ì´ë™"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6712,8 +6853,12 @@ msgid "Rear"
msgstr "ë’·ë©´"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "뷰와 정렬"
+msgid "Align Transform with View"
+msgstr "ë³€í˜•ì„ ë·°ì— ì •ë ¬"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "íšŒì „ì„ ë·°ì— ì •ë ¬"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6768,8 +6913,9 @@ msgid "Audio Listener"
msgstr "오디오 리스너"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "ë„플러 활성화"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "필터 활성화"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6808,7 +6954,7 @@ 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"
+"참고: FPS ê°’ì€ íŽ¸ì§‘ê¸°ì˜ í”„ë ˆìž„ ì†ë„입니다.\n"
"게임 ë‚´ ì„±ëŠ¥ì„ ë³´ì¦í•˜ëŠ” 표시로 ë³¼ 수 없습니다."
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6824,8 +6970,8 @@ msgid "Snap Nodes To Floor"
msgstr "노드를 ë°”ë‹¥ì— ìŠ¤ëƒ…"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "ì„ íƒ ëª¨ë“œ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6838,30 +6984,11 @@ msgstr ""
"알트+ìš°í´ë¦­: 겹친 ëª©ë¡ ì„ íƒ"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "ì´ë™ 모드 (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "회전 모드 (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "í¬ê¸° ì¡°ì ˆ 모드 (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "지역 좌표"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "로컬 스페ì´ìŠ¤ 모드 (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "스냅 모드 (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "하단 뷰"
@@ -6902,26 +7029,6 @@ msgid "Focus Selection"
msgstr "ì„ íƒ í¬ì»¤ìŠ¤"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "ì„ íƒ í•­ëª©ì„ ë·°ì— ì •ë ¬"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "ì„ íƒ íˆ´"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "ì´ë™ 툴"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "회전 툴"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "í¬ê¸° ì¡°ì ˆ 툴"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "ìžìœ  ì‹œì  í† ê¸€"
@@ -6976,7 +7083,8 @@ msgstr "ê²©ìž ë³´ê¸°"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "설정"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7269,10 +7377,6 @@ msgid "TextureRegion"
msgstr "í…스ì³ì§€ì—­"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "테마를 파ì¼ë¡œ 저장할 수 없습니다:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "모든 항목 추가"
@@ -7310,11 +7414,11 @@ msgstr "빈 템플릿 만들기"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Editor Template"
-msgstr "빈 ì—디터 템플릿 만들기"
+msgstr "빈 편집기 템플릿 만들기"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create From Current Editor Theme"
-msgstr "현재 ì—디터 테마로부터 만들기"
+msgstr "현재 편집기 테마로부터 만들기"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Toggle Button"
@@ -7357,11 +7461,13 @@ msgid "Submenu"
msgstr "하위 메뉴"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "항목 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "항목 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7466,14 +7572,6 @@ msgid "Transpose"
msgstr "바꾸기"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "X축 뒤집기"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Y축 뒤집기"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "ì˜¤í† íƒ€ì¼ ë¹„í™œì„±í™”"
@@ -7486,9 +7584,10 @@ msgid "Paint Tile"
msgstr "íƒ€ì¼ ì¹ í•˜ê¸°"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+ìš°í´ë¦­: ì„  그리기\n"
"Shift+Ctrl+ìš°í´ë¦­:사ê°í˜• 페ì¸íŠ¸"
@@ -7681,9 +7780,9 @@ msgid ""
"bindings.\n"
"Click on another Tile to edit it."
msgstr ""
-"사용할 서브 타ì¼ì„ ì•„ì´ì½˜ìœ¼ë¡œ 설정하세요, 유효하지 ì•Šì€ ìžë™ íƒ€ì¼ ë°”ì¸ë”©ì—ë„ "
+"ì•„ì´ì½˜ìœ¼ë¡œ 사용할 서브 타ì¼ì„ 설정하세요, 올바르지 ì•Šì€ ìžë™ íƒ€ì¼ ë°”ì¸ë”©ì—ë„ "
"사용ë©ë‹ˆë‹¤.\n"
-"다른 타ì¼ì„ 편집하려면 í´ë¦­."
+"다른 타ì¼ì„ 편집하려면 í´ë¦­í•˜ì„¸ìš”."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -7786,6 +7885,10 @@ msgid "TileSet"
msgstr "타ì¼ì…‹"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(GLES3만 가능)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "입력 추가 +"
@@ -7862,6 +7965,11 @@ msgid "Duplicate Nodes"
msgstr "노드 복제"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "노드 붙여넣기"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "노드 삭제"
@@ -7882,6 +7990,11 @@ msgid "Light"
msgstr "조명"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "ì…°ì´ë” 노드 만들기"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "ì…°ì´ë” 노드 만들기"
@@ -7954,6 +8067,22 @@ msgid "Color uniform."
msgstr "ìƒ‰ìƒ ìœ ë‹ˆí¼."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "ë‘ ë§¤ê°œë³€ìˆ˜ ì‚¬ì´ %s 비êµì˜ 불리언 ê²°ê³¼ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "같다 (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "보다 ë” í¬ë‹¤ (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "보다 í¬ê±°ë‚˜ 같다 (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7961,10 +8090,47 @@ msgstr "ì œê³µëœ ìŠ¤ì¹¼ë¼ê°€ 같거나, ë” í¬ê±°ë‚˜, ë” ìž‘ìœ¼ë©´ 관련 ë²
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "무한(INF)ê³¼ ìŠ¤ì¹¼ë¼ ë§¤ê°œë³€ìˆ˜ ì‚¬ì´ ë¹„êµì˜ 불리언 ê²°ê³¼ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"ìˆ«ìž ì•„ë‹˜(NaN)ê³¼ ìŠ¤ì¹¼ë¼ ë§¤ê°œë³€ìˆ˜ ì‚¬ì´ ë¹„êµì˜ 불리언 ê²°ê³¼ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "보다 ë” ìž‘ë‹¤ (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "보다 작거나 같다 (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "같지 않다 (!=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr "불리언 ê°’ì´ ì°¸ì´ê±°ë‚˜ 거짓ì´ë©´ 관련 벡터를 반환합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "ë‘ ë§¤ê°œë³€ìˆ˜ ì‚¬ì´ ë¹„êµì˜ 불리언 ê²°ê³¼ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"무한(INF) (ë˜ëŠ” ìˆ«ìž ì•„ë‹˜(NaN))ê³¼ ìŠ¤ì¹¼ë¼ ë§¤ê°œë³€ìˆ˜ ì‚¬ì´ ë¹„êµì˜ 불리언 ê²°ê³¼ ê°’"
+"ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "불리언 ìƒìˆ˜."
@@ -8053,16 +8219,16 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì•„í¬ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì•„í¬ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8073,8 +8239,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "ë§¤ê°œë³€ìˆ˜ë“¤ì˜ ì•„í¬íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8090,8 +8256,8 @@ msgid "Returns the cosine of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8159,12 +8325,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / 스칼ë¼"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(GLES3만 가능) 매개변수ì—ì„œ 가장 가까운 정수를 찾습니다."
+msgid "Finds the nearest integer to the parameter."
+msgstr "매개변수ì—ì„œ 가장 가까운 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr "(GLES3만 가능) 매개변수ì—ì„œ 가장 가까운 ì§ìˆ˜ 정수를 찾습니다."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "매개변수ì—ì„œ 가장 가까운 ì§ìˆ˜ 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -8179,18 +8345,19 @@ msgid "Returns the sine of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì œê³±ê·¼ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8200,10 +8367,11 @@ msgstr ""
"ë°˜í™˜ê°’ì€ ì—르미트 다항ì‹ì„ 통해 0.0ê³¼ 1.0사ì´ë¡œ ë³´ê°„ë©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step 함수( 스칼ë¼(edge), 스칼ë¼(x) ).\n"
"\n"
@@ -8214,12 +8382,12 @@ msgid "Returns the tangent of the parameter."
msgstr "ë§¤ê°œë³€ìˆ˜ì˜ íƒ„ì  íŠ¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr "(GLES3만 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì ˆì‚¬ ê°’ì„ ì°¾ìŠµë‹ˆë‹¤."
+msgid "Finds the truncated value of the parameter."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì ˆì‚¬ëœ ê°’ì„ ì°¾ìŠµë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8258,12 +8426,16 @@ msgid "Perform the texture lookup."
msgstr "í…ìŠ¤ì³ ë£©ì—…ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "세제곱 í…ìŠ¤ì³ ìœ ë‹ˆí¼."
+msgid "Cubic texture uniform lookup."
+msgstr "세제곱 í…ìŠ¤ì³ ìœ ë‹ˆí¼ ë£©ì—…."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "2D í…ìŠ¤ì³ ìœ ë‹ˆí¼."
+msgid "2D texture uniform lookup."
+msgstr "2D í…ìŠ¤ì³ ìœ ë‹ˆí¼ ë£©ì—…."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Triplanarê°€ ì ìš©ëœ 2D í…ìŠ¤ì³ ìœ ë‹ˆí¼ ë£©ì—… ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8271,7 +8443,7 @@ msgstr "변형 함수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8279,7 +8451,7 @@ 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"
"\n"
"OuterProduct는 첫 매개변수 'c'를 ì—´ 벡터로 취급합니다 (1ì—´ë¡œ ì´ë£¨ì–´ì§„ 행렬) "
"그리고 ë‘ ë²ˆì§¸ 매개변수 'r'ì„ í–‰ 벡터로 취급합니다 (1행으로 ì´ë£¨ì–´ì§„ 행렬) ê·¸"
@@ -8295,16 +8467,16 @@ msgid "Decomposes transform to four vectors."
msgstr "ë³€í˜•ì„ 4ê°œì˜ ë²¡í„°ë¡œ 분해합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr "(GLES3만 가능) ë³€í˜•ì˜ í–‰ë ¬ì‹ì„ 계산합니다."
+msgid "Calculates the determinant of a transform."
+msgstr "ë³€í˜•ì˜ í–‰ë ¬ì‹ì„ 계산합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(GLES3만 가능) ë³€í˜•ì˜ ì—­í•¨ìˆ˜ë¥¼ 계산합니다."
+msgid "Calculates the inverse of a transform."
+msgstr "ë³€í˜•ì˜ ì—­í•¨ìˆ˜ë¥¼ 계산합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(GLES3만 가능) ë³€í˜•ì˜ ì „ì¹˜ë¥¼ 계산합니다."
+msgid "Calculates the transpose of a transform."
+msgstr "ë³€í˜•ì˜ ì „ì¹˜ë¥¼ 계산합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8352,15 +8524,15 @@ msgstr "ë‘ ë²¡í„°ì˜ ìŠ¤ì¹¼ë¼ê³± ê°’ì„ ê³„ì‚°í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
-"참조 벡터와 ê°™ì€ ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 반환합니다. 함수ì—는 세 ê°œì˜ ë²¡í„° 매"
+"ê°™ì€ ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 참조 벡터로 반환합니다. 함수ì—는 세 ê°œì˜ ë²¡í„° 매"
"개변수가 있습니다 : ë°©í–¥ì„ ì§€ì •í•˜ëŠ” 벡터 N, ì¸ì‹œë˜íŠ¸ 벡터 I, 그리고 참조 벡"
-"í„° Nref. I와 Nrefì˜ ìŠ¤ì¹¼ë¼ê³± ê°’ì´ 0보다 작으면 ë°˜í™˜ê°’ì€ Nì´ ë©ë‹ˆë‹¤. 그렇지 ì•Š"
-"으면 -Nì´ ë°˜í™˜ë©ë‹ˆë‹¤."
+"í„° Nref. I와 Nrefì˜ ë‚´ì  ê°’ì´ 0보다 작으면 ë°˜í™˜ê°’ì€ Nì´ ë©ë‹ˆë‹¤. 그렇지 않으"
+"ë©´ -Nì´ ë°˜í™˜ë©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
@@ -8371,6 +8543,11 @@ msgid "Linear interpolation between two vectors."
msgstr "ë‘ ë²¡í„° ê°„ì˜ ì„ í˜• ë³´ê°„."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "ë‘ ë²¡í„° ê°„ì˜ ì„ í˜• ë³´ê°„."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "ë²¡í„°ì˜ ë…¸ë©€ ê°’ì„ ê³„ì‚°í•©ë‹ˆë‹¤."
@@ -8384,20 +8561,21 @@ msgstr "1.0 / 벡터"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+msgid "Returns the vector that points in the direction of refraction."
msgstr "반사 ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 반환합니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8408,10 +8586,11 @@ msgstr ""
"다."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8422,20 +8601,22 @@ msgstr ""
"다."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step 함수( 벡터(edge), 벡터(x) ).\n"
"\n"
"'x'ê°€ 'edge'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³  그렇지 않으면 1.0ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Step 함수( 스칼ë¼(edge), 벡터(x) ).\n"
"\n"
@@ -8488,60 +8669,57 @@ msgstr ""
"다 (í´ì˜¤í”„와 ê´€ë ¨ëœ ìž…ë ¥ì„ ì „ë‹¬í•¨)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
-msgstr "(GLES3만 가능) (프래그먼트/조명 모드만 가능) ìŠ¤ì¹¼ë¼ ë¯¸ë¶„ 함수."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr "(GLES3만 가능) (프래그먼트/조명 모드만 가능) 벡터 미분 함수."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(프래그먼트/조명 모드만 가능) ìŠ¤ì¹¼ë¼ ë¯¸ë¶„ 함수."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(프래그먼트/조명 모드만 가능) 벡터 미분 함수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
-msgstr ""
-"(GLES3만 가능) (프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ 'x'ì˜ (벡터) "
-"ë„함수."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr "(프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ 'x'ì˜ (벡터) ë„함수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
-"(GLES3만 가능) (프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ 'x'ì˜ (스칼"
-"ë¼) ë„함수."
+"(프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ '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'ì˜ (벡터) "
-"ë„함수."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr "(프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ 'y'ì˜ (벡터) ë„함수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
-"(GLES3만 가능) (프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ 'y'ì˜ (스칼"
-"ë¼) ë„함수."
+"(프래그먼트/조명 모드만 가능) 지역 ì°¨ë¶„ì„ ì´ìš©í•œ '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'ì˜ ì ˆëŒ€ 미분 ê°’"
-"ì˜ í•©."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr "(프래그먼트/조명 모드만 가능) (벡터) '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'ì˜ ì ˆëŒ€ 미분 "
-"ê°’ì˜ í•©."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr "(프래그먼트/조명 모드만 가능) (스칼ë¼) 'x'와 'y'ì˜ ì ˆëŒ€ 미분 ê°’ì˜ í•©."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8711,6 +8889,10 @@ msgid "Export templates for this platform are missing:"
msgstr "ì´ í”Œëž«í¼ì— 대한 내보내기 í…œí”Œë¦¿ì´ ì—†ìŒ:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "내보내기 템플릿 관리"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "디버그와 함께 내보내기"
@@ -8721,7 +8903,8 @@ msgstr "경로가 존재하지 않습니다."
#: editor/project_manager.cpp
msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
msgstr ""
-"유효하지 ì•Šì€ '.zip' 프로ì íŠ¸ 파ì¼, 'project.godot' 파ì¼ì„ í¬í•¨í•˜ì§€ ì•ŠìŒ."
+"올바르지 ì•Šì€ '.zip' 프로ì íŠ¸ 파ì¼, 'project.godot' 파ì¼ì„ í¬í•¨í•˜ì§€ ì•Šê³  있습"
+"니다."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
@@ -8761,7 +8944,7 @@ msgstr "프로ì íŠ¸ ì´ë¦„ì„ ì •í•˜ëŠ” ê²ƒì„ ê¶Œí•©ë‹ˆë‹¤."
#: editor/project_manager.cpp
msgid "Invalid project path (changed anything?)."
-msgstr "유효하지 ì•Šì€ í”„ë¡œì íŠ¸ 경로 (뭔가 변경하신 ê±°ë¼ë„?)."
+msgstr "올바르지 ì•Šì€ í”„ë¡œì íŠ¸ 경로 (뭔가 변경하신 ê±°ë¼ë„?)."
#: editor/project_manager.cpp
msgid ""
@@ -8868,6 +9051,15 @@ msgid "Unnamed Project"
msgstr "ì´ë¦„없는 프로ì íŠ¸"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "기존 프로ì íŠ¸ 가져오기"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "'%s'ì—ì„œ 프로ì íŠ¸ë¥¼ ì—´ 수 ì—†ìŒ."
@@ -8936,7 +9128,7 @@ 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
@@ -8960,12 +9152,13 @@ msgstr ""
"프로ì íŠ¸ í´ë”ì˜ ë‚´ìš©ì€ ìˆ˜ì •ë˜ì§€ 않습니다."
#: editor/project_manager.cpp
+#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"목ë¡ì—ì„œ 모든 ì´ë¦„없는 프로ì íŠ¸ë¥¼ 삭제하시겠습니까? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ìˆ˜ì •ë˜"
-"지 않습니다)"
+"%dê°œì˜ í”„ë¡œì íŠ¸ë¥¼ 삭제하시겠습니까?\n"
+"프로ì íŠ¸ í´ë”ì˜ ë‚´ìš©ì€ ìˆ˜ì •ë˜ì§€ 않습니다."
#: editor/project_manager.cpp
msgid ""
@@ -8973,7 +9166,7 @@ msgid ""
"The interface will update after restarting the editor or project manager."
msgstr ""
"언어가 변경ë˜ì—ˆìŠµë‹ˆë‹¤.\n"
-"ì¸í„°íŽ˜ì´ìŠ¤ëŠ” ì—디터나 프로ì íŠ¸ 매니저를 재시작할 ë•Œ ì—…ë°ì´íŠ¸ë©ë‹ˆë‹¤."
+"ì¸í„°íŽ˜ì´ìŠ¤ëŠ” 편집기나 프로ì íŠ¸ 매니저를 재시작할 ë•Œ ì—…ë°ì´íŠ¸ë©ë‹ˆë‹¤."
#: editor/project_manager.cpp
msgid ""
@@ -8988,8 +9181,9 @@ msgid "Project Manager"
msgstr "프로ì íŠ¸ 매니저"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "프로ì íŠ¸ 목ë¡"
+#, fuzzy
+msgid "Projects"
+msgstr "프로ì íŠ¸"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9012,10 +9206,6 @@ msgid "Templates"
msgstr "템플릿"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "종료"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "지금 재시작"
@@ -9029,7 +9219,7 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
"현재 프로ì íŠ¸ê°€ í•˜ë‚˜ë„ ì—†ìŠµë‹ˆë‹¤.\n"
-"ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ì—ì„œ ê³µì‹ ì˜ˆì œ 프로ì íŠ¸ë¥¼ 찾아보시겠습니까?"
+"ì• ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ì—ì„œ ê³µì‹ ì˜ˆì œ 프로ì íŠ¸ë¥¼ 찾아보시겠습니까?"
#: editor/project_settings_editor.cpp
msgid "Key "
@@ -9052,7 +9242,7 @@ msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
msgstr ""
-"유효하지 ì•Šì€ ì•¡ì…˜ ì´ë¦„. 공백ì´ê±°ë‚˜, '/' , ':', '=', '\\', '\"' 를 í¬í•¨í•˜ë©´ "
+"올바르지 ì•Šì€ ì•¡ì…˜ ì´ë¦„. 공백ì´ê±°ë‚˜, '/' , ':', '=', '\\', '\"' 를 í¬í•¨í•˜ë©´ "
"안 ë©ë‹ˆë‹¤"
#: editor/project_settings_editor.cpp
@@ -9277,7 +9467,7 @@ msgstr "재정ì˜..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
-msgstr "변경 ì‚¬í•­ì„ ì ìš©í•˜ë ¤ë©´ ì—디터를 다시 실행해야 합니다."
+msgstr "변경 ì‚¬í•­ì„ ì ìš©í•˜ë ¤ë©´ 편집기를 다시 실행해야 합니다."
#: editor/project_settings_editor.cpp
msgid "Input Map"
@@ -9355,6 +9545,10 @@ msgstr "로케ì¼:"
msgid "AutoLoad"
msgstr "오토로드"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "플러그ì¸"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "등ì†"
@@ -9407,14 +9601,6 @@ msgstr "ê°€ìƒ ë©”ì„œë“œ ì„ íƒ"
msgid "Select Method"
msgstr "메서드 ì„ íƒ"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "PVRTC ë„구를 실행할 수 없습니다:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "PVRTC ë„구를 사용하여 ë³€í™˜ëœ ì´ë¯¸ì§€ë¥¼ 다시 불러올 수 없습니다:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "ì¼ê´„ ì´ë¦„ 변경"
@@ -9709,6 +9895,11 @@ msgid "Remove Node(s)"
msgstr "노드 삭제"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "출력 í¬íŠ¸ ì´ë¦„ 변경"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9752,6 +9943,10 @@ msgid "Extend Script"
msgstr "스í¬ë¦½íŠ¸ 펼치기"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "새 ë…¸ë“œì— ë¶€ëª¨ 노드 재지정"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "씬 루트 만들기"
@@ -9823,24 +10018,27 @@ msgid "Node configuration warning:"
msgstr "노드 구성 경고:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"노드가 ì—°ê²°ê³¼ ê·¸ë£¹ì„ ê°–ê³  있습니다.\n"
"ì‹œê·¸ë„ ë…ì„ í´ë¦­í•˜ì—¬ 보세요."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"노드가 ì—°ê²°ì„ ê°–ê³  있습니다\n"
"ì‹œê·¸ë„ ë…ì„ í´ë¦­í•˜ì—¬ 보세요."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"노드가 그룹 ì•ˆì— ìžˆìŠµë‹ˆë‹¤.\n"
@@ -9880,7 +10078,7 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid "Invalid node name, the following characters are not allowed:"
-msgstr "유효하지 ì•Šì€ ë…¸ë“œ ì´ë¦„입니다. 다ìŒì˜ 문ìžëŠ” 허용ë˜ì§€ 않습니다:"
+msgstr "올바르지 ì•Šì€ ë…¸ë“œ ì´ë¦„입니다. 다ìŒì˜ 문ìžëŠ” 허용ë˜ì§€ 않습니다:"
#: editor/scene_tree_editor.cpp
msgid "Rename Node"
@@ -9939,6 +10137,11 @@ msgid "Error loading script from %s"
msgstr "'%s' 스í¬ë¦½íŠ¸ 로딩 중 오류"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "ë®ì–´ 쓰기"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "해당 ì—†ìŒ"
@@ -9964,11 +10167,11 @@ msgstr "올바르지 ì•Šì€ ìƒì†ëœ 부모 ì´ë¦„ ë˜ëŠ” 경로."
#: editor/script_create_dialog.cpp
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 그리고 _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "허용ë¨: a-z, A-z, 0-9 그리고 ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10127,6 +10330,10 @@ msgid "Change Shortcut"
msgstr "단축키 변경"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "편집기 설정"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "단축키"
@@ -10284,21 +10491,21 @@ msgstr "리소스 파ì¼ì— 기반하지 ì•ŠìŒ"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (missing @path)"
-msgstr "유효하지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@path ì—†ìŒ)"
+msgstr "올바르지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@path ì—†ìŒ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (can't load script at @path)"
msgstr ""
-"유효하지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@path ì—ì„œ 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 ì—†ìŒ)"
+"올바르지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@path ì—ì„œ 스í¬ë¦½íŠ¸ë¥¼ 불러올 수 ì—†ìŒ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (invalid script at @path)"
msgstr ""
-"유효하지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@pathì˜ ìŠ¤í¬ë¦½íŠ¸ê°€ 유효하지 ì•ŠìŒ)"
+"올바르지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary í˜•ì‹ (@pathì˜ ìŠ¤í¬ë¦½íŠ¸ê°€ 올바르지 ì•ŠìŒ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr "유효하지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary (서브í´ëž˜ìŠ¤ê°€ 유효하지 ì•ŠìŒ)"
+msgstr "올바르지 ì•Šì€ ì¸ìŠ¤í„´ìŠ¤ Dictionary (하위 í´ëž˜ìŠ¤ê°€ 올바르지 ì•ŠìŒ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
@@ -10514,7 +10721,7 @@ msgstr ""
#: modules/visual_script/visual_script.cpp
msgid "Node returned an invalid sequence output: "
-msgstr "유효하지 ì•Šì€ ì‹œí€€ìŠ¤ ì¶œë ¥ì„ ë°˜í™˜í•œ 노드: "
+msgstr "올바르지 ì•Šì€ ì‹œí€€ìŠ¤ ì¶œë ¥ì„ ë°˜í™˜í•œ 노드: "
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
@@ -10546,12 +10753,32 @@ msgid "Set Variable Type"
msgstr "변수 타입 설정"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "기존 내장 타입 ì´ë¦„ê³¼ 충ëŒí•˜ì§€ 않아야 합니다."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "새 사ê°í˜• 만들기."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "변수:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "새 사ê°í˜• 만들기."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "새로운 í´ë¦¬ê³¤ 만들기."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
-msgstr "유효한 ì‹ë³„ìžê°€ ì•„ë‹Œ ì´ë¦„:"
+msgstr "ì´ë¦„ì´ ì˜¬ë°”ë¥¸ ì‹ë³„ìžê°€ 아닙니다:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
@@ -10738,10 +10965,6 @@ msgid "Cut Nodes"
msgstr "노드 잘ë¼ë‚´ê¸°"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "노드 붙여넣기"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "멤버 편집"
@@ -10759,7 +10982,7 @@ msgstr "반복ìžê°€ 유효하지 않게 ë¨: "
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
-msgstr "유효하지 ì•Šì€ ì¸ë±ìŠ¤ ì†ì„±ëª…."
+msgstr "올바르지 ì•Šì€ ì¸ë±ìŠ¤ ì†ì„±ëª…."
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Base object is not a Node!"
@@ -10771,15 +10994,15 @@ msgstr "노드를 지칭하는 경로가 아닙니다!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name '%s' in node %s."
-msgstr "노드 %s ì•ˆì— ì¸ë±ìŠ¤ ì†ì„± ì´ë¦„ '%s'ì€(는) 유효하지 않습니다."
+msgstr "노드 %s ì•ˆì— ì¸ë±ìŠ¤ ì†ì„± ì´ë¦„ '%s'ì€(는) 올바르지 않습니다."
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
-msgstr ": 유효하지 ì•Šì€ ì¸ìˆ˜ 타입: "
+msgstr ": 올바르지 ì•Šì€ ì¸ìˆ˜ 타입: "
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid arguments: "
-msgstr ": 유효하지 ì•Šì€ ì¸ìˆ˜: "
+msgstr ": 올바르지 ì•Šì€ ì¸ìˆ˜: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
@@ -10799,7 +11022,7 @@ msgid ""
"Invalid return value from _step(), must be integer (seq out), or string "
"(error)."
msgstr ""
-"_step()ìœ¼ë¡œë¶€í„°ì˜ ìœ íš¨í•˜ì§€ ì•Šì€ ë°˜í™˜ 값으로, integer (seq out), í˜¹ì€ string "
+"_step()ìœ¼ë¡œë¶€í„°ì˜ ì˜¬ë°”ë¥´ì§€ ì•Šì€ ë°˜í™˜ 값으로, integer (seq out), í˜¹ì€ string "
"(error)ê°€ 아니면 안ë©ë‹ˆë‹¤."
#: modules/visual_script/visual_script_property_selector.cpp
@@ -10841,39 +11064,39 @@ msgstr "패키지는 ì ì–´ë„ í•˜ë‚˜ì˜ '.' 분리 기호를 ê°–ê³  있어야 í
#: platform/android/export/export.cpp
msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB 실행 파ì¼ì´ ì—디터 설정ì—ì„œ 구성ë˜ì§€ 않았습니다."
+msgstr "ADB 실행 파ì¼ì´ 편집기 설정ì—ì„œ 구성ë˜ì§€ 않았습니다."
#: platform/android/export/export.cpp
msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsignerê°€ ì—디터 설정ì—ì„œ 구성ë˜ì§€ 않았습니다."
+msgstr "OpenJDK jarsignerê°€ 편집기 설정ì—ì„œ 구성ë˜ì§€ 않았습니다."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
-msgstr "Debug keystoreì´ ì—디터 설정 ë˜ëŠ” 프리셋ì—ì„œ 구성ë˜ì§€ 않았습니다."
+msgstr "Debug keystoreì´ íŽ¸ì§‘ê¸° 설정 ë˜ëŠ” 프리셋ì—ì„œ 구성ë˜ì§€ 않았습니다."
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
-"커스텀 빌드ì—는 ì—디터 설정ì—ì„œ 유효한 안드로ì´ë“œ SDK 경로가 필요합니다."
+"커스텀 빌드ì—는 편집기 설정ì—ì„œ 올바른 안드로ì´ë“œ SDK 경로가 필요합니다."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "ì—디터 설정ì—ì„œ 커스텀 ë¹Œë“œì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다."
+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."
-msgstr "APK í™•ìž¥ì— ìœ íš¨í•˜ì§€ ì•Šì€ ê³µìš© 키입니다."
+msgstr "APK í™•ìž¥ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ê³µìš© 키입니다."
#: platform/android/export/export.cpp
msgid "Invalid package name:"
-msgstr "유효하지 ì•Šì€ íŒ¨í‚¤ì§€ ì´ë¦„:"
+msgstr "올바르지 ì•Šì€ íŒ¨í‚¤ì§€ ì´ë¦„:"
#: platform/android/export/export.cpp
msgid ""
@@ -10942,7 +11165,7 @@ msgstr "앱스토어 팀 IDê°€ 지정ë˜ì§€ 않았습니다 - 프로ì íŠ¸ë¥¼ êµ
#: platform/iphone/export/export.cpp
msgid "Invalid Identifier:"
-msgstr "유효하지 ì•Šì€ ì‹ë³„ìž:"
+msgstr "올바르지 ì•Šì€ ì‹ë³„ìž:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
@@ -10966,7 +11189,7 @@ msgstr "내보내기 í…œí”Œë¦¿ì„ ì—´ 수 없습니다:"
#: platform/javascript/export/export.cpp
msgid "Invalid export template:"
-msgstr "유효하지 ì•Šì€ ë‚´ë³´ë‚´ê¸° 템플릿:"
+msgstr "올바르지 ì•Šì€ ë‚´ë³´ë‚´ê¸° 템플릿:"
#: platform/javascript/export/export.cpp
msgid "Could not read custom HTML shell:"
@@ -10982,7 +11205,7 @@ msgstr "기본 부트 스플래시 ì´ë¯¸ì§€ 사용."
#: platform/uwp/export/export.cpp
msgid "Invalid package unique name."
-msgstr "유효하지 ì•Šì€ íŒ¨í‚¤ì§€ 고유 ì´ë¦„."
+msgstr "올바르지 ì•Šì€ íŒ¨í‚¤ì§€ 고유 ì´ë¦„."
#: platform/uwp/export/export.cpp
msgid "Invalid product GUID."
@@ -10998,41 +11221,40 @@ msgstr "유요하지 ì•Šì€ ë°°ê²½ 색ìƒ."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (50x50 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (50x50 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (44x44 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (44x44 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (71x71 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (71x71 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (150x150 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (150x150 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (310x310 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (310x310 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
-msgstr "유효하지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (310x150 ì´ì–´ì•¼ 합니다)."
+msgstr "올바르지 ì•Šì€ ë¡œê³  ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (310x150 ì´ì–´ì•¼ 합니다)."
#: platform/uwp/export/export.cpp
msgid "Invalid splash screen image dimensions (should be 620x300)."
msgstr ""
-"유효하지 ì•Šì€ ìŠ¤í”Œëž˜ì‰¬ 스í¬ë¦° ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (620x300 ì´ì–´ì•¼ 합니다)."
+"올바르지 ì•Šì€ ìŠ¤í”Œëž˜ì‹œ 스í¬ë¦° ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (620x300 ì´ì–´ì•¼ 합니다)."
#: scene/2d/animated_sprite.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite to display frames."
msgstr ""
-"AnimatedSpriteì´ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 'Frames' ì†ì„±ì— SpriteFrames 리소"
-"스 만들거나 지정해야 합니다."
+"AnimatedSpriteì´ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 \"Frames\" ì†ì„±ì— SpriteFrames 리"
+"소스를 만들거나 지정해야 합니다."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11094,11 +11316,10 @@ msgstr ""
"CanvasItemMaterialì´ í•„ìš”í•©ë‹ˆë‹¤."
#: scene/2d/light_2d.cpp
-#, fuzzy
msgid ""
"A texture with the shape of the light must be supplied to the \"Texture\" "
"property."
-msgstr "ë¼ì´íŠ¸ì˜ ëª¨ì–‘ì„ ë‚˜íƒ€ë‚´ëŠ” í…스ì³ë¥¼ 'texture' ì†ì„±ì— 지정해야합니다."
+msgstr "ì¡°ëª…ì˜ ëª¨ì–‘ì„ ë‚˜íƒ€ë‚¼ í…스ì³ë¥¼ \"Texture\" ì†ì„±ì— 지정해야 합니다."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11107,9 +11328,8 @@ msgstr ""
"Occluderê°€ ë™ìž‘하기 위해서는 Occluder í´ë¦¬ê³¤ì„ 지정하거나 그려야 합니다."
#: scene/2d/light_occluder_2d.cpp
-#, fuzzy
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
-msgstr "Occluder í´ë¦¬ê³¤ì´ 비어있습니다. í´ë¦¬ê³¤ì„ 그리세요!"
+msgstr "Occluder í´ë¦¬ê³¤ì´ 비어있습니다. í´ë¦¬ê³¤ì„ 그리세요."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11175,7 +11395,7 @@ msgstr ""
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
-msgstr "Path ì†ì„±ì€ 유효한 Node2D 노드를 가리켜야 합니다."
+msgstr "Path ì†ì„±ì€ 올바른 Node2D 노드를 가리켜야 합니다."
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
@@ -11203,18 +11423,16 @@ msgstr ""
"ì˜ ìžì‹ 노드로 추가하여 사용합니다."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
-"VisibilityEnable2D는 편집 ì”¬ì˜ ë£¨íŠ¸ì˜ í•˜ìœ„ 노드로 추가할 ë•Œ 가장 잘 ë™ìž‘합니"
+"VisibilityEnabler2D는 편집 ì”¬ì˜ ë£¨íŠ¸ì˜ í•˜ìœ„ 노드로 추가할 ë•Œ 가장 잘 ë™ìž‘합니"
"다."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera는 반드시 ARVROrigin 노드를 부모로 가지고 있어야 함"
+msgstr "ARVRCamera는 반드시 ARVROrigin 노드를 부모로 가지고 있어야 합니다."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11301,13 +11519,12 @@ 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 ""
-"CollisionShapeê°€ ê¸°ëŠ¥ì„ í•˜ê¸° 위해서는 Shapeì´ ì œê³µë˜ì–´ì•¼ 합니다. Shape 리소스"
-"를 만드세요!"
+"CollisionShapeê°€ ì œ ê¸°ëŠ¥ì„ í•˜ë ¤ë©´ Shapeê°€ 제공ë˜ì–´ì•¼ 합니다. Shape 리소스를 "
+"만드세요."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11343,7 +11560,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "SpotLightì˜ ê°ë„를 90ë„ ì´ìƒìœ¼ë¡œ 잡게ë˜ë©´ 그림ìžë¥¼ 투ì˜í•  수 없습니다."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11387,13 +11604,12 @@ msgid "PathFollow only works when set as a child of a Path node."
msgstr "PathFollow는 Path ë…¸ë“œì˜ ìžì‹ìœ¼ë¡œ ìžˆì„ ë•Œë§Œ ë™ìž‘합니다."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"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\"ê°€ "
-"활성화ë˜ì–´ 있어야 합니다."
+"PathFollowì˜ ROTATION_ORIENTED는 부모 Pathì˜ Curve 리소스ì—ì„œ \"Up Vector"
+"\"ê°€ 활성화ë˜ì–´ 있어야 합니다."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11406,11 +11622,12 @@ msgstr ""
"대신 ìžì‹ ì¶©ëŒ í˜•íƒœì˜ í¬ê¸°ë¥¼ 변경해보세요."
#: scene/3d/remote_transform.cpp
-#, fuzzy
msgid ""
"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
"derived node to work."
-msgstr "Path ì†ì„±ì€ 유효한 Spatial 노드를 가리켜야 합니다."
+msgstr ""
+"\"Remote Path\" ì†ì„±ì€ 올바른 Spatial 노드, ë˜ëŠ” Spatial íŒŒìƒ ë…¸ë“œë¥¼ 가리켜"
+"야 합니다."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11426,13 +11643,12 @@ msgstr ""
"대신 ìžì‹ì˜ ì¶©ëŒ í¬ê¸°ë¥¼ 변경하세요."
#: scene/3d/sprite_3d.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"AnimatedSprite3Dê°€ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 'Frames' ì†ì„±ì— SpriteFrames 리"
-"소스 만들거나 지정해야 합니다."
+"AnimatedSprite3Dê°€ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 \"Frames\" ì†ì„±ì— SpriteFrames "
+"리소스 만들거나 지정해야 합니다."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11447,6 +11663,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment는 ì‹œê° íš¨ê³¼ë¥¼ 위해 Environment를 갖는 \"Environment\" ì†ì„±"
+"ì´ í•„ìš”í•©ë‹ˆë‹¤."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11471,20 +11689,19 @@ msgstr "애니메ì´ì…˜ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ: '%s'"
#: scene/animation/animation_tree.cpp
msgid "In node '%s', invalid animation: '%s'."
-msgstr "노드 '%s'ì—ì„œ, 유효하지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜: '%s'."
+msgstr "노드 '%s'ì—ì„œ, 올바르지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜: '%s'."
#: scene/animation/animation_tree.cpp
msgid "Invalid animation: '%s'."
-msgstr "유효하지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜: '%s'."
+msgstr "올바르지 ì•Šì€ ì• ë‹ˆë©”ì´ì…˜: '%s'."
#: scene/animation/animation_tree.cpp
msgid "Nothing connected to input '%s' of node '%s'."
msgstr "노드 '%s'ì˜ '%s' ìž…ë ¥ì— ì•„ë¬´ê²ƒë„ ì—°ê²°ë˜ì§€ ì•ŠìŒ."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "ê·¸ëž˜í”„ì˜ ë£¨íŠ¸ AnimationNodeê°€ 설정ë˜ì§€ 않았습니다."
+msgstr "그래프를 위한 루트 AnimationNodeê°€ 설정ë˜ì§€ 않았습니다."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11498,9 +11715,8 @@ msgstr ""
"다."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "AnimationPlayer 루트가 유효한 노드가 아닙니다."
+msgstr "AnimationPlayer 루트 노드가 올바른 노드가 아닙니다."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11528,14 +11744,13 @@ msgid "Add current color as a preset."
msgstr "현재 색ìƒì„ 프리셋으로 추가합니다."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
"If you don't intend to add a script, use a plain Control node instead."
msgstr ""
"Container ìžì²´ëŠ” ìžì‹ 배치 ìž‘ì—…ì„ êµ¬ì„±í•˜ëŠ” 스í¬ë¦½íŠ¸ 외ì—는 목ì ì´ 없습니다.\n"
-"스í¬ë¦½íŠ¸ë¥¼ 추가하지 않는 경우, 순수한 'Control' 노드를 사용해주세요."
+"스í¬ë¦½íŠ¸ë¥¼ 추가하지 않는 경우, 순수한 Control 노드를 사용해주세요."
#: scene/gui/control.cpp
msgid ""
@@ -11555,30 +11770,27 @@ 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, but they will hide upon "
"running."
msgstr ""
-"Popupì€ popup() ë˜ëŠ” 기타 popup*() 함수를 호출하기 전까지는 기본ì ìœ¼ë¡œ 숨겨집"
-"니다. 편집하는 ë™ì•ˆ 보여지ë„ë¡ í•  수는 있으나, 실행 ì‹œì—는 숨겨집니다."
+"Popupì€ popup() ë˜ëŠ” 기타 popup*() 함수로 호출ë˜ê¸° 전까지 기본ì ìœ¼ë¡œ 숨어있습"
+"니다. 편집하는 ë™ì•ˆ ë³´ì´ë„ë¡ í•  수는 있으나, 실행 ì‹œì—는 ë³´ì´ì§€ 않습니다."
#: scene/gui/range.cpp
-#, fuzzy
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr "exp_editì´ ì°¸ì´ë¼ë©´ min_value는 반드시 > 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer는 ë‹¨ì¼ ìžì‹ ì»¨íŠ¸ë¡¤ì„ ìž‘ì—…í•˜ê¸° 위한 것입니다.\n"
-"컨테ì´ë„ˆë¥¼ ìžì‹ (VBox,HBox,등)으로 사용하거나, Controlì„ ìˆ˜ë™ìœ¼ë¡œ 지정한 최"
-"소 수치로 설정해서 사용하세요."
+"ScrollContainer는 ë‹¨ì¼ ìžì‹ Controlì„ ìž‘ì—…í•˜ê¸° 위한 것입니다.\n"
+"컨테ì´ë„ˆë¥¼ ìžì‹ìœ¼ë¡œ 사용하거나 (VBox, HBox 등), Controlì„ ì‚¬ìš©í•´ ì†ìˆ˜ 최소 수"
+"치를 설정하세요."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11604,34 +11816,21 @@ msgstr ""
"그렇지 ì•Šì„ ê²½ìš°, í™”ë©´ì— í‘œì‹œí•˜ê¸° 위해서는 RenderTarget으로 설정하고 내부ì "
"ì¸ í…스ì³ë¥¼ 다른 ë…¸ë“œì— í• ë‹¹í•´ì•¼ 합니다."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "FreeType 초기화 오류."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "ì•Œ 수 없는 í°íŠ¸ 형ì‹."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "í°íŠ¸ 로딩 오류."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "유효하지 ì•Šì€ í°íŠ¸ í¬ê¸°."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "ìž…ë ¥"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "ì…°ì´ë”ì— ìœ íš¨í•˜ì§€ ì•Šì€ ì†ŒìŠ¤."
+msgstr "ë¯¸ë¦¬ë³´ê¸°ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ì†ŒìŠ¤."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
-msgstr "ì…°ì´ë”ì— ìœ íš¨í•˜ì§€ ì•Šì€ ì†ŒìŠ¤."
+msgstr "ì…°ì´ë”ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ì†ŒìŠ¤."
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "해당 íƒ€ìž…ì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ë¹„êµ í•¨ìˆ˜."
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
@@ -11649,6 +11848,126 @@ msgstr "Varyings는 ì˜¤ì§ ë²„í…스 함수ì—서만 지정할 수 있습니다.
msgid "Constants cannot be modified."
msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
+#~ msgid "No Matches"
+#~ msgstr "ì¼ì¹˜ ê²°ê³¼ ì—†ìŒ"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "file_type_cache.cch를 열수 없어서, íŒŒì¼ íƒ€ìž… ìºì‰¬ë¥¼ 저장하지 않습니다!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "íŒŒì¼ ì‹œìŠ¤í…œì—ì„œ '%s'ì„(를) ì°¾ì„ ìˆ˜ 없습니다!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "ì´ë¯¸ì§€ 불러오기 오류:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "ì´ë¯¸ì§€ì— 투명ë„ê°€ 128보다 í° í”½ì…€ì´ ì—†ìŠµë‹ˆë‹¤..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "부모노드가 솔리드 페ì´ìŠ¤ë¥¼ 가지고 있지 ì•Šì•„ ìƒì„±í•  수 없습니다."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "ì˜ì—­ì„ 매핑 í•  수 없습니다."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "페ì´ìŠ¤ê°€ ì˜ì—­ì„ 가지고 있지 않습니다!"
+
+#~ msgid "No faces!"
+#~ msgstr "페ì´ìŠ¤ê°€ 없습니다!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "오류: 파ì¼ì„ 불러올 수 ì—†ìŒ."
+
+#~ msgid "Error could not load file."
+#~ msgstr "오류로 파ì¼ì„ 불러올 수 ì—†ìŒ."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "ë„플러 활성화"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "ì„ íƒ ëª¨ë“œ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "ì´ë™ 모드 (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "회전 모드 (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "í¬ê¸° ì¡°ì ˆ 모드 (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "지역 좌표"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "스냅 모드 (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "ì„ íƒ íˆ´"
+
+#~ msgid "Tool Move"
+#~ msgstr "ì´ë™ 툴"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "회전 툴"
+
+#~ msgid "Tool Scale"
+#~ msgstr "í¬ê¸° ì¡°ì ˆ 툴"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "목ë¡ì—ì„œ 모든 ì´ë¦„없는 프로ì íŠ¸ë¥¼ 삭제하시겠습니까? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ìˆ˜ì •"
+#~ "ë˜ì§€ 않습니다)"
+
+#~ msgid "Project List"
+#~ msgstr "프로ì íŠ¸ 목ë¡"
+
+#~ msgid "Exit"
+#~ msgstr "종료"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "PVRTC ë„구를 실행할 수 없습니다:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "PVRTC ë„구를 사용하여 ë³€í™˜ëœ ì´ë¯¸ì§€ë¥¼ 다시 불러올 수 없습니다:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "FreeType 초기화 오류."
+
+#~ msgid "Unknown font format."
+#~ msgstr "ì•Œ 수 없는 í°íŠ¸ 형ì‹."
+
+#~ msgid "Error loading font."
+#~ msgstr "í°íŠ¸ 로딩 오류."
+
+#~ msgid "Invalid font size."
+#~ msgstr "올바르지 ì•Šì€ í°íŠ¸ í¬ê¸°."
+
+#~ msgid "Previous Folder"
+#~ msgstr "ì´ì „ í´ë”"
+
+#~ msgid "Next Folder"
+#~ msgstr "ë‹¤ìŒ í´ë”"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "스í¬ë¦°ìƒ· ìžë™ 열기"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "외부 ì´ë¯¸ì§€ 편집기ì—ì„œ 열기."
+
+#~ msgid "Reverse"
+#~ msgstr "뒤집기"
+
+#~ msgid "Mirror X"
+#~ msgstr "X축 뒤집기"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Y축 뒤집기"
+
#~ msgid "Generating solution..."
#~ msgstr "솔루션 ìƒì„± 중..."
@@ -12394,9 +12713,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Erase selection"
#~ msgstr "ì„ íƒ ì§€ìš°ê¸°"
-#~ msgid "Could not find tile:"
-#~ msgstr "타ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ:"
-
#~ msgid "Item name or ID:"
#~ msgstr "ì•„ì´í…œ ì´ë¦„ ë˜ëŠ” ì•„ì´ë””:"
@@ -12643,9 +12959,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Info"
#~ msgstr "ì •ë³´"
-#~ msgid "Re-Import..."
-#~ msgstr "다시 가져오기..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "가져올 비트 마스í¬ê°€ 없습니다!"
@@ -13036,9 +13349,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Stereo"
#~ msgstr "스테레오"
-#~ msgid "Window"
-#~ msgstr "윈ë„ìš°"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "%s%%ë¡œ í¬ê¸° 변경."
@@ -13241,9 +13551,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Add Image Group"
#~ msgstr "ì´ë¯¸ì§€ 그룹 추가"
-#~ msgid "Delete Image Group"
-#~ msgstr "ì´ë¯¸ì§€ 그룹 ì‚­ì œ"
-
#~ msgid "Project Export Settings"
#~ msgstr "프로ì íŠ¸ 내보내기 설정"
@@ -13328,9 +13635,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Export Project PCK"
#~ msgstr "프로ì íŠ¸ PCK 내보내기"
-#~ msgid "Export..."
-#~ msgstr "내보내기..."
-
#~ msgid "Project Export"
#~ msgstr "프로ì íŠ¸ 내보내기"
@@ -13428,6 +13732,3 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Deploy File Server Clients"
#~ msgstr "íŒŒì¼ ì„œë²„ í´ë¼ì´ì–¸íŠ¸ ë°°í¬"
-
-#~ msgid "Group Editor"
-#~ msgstr "그룹 편집기"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index ab9107801f..79d42d1231 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -60,7 +60,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Nemokama"
@@ -133,6 +132,31 @@ msgstr "Animacija: Pakeisti IÅ¡kvietimÄ…"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animacija: Pakeisti Reikšmę"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animacija: Pakeisti PerÄ—jimÄ…"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animacija: Pakeisti TransformacijÄ…"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animacija: Pakeisti Reikšmę"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animacija: Pakeisti IÅ¡kvietimÄ…"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Animacijos Nodas"
@@ -639,15 +663,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -884,8 +908,7 @@ msgstr "MÄ—gstamiausi:"
msgid "Recent:"
msgstr "Naujausi:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -979,7 +1002,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -1015,7 +1038,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1104,14 +1127,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1128,7 +1151,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1145,7 +1168,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1623,12 +1645,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1695,7 +1716,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1746,7 +1767,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1772,24 +1793,28 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2031,6 +2056,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2328,6 +2357,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Atidaryti Skriptų Editorių"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2422,6 +2460,11 @@ msgstr ""
msgid "Close Tab"
msgstr "Uždaryti"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Uždaryti"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2476,6 +2519,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Panaikinti pasirinkimÄ…"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2503,20 +2551,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2549,24 +2593,33 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Redaguoti"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2646,13 +2699,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Importuoti Animacijas..."
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2667,14 +2721,6 @@ 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 ""
@@ -2695,14 +2741,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2710,12 +2756,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2991,6 +3038,11 @@ msgstr "TrukmÄ—:"
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Redaguoti Filtrus"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3156,7 +3208,8 @@ msgid "Import From Node:"
msgstr "Importuoti iš Nodo:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Atsiųsti iš naujo"
#: editor/export_template_manager.cpp
@@ -3173,6 +3226,10 @@ msgid "Download"
msgstr "Atsiųsti"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Nerasta)"
@@ -3236,12 +3293,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3255,16 +3310,21 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
-msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+msgid "Cannot remove temporary file:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "Duplikuoti"
+
+#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
msgstr ""
@@ -3347,20 +3407,12 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "MÄ—gstamiausi:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3395,11 +3447,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3464,6 +3516,11 @@ msgstr "Duplikuoti"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Atidaryti Skriptų Editorių"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3529,6 +3586,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Sukurti"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3591,6 +3653,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3599,12 +3669,21 @@ msgstr ""
msgid "Invalid group name."
msgstr "Netinkamas Å¡rifto dydis."
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "IÅ¡trinti EfektÄ…"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3617,12 +3696,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Atidaryti Skriptų Editorių"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3828,7 +3908,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4601,10 +4681,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4617,14 +4693,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "TrukmÄ—:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4666,6 +4771,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "(Įdiegta)"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Bandyti iš naujo"
@@ -4695,13 +4805,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Visi"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importuoti Animacijas..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Priedai"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4709,7 +4823,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4722,7 +4836,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4734,6 +4848,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Atsiųsti"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4784,31 +4903,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Sukurti"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Panaikinti pasirinkimÄ…"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Prijunkite prie Nodo:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Panaikinti pasirinkimÄ…"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4890,6 +5013,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Animacija: Pakeisti TransformacijÄ…"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4920,6 +5048,7 @@ msgid "Zoom Reset"
msgstr "Nutolinti"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4940,14 +5069,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "TimeScale Nodas"
@@ -4972,6 +5104,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4988,11 +5121,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5005,6 +5133,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5213,16 +5346,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5538,14 +5661,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5629,19 +5744,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5976,7 +6095,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6083,11 +6201,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6116,7 +6230,7 @@ msgid "Error Importing"
msgstr "Įvyko klaida kraunant šriftą."
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6202,6 +6316,11 @@ msgid "Open..."
msgstr "Atidaryti"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Atidaryti Skriptų Editorių"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6240,11 +6359,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6332,6 +6451,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6402,6 +6525,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6437,22 +6561,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6473,6 +6581,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Panaikinti pasirinkimÄ…"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6489,30 +6602,33 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtrai..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtrai..."
+msgid "Remove All Bookmarks"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6523,7 +6639,20 @@ msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6701,7 +6830,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6757,8 +6890,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Animacija"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6811,9 +6945,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6823,27 +6956,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6887,26 +7000,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6961,7 +7054,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7265,10 +7358,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7356,11 +7445,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7468,14 +7557,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7490,8 +7571,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7795,6 +7876,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7877,6 +7962,11 @@ msgid "Duplicate Nodes"
msgstr "Duplikuoti"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "IÅ¡trinti EfektÄ…"
@@ -7899,6 +7989,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Prijunkite prie Nodo:"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Prijunkite prie Nodo:"
@@ -7974,6 +8069,22 @@ msgid "Color uniform."
msgstr "Animacija: Pakeisti TransformacijÄ…"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7981,10 +8092,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8073,7 +8218,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8081,7 +8226,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8093,7 +8238,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8110,7 +8255,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8179,11 +8324,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8199,7 +8344,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8210,7 +8355,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8219,7 +8364,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8227,11 +8372,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8272,11 +8417,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8286,7 +8435,7 @@ msgstr "Keisti Poligono SkalÄ™"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8304,15 +8453,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8363,7 +8512,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8378,6 +8527,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8391,19 +8544,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8412,7 +8565,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8421,14 +8574,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8473,47 +8626,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8685,6 +8845,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8835,6 +8999,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8904,8 +9076,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8925,7 +9097,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8950,10 +9122,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9288,6 +9456,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Priedai"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9340,14 +9512,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9639,6 +9803,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9682,6 +9850,11 @@ msgid "Extend Script"
msgstr "Atidaryti Skriptų Editorių"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Sukurti NaujÄ…"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9755,19 +9928,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9861,6 +10034,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9892,7 +10069,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10053,6 +10230,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10466,10 +10647,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Sukurti NaujÄ…"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Sukurti NaujÄ…"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Keisti Poligono SkalÄ™"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10656,10 +10856,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Redaguoti Filtrus"
@@ -11402,22 +11598,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Klaida inicijuojant FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Nežinomas šrifto formatas."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Įvyko klaida kraunant šriftą."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Netinkamas Å¡rifto dydis."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11432,6 +11612,11 @@ msgstr "Netinkamas Å¡rifto dydis."
msgid "Invalid source for shader."
msgstr "Netinkamas Å¡rifto dydis."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Netinkamas Å¡rifto dydis."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11448,6 +11633,22 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Klaida inicijuojant FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Nežinomas šrifto formatas."
+
+#~ msgid "Error loading font."
+#~ msgstr "Įvyko klaida kraunant šriftą."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Netinkamas Å¡rifto dydis."
+
#~ msgid "Path to Node:"
#~ msgstr "Kelias iki Nodo:"
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index cb6df1de91..fe36132eca 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -60,7 +60,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Bezmaksas"
@@ -131,6 +130,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Length"
msgstr "AnimÄciju Cilpa"
@@ -637,15 +656,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -878,8 +897,7 @@ msgstr "Favorīti:"
msgid "Recent:"
msgstr "Nesenie:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -976,7 +994,7 @@ msgstr ""
"varÄ“tu strÄdÄt.\n"
"Tik un tÄ noņemt tos? (Nevar atsaukt)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nevar noņemt:"
@@ -1015,7 +1033,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr "Salabot dependecīju"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1104,14 +1122,16 @@ msgid "License"
msgstr "Licence"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "TreÅ¡Äs partijas Licence"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot DzinÄ“js paļaujas uz citiem treÅ¡Äs partijas brÄ«vajÄm un atvÄ“rtÄ avota "
@@ -1132,7 +1152,8 @@ msgid "Licenses"
msgstr "Licences"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Kļūme atverot arhÄ«vu failu, nav ZIP formÄtÄ."
#: editor/editor_asset_installer.cpp
@@ -1149,7 +1170,6 @@ msgid "Success!"
msgstr "IzdevÄs!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Ieinstalēt"
@@ -1632,12 +1652,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1702,7 +1721,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1753,7 +1772,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1779,24 +1798,29 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Izvēlēties šo Mapi"
+msgid "Go to previous folder."
+msgstr "Doties uz iepriekšējo soli"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Izvēlēties šo Mapi"
+msgid "Go to next folder."
+msgstr "Doties uz nÄkamo soli"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Meklēt:"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2037,6 +2061,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2334,6 +2362,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Atjaunina Ainu"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2428,6 +2465,11 @@ msgstr ""
msgid "Close Tab"
msgstr "Aizvērt"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Aizvērt"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2482,6 +2524,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Noņemt Izvēlēto"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2509,6 +2556,10 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr ""
@@ -2519,14 +2570,6 @@ msgid "Save All Scenes"
msgstr "SaglabÄt KÄ"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2556,16 +2599,20 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2573,8 +2620,12 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "Projekta DibinÄtÄji"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2654,12 +2705,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2675,14 +2726,6 @@ 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 ""
@@ -2703,14 +2746,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2718,12 +2761,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2996,6 +3040,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Savieno SignÄlu:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3158,7 +3207,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3175,6 +3224,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3236,12 +3289,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3255,14 +3306,20 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nevar noņemt:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
-msgstr ""
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "Kļūme lÄdÄ“jot:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3347,20 +3404,12 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Favorīti:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3393,11 +3442,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3459,6 +3508,11 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Resurs"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3526,6 +3580,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Izveidot"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3589,6 +3648,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3597,12 +3664,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "Nederīgs nosaukums."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "PÄrsaukt Audio Kopni"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Izdzēst"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3615,12 +3692,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Rediģēt"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3826,7 +3904,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4588,10 +4666,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4604,14 +4678,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nevar noņemt:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4652,6 +4755,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Ieinstalēt"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4680,13 +4788,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4694,7 +4804,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4707,7 +4817,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4719,6 +4829,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "IelÄdÄ“t"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4769,31 +4884,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Izveidot"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Noņemt Izvēlēto"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Izveidot Jaunu %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Noņemt Izvēlēto"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4875,6 +4994,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Izveidot"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4904,6 +5028,7 @@ msgid "Zoom Reset"
msgstr "AttÄlinÄt"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4924,14 +5049,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Mēroga Attiecība:"
@@ -4956,6 +5084,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4972,11 +5101,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4989,6 +5113,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5199,16 +5328,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5526,14 +5645,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5617,19 +5728,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5960,7 +6075,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6066,11 +6180,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6099,7 +6209,7 @@ msgid "Error Importing"
msgstr "Kļūme lÄdÄ“jot:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6183,6 +6293,10 @@ msgid "Open..."
msgstr "Atvērt"
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6220,11 +6334,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6313,6 +6427,10 @@ msgstr ""
msgid "Search Results"
msgstr "Meklēt:"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6384,6 +6502,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6419,24 +6538,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Doties uz nÄkamo soli"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Doties uz iepriekšējo soli"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6457,6 +6558,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Mēroga Izvēle"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6473,30 +6579,33 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Go to Next Bookmark"
msgstr "Doties uz nÄkamo soli"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr "Doties uz iepriekšējo soli"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
@@ -6510,9 +6619,24 @@ msgid "Go to Line..."
msgstr "Doties uz Rindu"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Doties uz nÄkamo soli"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Doties uz iepriekšējo soli"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6688,7 +6812,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6744,8 +6872,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Nomainīt"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6798,7 +6927,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6809,27 +6938,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6873,26 +6982,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6947,7 +7036,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7251,10 +7340,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7341,11 +7426,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7453,14 +7538,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7474,8 +7551,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7776,6 +7853,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7857,6 +7938,11 @@ msgid "Duplicate Nodes"
msgstr "Dublicēt atslēgvietnes"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Izdzēst"
@@ -7879,6 +7965,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Izveidot Jaunu %s"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Izveidot Jaunu %s"
@@ -7954,6 +8045,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7961,10 +8068,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8054,7 +8195,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8062,7 +8203,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8074,7 +8215,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8091,7 +8232,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8160,11 +8301,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8180,7 +8321,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8191,7 +8332,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8200,7 +8341,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8208,11 +8349,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8252,11 +8393,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8266,7 +8411,7 @@ msgstr "Izveidot"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8284,15 +8429,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8344,7 +8489,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8359,6 +8504,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8372,19 +8521,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8393,7 +8542,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8402,14 +8551,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8454,47 +8603,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8661,6 +8817,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8807,6 +8967,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8876,8 +9044,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8897,8 +9065,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projekta DibinÄtÄji"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8922,10 +9091,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9260,6 +9425,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9312,14 +9481,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9609,6 +9770,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9651,6 +9816,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Izveidot Jaunu %s"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9724,19 +9894,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9831,6 +10001,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9860,7 +10034,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10022,6 +10196,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10435,10 +10613,32 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Nederīgs nosaukums. Nedrīkst sadurties ar eksistējošu iebūvēto tipa "
+"nosaukumu."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Izveidot Jaunu %s"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Izveidot Jaunu %s"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Izveidot"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10623,10 +10823,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11366,22 +11562,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Kļūme inicializējot FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "NezinÄms fonta formÄts."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Kļūda lÄdÄ“jot fontu."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Nederīgs fonta izmērs."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11396,6 +11576,11 @@ msgstr "Nederīgs fonta izmērs."
msgid "Invalid source for shader."
msgstr "Nederīgs fonta izmērs."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Nederīgs fonta izmērs."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11412,6 +11597,26 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Kļūme inicializējot FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "NezinÄms fonta formÄts."
+
+#~ msgid "Error loading font."
+#~ msgstr "Kļūda lÄdÄ“jot fontu."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Nederīgs fonta izmērs."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Izvēlēties šo Mapi"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Izvēlēties šo Mapi"
+
#~ msgid "Delete selected files?"
#~ msgstr "Izdzēst izvēlētos failus?"
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 5462f66f69..1bb449ea57 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -50,7 +50,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -119,6 +118,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -603,15 +622,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -835,8 +854,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -930,7 +948,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -966,7 +984,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1055,14 +1073,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1079,7 +1097,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1096,7 +1114,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1563,12 +1580,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1629,7 +1645,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1680,7 +1696,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1705,23 +1721,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1954,6 +1974,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2250,6 +2274,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2343,6 +2375,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2396,6 +2432,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2423,20 +2463,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2469,24 +2505,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2566,12 +2610,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2587,14 +2631,6 @@ 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 ""
@@ -2615,14 +2651,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2630,12 +2666,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2907,6 +2944,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3068,7 +3109,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3085,6 +3126,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3146,12 +3191,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3165,13 +3208,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3256,19 +3303,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3301,11 +3340,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3364,6 +3403,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3427,6 +3470,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3487,6 +3534,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3494,12 +3549,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3512,11 +3575,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3723,7 +3786,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4465,10 +4528,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4481,14 +4540,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4529,6 +4616,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4557,13 +4648,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4571,7 +4664,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4584,7 +4677,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4596,6 +4689,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4646,31 +4743,31 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4750,6 +4847,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4778,6 +4879,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4798,14 +4900,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4829,6 +4934,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4845,11 +4951,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4862,6 +4963,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5069,16 +5175,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5389,14 +5485,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5480,19 +5568,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5819,7 +5911,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5925,11 +6016,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5953,7 +6040,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6034,6 +6121,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6071,11 +6162,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6163,6 +6254,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6229,6 +6324,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6263,92 +6359,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6526,7 +6626,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6582,7 +6686,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6636,7 +6740,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6647,27 +6751,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6711,26 +6795,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6785,7 +6849,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7078,10 +7142,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7166,11 +7226,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7275,14 +7335,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7296,8 +7348,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7576,6 +7628,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7652,6 +7708,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7672,6 +7733,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7744,6 +7809,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7751,10 +7832,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7843,7 +7958,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7851,7 +7966,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7863,7 +7978,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7880,7 +7995,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7949,11 +8064,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7969,7 +8084,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7980,7 +8095,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -7989,7 +8104,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7997,11 +8112,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8041,11 +8156,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8054,7 +8173,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8072,15 +8191,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8129,7 +8248,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8144,6 +8263,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8157,19 +8280,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8178,7 +8301,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8187,14 +8310,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8239,47 +8362,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8446,6 +8576,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8592,6 +8726,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8661,8 +8803,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8682,7 +8824,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8706,10 +8848,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9043,6 +9181,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9095,14 +9237,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9388,6 +9522,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9430,6 +9568,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9501,19 +9643,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9604,6 +9746,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9632,7 +9778,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9792,6 +9938,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10202,10 +10352,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10390,10 +10556,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11123,22 +11285,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11151,6 +11297,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 4e120c2412..876edb73fa 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -58,7 +58,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -127,6 +126,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -611,15 +630,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -843,8 +862,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -938,7 +956,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -974,7 +992,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1063,14 +1081,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1087,7 +1105,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1104,7 +1122,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1571,12 +1588,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1637,7 +1653,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1688,7 +1704,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1713,23 +1729,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1962,6 +1982,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2258,6 +2282,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2351,6 +2383,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2404,6 +2440,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2431,20 +2471,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2477,24 +2513,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2574,12 +2618,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2595,14 +2639,6 @@ 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 ""
@@ -2623,14 +2659,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2638,12 +2674,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2915,6 +2952,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3076,7 +3117,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3093,6 +3134,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3154,12 +3199,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3173,13 +3216,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3264,19 +3311,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3309,11 +3348,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3372,6 +3411,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3435,6 +3478,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3495,6 +3542,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3502,12 +3557,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3520,11 +3583,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3731,7 +3794,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4473,10 +4536,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4489,14 +4548,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4537,6 +4624,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4565,13 +4656,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4579,7 +4672,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4592,7 +4685,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4604,6 +4697,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4654,31 +4751,31 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4758,6 +4855,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4786,6 +4887,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4806,14 +4908,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4837,6 +4942,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4853,11 +4959,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4870,6 +4971,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5077,16 +5183,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5397,14 +5493,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5488,19 +5576,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5827,7 +5919,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5933,11 +6024,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5961,7 +6048,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6042,6 +6129,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6079,11 +6170,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6171,6 +6262,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6237,6 +6332,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6271,92 +6367,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6534,7 +6634,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6590,7 +6694,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6644,7 +6748,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6655,27 +6759,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6719,26 +6803,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6793,7 +6857,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7086,10 +7150,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7174,11 +7234,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7283,14 +7343,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7304,8 +7356,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7584,6 +7636,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7660,6 +7716,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7680,6 +7741,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7752,6 +7817,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7759,10 +7840,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7851,7 +7966,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7859,7 +7974,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7871,7 +7986,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7888,7 +8003,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7957,11 +8072,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7977,7 +8092,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7988,7 +8103,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -7997,7 +8112,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8005,11 +8120,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8049,11 +8164,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8062,7 +8181,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8080,15 +8199,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8137,7 +8256,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8152,6 +8271,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8165,19 +8288,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8186,7 +8309,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8195,14 +8318,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8247,47 +8370,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8454,6 +8584,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8600,6 +8734,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8669,8 +8811,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8690,7 +8832,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8714,10 +8856,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9051,6 +9189,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9103,14 +9245,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9396,6 +9530,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9438,6 +9576,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9509,19 +9651,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9612,6 +9754,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9640,7 +9786,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9800,6 +9946,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10210,10 +10360,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10398,10 +10564,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11131,22 +11293,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11159,6 +11305,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 7b7ac1ea61..afe9e390fe 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -61,7 +61,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -132,6 +131,31 @@ msgid "Anim Change Call"
msgstr "Anim Ubah Panggilan"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Ubah Masa Keyframe"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Ubah Peralihan"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Ubah Penukaran"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Ubah Nilai Keyframe"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Ubah Panggilan"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -626,15 +650,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -858,8 +882,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -953,7 +976,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -989,7 +1012,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1078,14 +1101,14 @@ msgid "License"
msgstr "Lesen"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1102,7 +1125,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1119,7 +1142,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1587,12 +1609,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1653,7 +1674,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1704,7 +1725,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1729,23 +1750,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1979,6 +2004,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2275,6 +2304,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2368,6 +2405,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2421,6 +2462,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Semua Pilihan"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2448,20 +2494,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2494,24 +2536,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2591,13 +2641,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Set Peralihan ke:"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2612,14 +2663,6 @@ 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 ""
@@ -2640,14 +2683,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2655,12 +2698,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2932,6 +2976,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3093,7 +3141,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3110,6 +3158,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3171,12 +3223,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3190,13 +3240,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3281,19 +3335,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3326,11 +3372,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3389,6 +3435,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3452,6 +3502,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3512,6 +3566,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3519,12 +3581,21 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Semua Pilihan"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3537,11 +3608,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3748,7 +3819,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4498,10 +4569,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4514,14 +4581,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4562,6 +4657,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4590,13 +4689,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4604,7 +4705,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4617,7 +4718,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4629,6 +4730,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4679,31 +4784,32 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Buang Trek Anim"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4785,6 +4891,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Anim Ubah Penukaran"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4814,6 +4925,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4834,14 +4946,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4865,6 +4980,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4881,11 +4997,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4898,6 +5009,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5105,16 +5221,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5427,14 +5533,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5518,19 +5616,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5857,7 +5959,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5963,11 +6064,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5991,7 +6088,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6072,6 +6169,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6109,11 +6210,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6201,6 +6302,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6267,6 +6372,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6301,92 +6407,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Semua Pilihan"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6564,7 +6675,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6620,7 +6735,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6674,7 +6789,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6685,27 +6800,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6749,26 +6844,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6823,7 +6898,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7118,10 +7193,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7208,11 +7279,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7319,14 +7390,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7340,8 +7403,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7623,6 +7686,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7701,6 +7768,11 @@ msgid "Duplicate Nodes"
msgstr "Anim Menduakan Kunci"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Semua Pilihan"
@@ -7722,6 +7794,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7795,6 +7871,22 @@ msgid "Color uniform."
msgstr "Anim Ubah Penukaran"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7802,10 +7894,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7894,7 +8020,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7902,7 +8028,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7914,7 +8040,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7931,7 +8057,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8000,11 +8126,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8020,7 +8146,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8031,7 +8157,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8040,7 +8166,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8048,11 +8174,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8093,11 +8219,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8106,7 +8236,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8124,15 +8254,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8181,7 +8311,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8196,6 +8326,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8209,19 +8343,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8230,7 +8364,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8239,14 +8373,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8291,47 +8425,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8498,6 +8639,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8644,6 +8789,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8713,8 +8866,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8734,7 +8887,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8758,10 +8911,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9096,6 +9245,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9148,14 +9301,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9443,6 +9588,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9485,6 +9634,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9556,19 +9709,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9659,6 +9812,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9687,7 +9844,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9847,6 +10004,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10260,10 +10421,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10448,10 +10625,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11181,22 +11354,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11209,6 +11366,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index 66d1b3952a..7b642c69e0 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -19,8 +19,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:51+0000\n"
-"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n"
+"PO-Revision-Date: 2019-07-29 19:21+0000\n"
+"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb_NO/>\n"
"Language: nb\n"
@@ -50,31 +50,26 @@ msgid "self can't be used because instance is null (not passed)"
msgstr "self kan ikke brukes siden instansen er lik null (ikke bestått)"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "Ugyldig indeks egenskap navn '%s' i node %s."
+msgstr "Ugyldige argumenter til operator %s, %s og %s."
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid index of type %s for base type %s"
-msgstr "Ugyldig indeks egenskap navn '%s' i node %s."
+msgstr "Ugyldig indeks av type %s for basistype %s"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid named index '%s' for base type %s"
msgstr "Ugyldig navngitt indeks \"%s\" for grunntypen %s"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid arguments to construct '%s'"
-msgstr ": Ugyldig argument av type: "
+msgstr "Ugyldige argumenter for å lage \"%s\""
#: core/math/expression.cpp
msgid "On call to '%s':"
msgstr "NÃ¥r \"%s\" ble anropt:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Frigjør"
@@ -91,14 +86,12 @@ msgid "Time:"
msgstr "Tid:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Value:"
-msgstr "Nytt navn:"
+msgstr "Verdi:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Insert Key Here"
-msgstr "Sett inn Nøkkel"
+msgstr "Sett inn nøkkel her"
#: editor/animation_bezier_editor.cpp
msgid "Duplicate Selected Key(s)"
@@ -148,6 +141,31 @@ msgstr "Anim Forandre Kall"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Endre Nøkkelbildetid"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Forandre Overgang"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Forandre Omforming"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Endre Nøkkelbildeverdi"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Forandre Kall"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Endre Animasjonsnavn:"
@@ -681,17 +699,18 @@ msgid "Line Number:"
msgstr "Linjenummer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Erstattet %d forekomst(er)."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Ingen Treff"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Erstattet %d forekomst(er)."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Match Tilfelle"
@@ -931,8 +950,7 @@ msgstr "Favoritter:"
msgid "Recent:"
msgstr "Nylige:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1036,7 +1054,7 @@ msgstr ""
"Filene som fjernes kreves for at andre ressurser skal virke.\n"
"Fjern dem likevel? (kan ikke angres)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Kan ikke fjerne:"
@@ -1074,7 +1092,7 @@ msgstr "Slett %d elementer for godt? (kan ikke angres)"
msgid "Show Dependencies"
msgstr "Avhengigheter"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Foreldreløs ressursutforsker"
@@ -1165,14 +1183,16 @@ msgid "License"
msgstr "Lisens"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Tredjepartslisens"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine avhenger av en rekke tredjeparts frie og åpne kildekode-"
@@ -1193,7 +1213,8 @@ msgid "Licenses"
msgstr "Lisenser"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Feil ved åpning av pakkefil, ikke i zip format."
#: editor/editor_asset_installer.cpp
@@ -1211,7 +1232,6 @@ msgid "Success!"
msgstr "Suksess!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installer"
@@ -1716,12 +1736,11 @@ msgid "New"
msgstr "Ny"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importer"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Eksporter"
@@ -1792,7 +1811,7 @@ msgstr "Vis I Filutforsker"
msgid "New Folder..."
msgstr "Ny Mappe..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Oppdater"
@@ -1843,7 +1862,7 @@ msgstr "GÃ¥ framover"
msgid "Go Up"
msgstr "GÃ¥ oppover"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Veksle visning av skjulte filer"
@@ -1869,27 +1888,30 @@ msgstr "Flytt Favoritt Nedover"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Forrige fane"
+msgid "Go to previous folder."
+msgstr "GÃ¥ til ovennevnt mappe."
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Lag mappe"
+msgid "Go to next folder."
+msgstr "GÃ¥ til ovennevnt mappe."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
-msgstr "GÃ¥ til overnevnt mappe"
+msgstr "GÃ¥ til ovennevnt mappe."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "(Un)favorite current folder."
-msgstr "Kunne ikke opprette mappe."
+msgid "Refresh files."
+msgstr "Søk i klasser"
#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr "(Av)favoriser gjeldende mappe."
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Veksle visning av skjulte filer"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2151,6 +2173,10 @@ msgstr "Tøm"
msgid "Clear Output"
msgstr "Nullstill resultat"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Eksport av prosjektet mislyktes med feilkode %d."
@@ -2477,6 +2503,15 @@ msgid "Pick a Main Scene"
msgstr "Velg en HovedScene"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Lukk Scene"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Lukk Scene"
+
+#: editor/editor_node.cpp
#, fuzzy
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2593,6 +2628,11 @@ msgstr "Spill Scene"
msgid "Close Tab"
msgstr "Lukk Andre Faner"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Lukk Andre Faner"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Lukk Andre Faner"
@@ -2647,6 +2687,11 @@ msgid "Go to previously opened scene."
msgstr "Gå til forrige åpne scene."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopier Sti"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Neste fane"
@@ -2674,6 +2719,10 @@ msgstr "Ny Arvet Scene..."
msgid "Open Scene..."
msgstr "Ã…pne Scene..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Ã…pne Nylig"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Lagre Scene"
@@ -2684,14 +2733,6 @@ msgid "Save All Scenes"
msgstr "Lagre alle Scener"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Lukk Scene"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Ã…pne Nylig"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konverter Til..."
@@ -2722,26 +2763,37 @@ msgstr "Tilbakestille Scene"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Diverse prosjekt- eller scene-relaterte verktøy"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Prosjekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Prosjektinnstillinger"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Verktøy"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Eksporter"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Ã…pne ProsjektManager?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Verktøy"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Foreldreløs ressursutforsker"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2843,13 +2895,14 @@ msgstr ""
"Når det brukes ekstert på en enhet, dette er mer effektivt med et "
"nettverksfilsystem."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Editor"
msgstr "Redigeringsverktøy"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Redigeringsverktøy-instillinger"
#: editor/editor_node.cpp
@@ -2867,15 +2920,6 @@ 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"
@@ -2900,15 +2944,15 @@ msgstr "Redigeringsverktøy-instillinger"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "HÃ¥ndter Eksportmaler"
-#: editor/editor_node.cpp editor/project_export.cpp
+#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Export Templates"
+msgid "Manage Export Templates..."
msgstr "HÃ¥ndter Eksportmaler"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Hjelp"
@@ -2916,12 +2960,13 @@ msgstr "Hjelp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Søk"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentasjon"
@@ -3210,6 +3255,11 @@ msgstr "Tid:"
msgid "Calls"
msgstr "Ring"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Medlemmer"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "PÃ¥"
@@ -3383,7 +3433,8 @@ msgid "Import From Node:"
msgstr "Importer Fra Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Last Ned PÃ¥ Nytt"
#: editor/export_template_manager.cpp
@@ -3400,6 +3451,10 @@ msgid "Download"
msgstr "Last ned"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mangler)"
@@ -3467,13 +3522,11 @@ msgid "No response."
msgstr "Ingen respons."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "Forespørsel Feilet."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Redirect Loop."
msgstr "Omdirigerings-Loop."
@@ -3488,13 +3541,19 @@ msgid "Download Complete."
msgstr "Nedlastning fullført."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kan ikke fjerne:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Error ved forespørsel av url: "
#: editor/export_template_manager.cpp
@@ -3586,21 +3645,12 @@ msgstr "Last ned Mal"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Velg fillager fra liste: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Kan ikke åpne fyle_type_cache.cch for skriving, lagrer ikke file type cache!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Favoritter:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Kan ikke navigere til '%s' for den ble ikke funnet på filsystemet!"
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3643,14 +3693,14 @@ msgid "Provided name contains invalid characters."
msgstr "Gitt navn inneholder ugyldige tegn"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Navn inneholder ugyldige tegn."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "En fil eller mappe med dette navnet eksisterer allerede."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Navn inneholder ugyldige tegn."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Endrer filnavn:"
@@ -3713,6 +3763,11 @@ msgstr "Duplisér"
msgid "Move To..."
msgstr "Flytt Til..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ny Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3787,6 +3842,11 @@ msgstr "En fil eller mappe med dette navnet eksisterer allerede."
msgid "Overwrite"
msgstr "Overskriv"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Lagre Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Opprett skript"
@@ -3856,6 +3916,14 @@ msgid "Search complete"
msgstr "Søk Tekst"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Legg til i Gruppe"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Fjern fra Gruppe"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "ERROR: Animasjonsnavnet finnes allerede!"
@@ -3865,13 +3933,23 @@ msgstr "ERROR: Animasjonsnavnet finnes allerede!"
msgid "Invalid group name."
msgstr "Ugyldig navn."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Grupper"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Slett Layout"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupper"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Legg til i Gruppe"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3886,12 +3964,13 @@ msgid "Nodes in Group"
msgstr "Legg til i Gruppe"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Legg til i Gruppe"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Fjern fra Gruppe"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Ã…pne SkriptEditor"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4108,7 +4187,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Set"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Velg en Node for å endre Signaler og Grupper."
#: editor/plugin_config_dialog.cpp
@@ -4923,10 +5003,6 @@ msgid "View Files"
msgstr "Vis Filer"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Kan ikke løse tjenernavn:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Tilkoblingsfeil, vennligst prøv igjen."
@@ -4939,15 +5015,48 @@ msgid "No response from host:"
msgstr "Ingen respons fra tjener:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Kan ikke løse tjenernavn:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Forespørsel feilet, returneringskode:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Forespørsel Feilet."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kan ikke fjerne:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Forespørsel feilet, for mange omdirigeringer"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
+msgid "Redirect loop."
+msgstr "Omdirigerings-Loop."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Forespørsel feilet, returneringskode:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tid:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Bad download hash, assuming file has been tampered with."
msgstr "DÃ¥rlig nedlastningshash, antar at filen har blitt tuklet med."
@@ -4991,6 +5100,11 @@ msgid "Idle"
msgstr "Inaktiv"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Installer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Prøv på nytt"
@@ -5022,14 +5136,17 @@ msgid "Last"
msgstr "Siste"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Alle"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
#, fuzzy
-msgid "Plugins"
+msgid "Import..."
+msgstr "Importer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -5037,8 +5154,9 @@ msgid "Sort:"
msgstr "Sorter:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Reverser"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Ber om..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -5050,7 +5168,8 @@ msgid "Site:"
msgstr "Side:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Support..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5062,6 +5181,11 @@ msgid "Testing"
msgstr "Tester"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Last"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Assets ZIP-Fil"
@@ -5112,31 +5236,38 @@ msgid "Rotation Step:"
msgstr "Rotasjon Steg:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Flytt vertikal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Lag ny vertikal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Fjern vertikal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Flytt horisontal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Lag ny horisontal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Fjern horisontal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Lag ny horisontal og vertikal veileder"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5227,6 +5358,11 @@ msgstr "Lim Inn Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Fjern Pose"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Fjern Ben"
@@ -5257,6 +5393,7 @@ msgid "Zoom Reset"
msgstr "Zoom Ut"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Velg Modus"
@@ -5278,14 +5415,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+Høyreklikk: Dybdelisteutvalg"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Flytt Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Roter Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Velg Modus"
@@ -5314,6 +5454,7 @@ msgid "Toggle snapping."
msgstr "Slå av/på snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Bruk Snap"
@@ -5332,11 +5473,6 @@ msgid "Use Rotation Snap"
msgstr "Bruk Rotasjons-Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Konfigurer Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relativt"
@@ -5350,6 +5486,11 @@ msgid "Smart Snapping"
msgstr "Smart snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Konfigurer Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Snap til foreldre"
@@ -5576,16 +5717,6 @@ msgstr "Sett Handle"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Feil ved innlasting av bilde:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Ingen piksler med gjennomsiktighet > 128 i bilde..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5909,14 +6040,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -6001,19 +6124,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6360,7 +6487,6 @@ msgid "Grid Settings"
msgstr "Redigeringsverktøy-instillinger"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6479,12 +6605,7 @@ msgstr "Error ved lagring av TileSet!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Kunne ikke opprette mappe."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Kunne ikke opprette mappe."
#: editor/plugins/script_editor_plugin.cpp
@@ -6514,7 +6635,7 @@ msgstr "Error ved importering"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Ny Mappe..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6601,6 +6722,11 @@ msgid "Open..."
msgstr "Ã…pne"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Kjør Skript"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Lagre Alle"
@@ -6640,13 +6766,13 @@ msgid "Save Theme"
msgstr "Lagre drakt"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Lukk Dokumentasjon"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Lukk Alle"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Lukk Dokumentasjon"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Kjør"
@@ -6735,6 +6861,11 @@ msgstr "Feilretter"
msgid "Search Results"
msgstr "Søk hjelp"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Fjern Nylige Scener"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6807,6 +6938,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6844,26 +6976,6 @@ msgstr "Veksle kommentar"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Veksle kommentar"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "GÃ¥ til Neste Steg"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "GÃ¥ til tidligere redigert dokument."
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Fjern Funksjon"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "Slett Valgte"
@@ -6884,6 +6996,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skaler Utvalg"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6902,32 +7019,37 @@ msgid "Auto Indent"
msgstr "Automatisk innrykk"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr ""
+msgid "Find Previous"
+msgstr "Finn forrige"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtrer Filer..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "GÃ¥ til Neste Steg"
+msgid "Toggle Bookmark"
+msgstr "Veksle kommentar"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "GÃ¥ til tidligere redigert dokument."
+msgid "Go to Next Bookmark"
+msgstr "GÃ¥ til Neste Steg"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Finn forrige"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "GÃ¥ til tidligere redigert dokument."
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtrer Filer..."
+msgid "Remove All Bookmarks"
+msgstr "Fjern Funksjon"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6940,9 +7062,24 @@ msgid "Go to Line..."
msgstr "GÃ¥ til Linje"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "GÃ¥ til Neste Steg"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "GÃ¥ til tidligere redigert dokument."
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -7126,7 +7263,12 @@ msgstr "Bak"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr "Høyrevisning"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr "Høyrevisning"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7183,8 +7325,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Endre Anim Lengde"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7240,9 +7383,8 @@ msgid "Snap Nodes To Floor"
msgstr "Snap til rutenett"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Velg Modus"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7252,31 +7394,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Snap til veiledere"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Bunnvisning"
@@ -7317,27 +7438,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "Slett Valgte"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7393,8 +7493,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Redigeringsverktøy-instillinger"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7704,10 +7805,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7799,12 +7896,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Element %d"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Element %d"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7916,14 +8013,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Speil X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Speil Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7938,8 +8027,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8261,6 +8350,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Legg til Input"
@@ -8352,6 +8445,11 @@ msgid "Duplicate Nodes"
msgstr "Anim Dupliser Nøkler"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Lim inn Noder"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Kutt Noder"
@@ -8375,6 +8473,11 @@ msgstr "Høyre"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Lag Node"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Lag Node"
@@ -8453,6 +8556,22 @@ msgid "Color uniform."
msgstr "Anim Forandre Omforming"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8460,10 +8579,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8554,7 +8707,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8562,7 +8715,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8574,7 +8727,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8591,7 +8744,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8660,11 +8813,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8680,7 +8833,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8691,7 +8844,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8700,7 +8853,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8708,11 +8861,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8753,11 +8906,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8767,7 +8924,7 @@ msgstr "Lag Poly"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8785,15 +8942,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8845,7 +9002,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8860,6 +9017,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8873,19 +9034,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8894,7 +9055,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8903,14 +9064,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8955,47 +9116,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9170,6 +9338,11 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+#, fuzzy
+msgid "Manage Export Templates"
+msgstr "HÃ¥ndter Eksportmaler"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9323,6 +9496,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Importer Eksisterende Prosjekt"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Kan ikke åpne prosjekt"
@@ -9400,8 +9582,8 @@ msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
#: editor/project_manager.cpp
@@ -9424,8 +9606,9 @@ msgid "Project Manager"
msgstr "Prosjektleder"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Prosjektliste"
+#, fuzzy
+msgid "Projects"
+msgstr "Prosjekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9449,10 +9632,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Avslutt"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Omstart NÃ¥"
@@ -9796,6 +9975,11 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9850,14 +10034,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10160,6 +10336,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Anim Forandre Verdi"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10207,6 +10388,11 @@ msgstr "Kjør Skript"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Lag ny %s"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Lagre Scene"
@@ -10285,19 +10471,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10395,6 +10581,11 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Overskriv"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10428,7 +10619,7 @@ msgid "Script is valid."
msgstr "Animasjonstre er gyldig."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10595,6 +10786,10 @@ msgid "Change Shortcut"
msgstr "Endre Anker"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Redigeringsverktøy-instillinger"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -11022,10 +11217,31 @@ msgid "Set Variable Type"
msgstr "Rediger Variabel:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ugyldig navn. Kan ikke kollidere med et eksisterende innebygd type navn."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Lag ny %s"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variabler:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Lag ny %s"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Lag en ny polygon fra bunnen."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Navn er ikke en gyldig identifikator:"
@@ -11225,10 +11441,6 @@ msgid "Cut Nodes"
msgstr "Kutt Noder"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Lim inn Noder"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Medlemmer"
@@ -11976,22 +12188,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Feil ved innlasting av font."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ugyldig fontstørrelse."
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -12007,6 +12203,11 @@ msgstr "Ugyldig fontstørrelse."
msgid "Invalid source for shader."
msgstr "Ugyldig fontstørrelse."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ugyldig fontstørrelse."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -12021,7 +12222,77 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Konstanter kan ikke endres."
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Kan ikke åpne fyle_type_cache.cch for skriving, lagrer ikke file type "
+#~ "cache!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Kan ikke navigere til '%s' for den ble ikke funnet på filsystemet!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Feil ved innlasting av bilde:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Ingen piksler med gjennomsiktighet > 128 i bilde..."
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Kunne ikke opprette mappe."
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Velg Modus"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Snap til veiledere"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "Slett Valgte"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
+
+#~ msgid "Project List"
+#~ msgstr "Prosjektliste"
+
+#~ msgid "Exit"
+#~ msgstr "Avslutt"
+
+#~ msgid "Error loading font."
+#~ msgstr "Feil ved innlasting av font."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ugyldig fontstørrelse."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Forrige fane"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Lag mappe"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Ã…pne den neste Editoren"
+
+#~ msgid "Reverse"
+#~ msgstr "Reverser"
+
+#~ msgid "Mirror X"
+#~ msgstr "Speil X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Speil Y"
#, fuzzy
#~ msgid "Generating solution..."
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index d5d9277fe9..2c836b5685 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -35,12 +35,13 @@
# Jimmy De Smet <J773@telenet.be>, 2019.
# Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>, 2019.
# Hector Peeters <hector.peeters@gmail.com>, 2019.
+# Shawn Gyina <gyina.shawn@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: Hector Peeters <hector.peeters@gmail.com>\n"
+"PO-Revision-Date: 2019-08-04 14:23+0000\n"
+"Last-Translator: Shawn Gyina <gyina.shawn@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
"Language: nl\n"
@@ -48,7 +49,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
@@ -91,7 +92,6 @@ msgid "On call to '%s':"
msgstr "Tijdens invocatie van '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Vrij"
@@ -108,9 +108,8 @@ msgid "Time:"
msgstr "Tijd:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Value:"
-msgstr "Nieuwe Waarde:"
+msgstr "Waarde:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
@@ -161,6 +160,31 @@ msgid "Anim Change Call"
msgstr "Anim Wijzig Aanroep"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Wijzig Keyframe Waarde"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Wijzig Overgang"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Wijzig Transform"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Wijzig Keyframe Waarde"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Wijzig Aanroep"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Verander Animatielengte"
@@ -467,10 +491,19 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Deze animatie behoort tot een geïmporteerde scène, dus veranderingen aan "
+"geïmporteerde tracks zullen niet worden opgeslagen.\n"
+"\n"
+"Om aangepaste tracks toe te voegen, navigeert u naar de importinstellingen "
+"van de scène en stelt u deze in\n"
+"\"Animation > Storage\" naar \"Files\", schakel \"Animation > Keep Custom "
+"Tracks\" in, dan herimporteren.\n"
+"U kunt ook een importvoorinstelling gebruiken die animaties importeert om "
+"bestanden te scheiden."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "Waarschuwing: Geïmporteerde animatie bewerken"
#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -478,9 +511,8 @@ msgid "Select All"
msgstr "Alles Selecteren"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Alles Selecteren"
+msgstr "Niets Selecteren"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -658,16 +690,18 @@ msgid "Line Number:"
msgstr "Regelnummer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d voorgekomen waarde(s) vervangen."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Geen Overeenkomsten"
+#, fuzzy
+msgid "%d match."
+msgstr "%d overeenkomst(en) gevonden."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d voorgekomen waarde(s) vervangen."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "%d overeenkomst(en) gevonden."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -719,17 +753,15 @@ msgid "Line and column numbers."
msgstr "Regel- en kolomnummers."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "Methode in doel Node moet gespecificeerd worden!"
+msgstr "Methode in doel Node moet gespecificeerd worden."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"Doel methode niet gevonden! Specificeer een geldige methode of koppel een "
+"Doel methode niet gevonden. Specificeer een geldige methode of koppel een "
"script aan de doel Node."
#: editor/connections_dialog.cpp
@@ -905,8 +937,7 @@ msgstr "Favorieten:"
msgid "Recent:"
msgstr "Recente:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1012,7 +1043,7 @@ msgstr ""
"te laten werken.\n"
"Toch verwijderen? (Kan niet ongedaan worden.)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Niet te verwijderen:"
@@ -1049,7 +1080,7 @@ msgstr "%d item(s) permanent verwijderen? (Kan niet ongedaan worden!)"
msgid "Show Dependencies"
msgstr "Afhankelijkheden"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Wees Resource Verkenner"
@@ -1138,14 +1169,16 @@ msgid "License"
msgstr "Licentie"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Derde partijslicentie"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine maakt gebruik van enkele gratis en open-source bibliotheken, "
@@ -1166,7 +1199,8 @@ msgid "Licenses"
msgstr "Licenties"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Fout bij het openen van het pakketbestand, geen zip-formaat."
#: editor/editor_asset_installer.cpp
@@ -1183,7 +1217,6 @@ msgid "Success!"
msgstr "Geslaagd!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installeer"
@@ -1680,12 +1713,11 @@ msgid "New"
msgstr "Nieuw"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importeren"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exporteren"
@@ -1754,7 +1786,7 @@ msgstr "Weergeven in Bestandsbeheer"
msgid "New Folder..."
msgstr "Nieuwe Map..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Verversen"
@@ -1805,7 +1837,7 @@ msgstr "Ga Verder"
msgid "Go Up"
msgstr "Ga Omhoog"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Toggle Verborgen Bestanden"
@@ -1830,25 +1862,32 @@ msgid "Move Favorite Down"
msgstr "Verplaats Favoriet Naar Beneden"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Vorige Folder"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Ga naar bovenliggende folder"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Volgende Folder"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Ga naar bovenliggende folder"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Ga naar bovenliggende folder"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Zoek bestanden"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "(On)favoriet huidige map."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Toggle Verborgen Bestanden"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2094,6 +2133,10 @@ msgstr "Leegmaken"
msgid "Clear Output"
msgstr "Maak Uitvoer Leeg"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Project exporteren faalt door foutcode %d."
@@ -2426,6 +2469,15 @@ msgid "Pick a Main Scene"
msgstr "Kies een Hoofdscene"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Scene Sluiten"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Scene Sluiten"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Inschakelen plug-in is gefaald op: '%s' inlezen van configuratiebestand "
@@ -2542,6 +2594,11 @@ msgstr "Speel Scene"
msgid "Close Tab"
msgstr "Tabblad sluiten"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Tabblad sluiten"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Sluit Andere Tabbladen"
@@ -2596,6 +2653,11 @@ msgid "Go to previously opened scene."
msgstr "Ga naar de vorige geopende scene."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopieer Pad"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Volgend tabblad"
@@ -2623,6 +2685,10 @@ msgstr "Nieuwe Geërfde Scene..."
msgid "Open Scene..."
msgstr "Scene Openen..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Recente Scenes Openen"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Scene Opslaan"
@@ -2633,14 +2699,6 @@ msgid "Save All Scenes"
msgstr "Alle Scenes Opslaan"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Scene Sluiten"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Recente Scenes Openen"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Converteer Naar..."
@@ -2672,26 +2730,37 @@ msgstr "Scene Herstellen"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Diverse project of scene-brede gereedschappen."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Project"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projectinstellingen"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Gereedschappen"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exporteren"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Open de Project Manager?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Gereedschappen"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Wees Resource Verkenner"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2790,13 +2859,14 @@ msgstr ""
"Wanneer dit op afstand wordt gebruikt op een andere machine, is dit "
"efficiënter met het netwerk bestandssysteem."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Editor"
msgstr "Verwerker"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Editor Instellingen"
#: editor/editor_node.cpp
@@ -2814,15 +2884,6 @@ 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"
@@ -2845,14 +2906,15 @@ msgstr "Open Editor Instellingen Map"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Beheer Export Templates"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Beheer Export Templates"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Help"
@@ -2860,12 +2922,13 @@ msgstr "Help"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Zoeken"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Documentatie"
@@ -3142,6 +3205,11 @@ msgstr "Tijd"
msgid "Calls"
msgstr "Aanroepen"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Bewerk Thema..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Aan"
@@ -3314,7 +3382,8 @@ msgid "Import From Node:"
msgstr "Importeer Vanuit Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Opnieuw Downloaden"
#: editor/export_template_manager.cpp
@@ -3331,6 +3400,10 @@ msgid "Download"
msgstr "Download"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Missend)"
@@ -3394,12 +3467,10 @@ msgid "No response."
msgstr "Geen antwoord."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Aanvraag Mislukt."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Redirectlus."
@@ -3413,15 +3484,22 @@ msgid "Download Complete."
msgstr "Download Voltooid."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kan thema niet opslaan in bestand:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Installatie van templates mislukt. De problematische template archieven "
"kunnen gevonden worden op '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Fout bij het opvragen van een URL: "
#: editor/export_template_manager.cpp
@@ -3508,23 +3586,11 @@ msgstr "Download Sjablonen"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Selecteer mirror uit lijst: (Shift-klik: In Browser openen)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Kan niet schrijven in file_type_cache.cch, de bestandstype cache wordt niet "
-"bewaard!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favorieten"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Kan niet naar '%s' navigeren omdat het niet in het bestandssysteem gevonden "
-"is!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Status: Importeren van bestand mislukt. Repareer het bestand en importeer "
@@ -3560,14 +3626,14 @@ msgid "Provided name contains invalid characters."
msgstr "De opgegeven naam bevat ongeldige tekens"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Naam bevat ongeldige tekens."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Er bestaat al een bestand of map met deze naam."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Naam bevat ongeldige tekens."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Hernoem bestand:"
@@ -3627,6 +3693,11 @@ msgstr "Dupliceren..."
msgid "Move To..."
msgstr "Verplaats Naar..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nieuwe Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nieuw Script..."
@@ -3695,6 +3766,11 @@ msgstr "Er is al een bestand of map met dezelfde naam op dit pad."
msgid "Overwrite"
msgstr "Overschrijven"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Creëer vanuit Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Creëer Script"
@@ -3758,6 +3834,14 @@ msgid "Search complete"
msgstr "Zoek Tekst"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Toevoegen aan Groep"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Verwijderen uit Groep"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Groepnaam bestaat al."
@@ -3765,12 +3849,23 @@ msgstr "Groepnaam bestaat al."
msgid "Invalid group name."
msgstr "Ongeldige groepnaam."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Groepen beheren"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Layout Verwijderen"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Groepen"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Knopen niet in de groep"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3783,12 +3878,13 @@ msgid "Nodes in Group"
msgstr "Knopen in de groep"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Toevoegen aan Groep"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Verwijderen uit Groep"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Open Script Bewerker"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3999,7 +4095,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Set"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Selecteer een Node om Signalen en Groepen aan te passen."
#: editor/plugin_config_dialog.cpp
@@ -4794,10 +4891,6 @@ msgid "View Files"
msgstr "Bekijk Bestanden"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Kan hostname niet herleiden:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Verbindingsfout, probeer het nog eens."
@@ -4810,14 +4903,47 @@ msgid "No response from host:"
msgstr "Geen antwoord van host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Kan hostname niet herleiden:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Aanvraag mislukt, retourcode:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Aanvraag Mislukt."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kan thema niet opslaan in bestand:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Aanvraag mislukt, te veel redirects"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Redirectlus."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Aanvraag mislukt, retourcode:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tijd"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Slechte download hash, ervan uitgaand dat met het bestand is geknoeid."
@@ -4858,6 +4984,11 @@ msgid "Idle"
msgstr "Inactief"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Installeer"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Probeer opnieuw"
@@ -4886,13 +5017,17 @@ msgid "Last"
msgstr "Laatste"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Alle"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importeren"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4900,8 +5035,9 @@ msgid "Sort:"
msgstr "Sorteren:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Omkeren"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Opvragen..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4913,7 +5049,8 @@ msgid "Site:"
msgstr "Site:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Ondersteuning..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4925,6 +5062,11 @@ msgid "Testing"
msgstr "Testen"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Laden..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Assets ZIP Bestand"
@@ -4982,31 +5124,38 @@ msgid "Rotation Step:"
msgstr "Rotatie Stap:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Verplaats vertical gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Maak nieuwe verticale gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Verwijder de verticale gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Verplaats de horizontale gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Maak nieuwe horizontale gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Verwijder de horizontale gids"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Maak nieuwe horizontale en verticale gidsen"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5095,6 +5244,11 @@ msgstr "Plak Houding"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Maak Houding Leeg"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Maak één of meerdere op maat gemaakte botten van één of meerdere Nodes"
@@ -5126,6 +5280,7 @@ msgid "Zoom Reset"
msgstr "Zoom terugzetten"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Selecteer Modus"
@@ -5148,14 +5303,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + RMB: Diepte lijst selectie"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Verplaatsingsmodus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Rotatiemodus"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Schaalwijze"
@@ -5181,6 +5339,7 @@ msgid "Toggle snapping."
msgstr "Automatisch schikken omschakelen."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Gebruik Uitlijnen"
@@ -5198,11 +5357,6 @@ msgid "Use Rotation Snap"
msgstr "Gebruik Rotatie Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configureer Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relatief"
@@ -5216,6 +5370,11 @@ msgid "Smart Snapping"
msgstr "Slim Uitlijnen"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configureer Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Snap naar ouder"
@@ -5450,16 +5609,6 @@ msgstr "Stel Handgreep In"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Error bij het laden van afbeelding:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Geen pixels met transparantie > 128 in afbeelding..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Laad Emissie Masker"
@@ -5789,15 +5938,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Oppervlakte bron is ongeldig (geen vlakken)."
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
-msgid "Parent has no solid faces to populate."
-msgstr "Ouder heeft geen vaste vlakken om te bevolken."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Kon het gebied niet mappen."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selecteer een Bron Mesh:"
@@ -5883,20 +6023,27 @@ msgid "Generation Time (sec):"
msgstr "Genereer Tijd (sec):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Vlakken bevatten geen gebied!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Node bevat geen geometrie (vlakken)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Geen vlakken!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Node bevat geen geometrie."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Node bevat geen geometrie (vlakken)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Node bevat geen geometrie."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6246,7 +6393,6 @@ msgid "Grid Settings"
msgstr "Instellingen"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Snap"
@@ -6361,13 +6507,8 @@ msgstr "Error bij het opslaan van TileSet!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Map kon niet gemaakt worden."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
-msgstr "Map kon niet gemaakt worden."
+msgid "Could not load file at:"
+msgstr "Niet gevonden titel:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6396,7 +6537,7 @@ msgstr "Fout bij importeren"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Nieuwe Map..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6483,6 +6624,11 @@ msgid "Open..."
msgstr "Openen"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Omschrijving:"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Alles Opslaan"
@@ -6522,13 +6668,13 @@ msgid "Save Theme"
msgstr "Thema Opslaan"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Sluit Docs"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Sluit Alles"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Sluit Docs"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Starten"
@@ -6621,6 +6767,11 @@ msgstr "Debugger"
msgid "Search Results"
msgstr "Zoek Hulp"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Maak Leeg"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6694,6 +6845,7 @@ msgid "Syntax Highlighter"
msgstr "Syntax Markeren"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6729,26 +6881,6 @@ msgid "Toggle Comment"
msgstr "Commentaar Aan/Uit"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Toggle Favoriet"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Ga Naar Volgende Breekpunt"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Ga Naar Vorige Breekpunt"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Verwijder Alle Items"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Vouw/Ontvouw Regel"
@@ -6769,6 +6901,11 @@ msgid "Complete Symbol"
msgstr "Voltooi Symbool"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Schaal selectie"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Trim Navolgende Spaties"
@@ -6787,32 +6924,37 @@ msgid "Auto Indent"
msgstr "Auto Indentatie"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Breekpunt Aan- of Uitschakelen"
+msgid "Find Previous"
+msgstr "Vind Vorige"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Verwijder Alle Breekpunten"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Bestanden Filteren..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "Contextuele Hulp"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Ga Naar Volgende Breekpunt"
+msgid "Toggle Bookmark"
+msgstr "Toggle Favoriet"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Ga Naar Vorige Breekpunt"
+msgid "Go to Next Bookmark"
+msgstr "Ga Naar Volgende Breekpunt"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Vind Vorige"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Ga Naar Vorige Breekpunt"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Bestanden Filteren..."
+msgid "Remove All Bookmarks"
+msgstr "Verwijder Alle Items"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6825,8 +6967,23 @@ msgid "Go to Line..."
msgstr "Ga Naar Regel..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Contextuele Hulp"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Breekpunt Aan- of Uitschakelen"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Verwijder Alle Breekpunten"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Ga Naar Volgende Breekpunt"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Ga Naar Vorige Breekpunt"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -7016,9 +7173,14 @@ msgstr "Achter"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "Uitlijnen met zicht"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Arrangeer Selectie naar Aanzicht"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "Geen ouder om kind aan te instantiëren."
@@ -7073,8 +7235,9 @@ msgid "Audio Listener"
msgstr "Audio Luisteraar"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Inschakelen Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Activeer filtering"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7134,8 +7297,8 @@ msgid "Snap Nodes To Floor"
msgstr "Uitlijnen op raster"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Selectiestand (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7148,29 +7311,9 @@ msgstr ""
"Alt+RMB: Diepte selectie"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Beweegstand (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Rotatiestand (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Schaalstand (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Lokale Coördinaten"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr "Lokale Ruimtemodus (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Op hulplijnen uitlijnen"
+msgid "Use Local Space"
+msgstr "Lokale Ruimtemodus (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
@@ -7214,26 +7357,6 @@ msgid "Focus Selection"
msgstr "Focus Selectie"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Arrangeer Selectie naar Aanzicht"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Gereedschappen"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Beweeg Gereedschap"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Roteer Gereedschap"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Verschalen Gereedschap"
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Toggle Freelook"
msgstr "Toggle Favoriet"
@@ -7291,7 +7414,8 @@ msgstr "Bekijk Raster"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Instellingen"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7613,10 +7737,6 @@ msgid "TextureRegion"
msgstr "Textuur Regio"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Kan thema niet opslaan in bestand:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Alle Items Toevoegen"
@@ -7706,12 +7826,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Item"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Item"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7820,14 +7940,6 @@ msgid "Transpose"
msgstr "Transponeren"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Spiegel X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Spiegel Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7842,8 +7954,8 @@ msgstr "Teken Tegel"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8174,6 +8286,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Voeg invoer toe"
@@ -8267,6 +8383,11 @@ msgid "Duplicate Nodes"
msgstr "Dupliceer Graaf Knooppunt(en)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Plak Nodes"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Alles Selecteren"
@@ -8292,6 +8413,11 @@ msgstr "Rechts"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Creëer Node"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Creëer Node"
@@ -8370,6 +8496,22 @@ msgid "Color uniform."
msgstr "Transform vrijmaken"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8377,10 +8519,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "Verander Vec Constante"
@@ -8473,7 +8649,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8481,7 +8657,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8493,7 +8669,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8510,7 +8686,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8579,11 +8755,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8599,7 +8775,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8610,7 +8786,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8619,7 +8795,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8627,11 +8803,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8674,12 +8850,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr "Verander Textuur Uniform"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup."
msgstr "Verander Textuur Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr "Verander Textuur Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8689,7 +8870,7 @@ msgstr "Transformatie Dialoog..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8707,15 +8888,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8768,7 +8949,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8783,6 +8964,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8796,19 +8981,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8817,7 +9002,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8826,14 +9011,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8880,47 +9065,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9107,6 +9299,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Vermiste Exportsjablonen voor dit platform:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Beheer Export Templates"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exporteer Met Debug"
@@ -9270,6 +9466,15 @@ msgstr "Naamloos Project"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Importeer bestaand project"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Kan project niet openen"
@@ -9372,8 +9577,8 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
"Project uit de lijst verwijderen? (Inhoud van map wordt niet gewijzigd)"
@@ -9400,8 +9605,9 @@ msgid "Project Manager"
msgstr "Project Manager"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Projectlijst"
+#, fuzzy
+msgid "Projects"
+msgstr "Project"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9426,10 +9632,6 @@ msgid "Templates"
msgstr "Verwijder Selectie"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Sluiten"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Herstart Nu"
@@ -9789,6 +9991,10 @@ msgstr ""
msgid "AutoLoad"
msgstr "Automatisch Laden"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Nul"
@@ -9843,14 +10049,6 @@ msgstr "Selecteer Virtuele Method"
msgid "Select Method"
msgstr "Selecteer Method"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Kan PVRTC tool niet uitvoeren:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "Kan geconverteerd beeld niet laden met de PVRTC tool:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10163,6 +10361,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Verander Input Naam"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10212,6 +10415,11 @@ msgstr "Omschrijving:"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Voeg nieuwe knooppunt aan"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Klinkt logisch!"
@@ -10293,19 +10501,19 @@ msgstr "Knooppunt configuratie waarschuwing:"
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10404,6 +10612,11 @@ msgid "Error loading script from %s"
msgstr "Fout bij het laden script van %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Overschrijven"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Niet van toepassing"
@@ -10438,7 +10651,8 @@ msgid "Script is valid."
msgstr "Script geldig"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Toegestaan: a-z, A-Z, 0-9 en _"
#: editor/script_create_dialog.cpp
@@ -10605,6 +10819,10 @@ msgid "Change Shortcut"
msgstr "Wijzig Ankers"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Editor Instellingen"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Snelkoppelingen"
@@ -11040,10 +11258,31 @@ msgid "Set Variable Type"
msgstr "Variabele Bewerken:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Ongeldige naam. Mag niet botsen met een bestaande ingebouwde type naam."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Nieuwe knopen maken."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variabelen:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Nieuwe knopen maken."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Nieuwe veelhoek aanmaken."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Naam is geen geldige identifier:"
@@ -11248,10 +11487,6 @@ msgid "Cut Nodes"
msgstr "Knip Nodes"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Plak Nodes"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Leden"
@@ -12082,22 +12317,6 @@ msgstr ""
"hebt zijn inhoud direct op het scherm te weergeven. Anders, maak er een "
"RenderTarget van en wijs zijn interne texture toe aan een node om te tonen."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Error bij het initialiseren van FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Onbekende lettertype formaat."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Fout bij het laden van lettertype."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ongeldige lettertype grootte."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Invoer"
@@ -12111,6 +12330,11 @@ msgstr "Ongeldige bron voor shader."
msgid "Invalid source for shader."
msgstr "Ongeldige bron voor shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ongeldige bron voor shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -12127,6 +12351,131 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No Matches"
+#~ msgstr "Geen Overeenkomsten"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Kan niet schrijven in file_type_cache.cch, de bestandstype cache wordt "
+#~ "niet bewaard!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Kan niet naar '%s' navigeren omdat het niet in het bestandssysteem "
+#~ "gevonden is!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Error bij het laden van afbeelding:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Geen pixels met transparantie > 128 in afbeelding..."
+
+#, fuzzy
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Ouder heeft geen vaste vlakken om te bevolken."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Kon het gebied niet mappen."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Vlakken bevatten geen gebied!"
+
+#~ msgid "No faces!"
+#~ msgstr "Geen vlakken!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Map kon niet gemaakt worden."
+
+#, fuzzy
+#~ msgid "Error could not load file."
+#~ msgstr "Map kon niet gemaakt worden."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Inschakelen Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Selectiestand (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Beweegstand (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Rotatiestand (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Schaalstand (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Lokale Coördinaten"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Op hulplijnen uitlijnen"
+
+#~ msgid "Tool Select"
+#~ msgstr "Gereedschappen"
+
+#~ msgid "Tool Move"
+#~ msgstr "Beweeg Gereedschap"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Roteer Gereedschap"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Verschalen Gereedschap"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Project uit de lijst verwijderen? (Inhoud van map wordt niet gewijzigd)"
+
+#~ msgid "Project List"
+#~ msgstr "Projectlijst"
+
+#~ msgid "Exit"
+#~ msgstr "Sluiten"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Kan PVRTC tool niet uitvoeren:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "Kan geconverteerd beeld niet laden met de PVRTC tool:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Error bij het initialiseren van FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Onbekende lettertype formaat."
+
+#~ msgid "Error loading font."
+#~ msgstr "Fout bij het laden van lettertype."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ongeldige lettertype grootte."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Vorige Folder"
+
+#~ msgid "Next Folder"
+#~ msgstr "Volgende Folder"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Open de volgende Editor"
+
+#~ msgid "Reverse"
+#~ msgstr "Omkeren"
+
+#~ msgid "Mirror X"
+#~ msgstr "Spiegel X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Spiegel Y"
+
#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "Mislukt om resource te laden."
@@ -12640,9 +12989,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Verwijder Selectie"
-#~ msgid "Could not find tile:"
-#~ msgstr "Niet gevonden titel:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Item naam of identificatiecode:"
diff --git a/editor/translations/or.po b/editor/translations/or.po
new file mode 100644
index 0000000000..6745237b50
--- /dev/null
+++ b/editor/translations/or.po
@@ -0,0 +1,11324 @@
+# Odia translation of the Godot Engine editor
+# Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)
+# This file is distributed under the same license as the Godot source code.
+# Pro Neon <proneon267@gmail.com>, 2019.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2019-08-11 10:23+0000\n"
+"Last-Translator: Pro Neon <proneon267@gmail.com>\n"
+"Language-Team: Odia <https://hosted.weblate.org/projects/godot-engine/godot/"
+"or/>\n"
+"Language: or\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.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 "convert() କୠଅବୈଧ ପà­à¬°à¬•à¬¾à¬° ଯà­à¬•à­à¬¤à¬¿, ବà­à­Ÿà¬¬à¬¹à¬¾à¬° କର TYPE_* ସà­à¬¥à¬¿à¬°à¬¾à¬™à­à¬• |"
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr ""
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr ""
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+msgid "Create"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp 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 ""
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "FPS"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+#: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr ""
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select tracks to copy:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replaced %d occurrence(s)."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr ""
+
+#: editor/code_editor.cpp editor/rename_dialog.cpp
+msgid "Replace"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_settings_editor.cpp editor/script_create_dialog.cpp
+msgid "Path"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Remove selected files from the project? (Can't be restored)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio Bus, Drag and Drop to rearrange."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Enable"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Not in resource path."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr ""
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem and Import Docks"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "New Folder..."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Refresh"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/inspector_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Hidden Files"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Preview:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr ""
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr ""
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+msgid "Inherits:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Brief Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties:"
+msgstr ""
+
+#: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "enum "
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class Description:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There are currently no tutorials for this class, you can [color=$color][url="
+"$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/"
+"url][/color]."
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr ""
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr ""
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr ""
+
+#: editor/editor_log.cpp editor/editor_profiler.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project export failed with error code %d."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error trying to save layout!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Default editor layout overridden."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Restored default layout to base settings."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene was never saved, please save it prior to running."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr ""
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "No"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This scene has never been saved. Save before running?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This action cannot be undone. Revert anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr ""
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Revert Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When exporting or deploying, the resulting executable will attempt to "
+"connect to the IP of this computer in order to be debugged."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network FS"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, export or deploy will produce a minimal "
+"executable.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploy will use the USB cable for faster performance. This "
+"option speeds up testing for games with a large footprint."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: 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 ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Navigation meshes and polygons will be visible on the running game if this "
+"option is turned on."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Scene Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any changes made to the scene in the editor "
+"will be replicated in the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Sync Script Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is turned on, any script that is saved will be reloaded on "
+"the running game.\n"
+"When used remotely on a device, this is more efficient with network "
+"filesystem."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle Fullscreen"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle System Console"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data/Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
+msgid "Search"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Issue Tracker"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause the scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_profiler.cpp
+msgid "Stop"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Node"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr ""
+
+#: editor/editor_node.cpp scene/resources/visual_shader.cpp
+msgid "Output"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will install the Android project for custom builds.\n"
+"Note that, in order to use it, it needs to be enabled per export preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+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 ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_export.cpp
+msgid "Export Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Password:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr ""
+
+#: editor/editor_profiler.cpp editor/plugins/animation_state_machine_editor.cpp
+#: editor/rename_dialog.cpp
+msgid "Start"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr ""
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the export menu."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "There is already file or folder with the same name in this location."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Search complete"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid " Files"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr ""
+
+#: editor/import_dock.cpp editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Save scenes, re-import and restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr ""
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Language:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node Moved"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Error!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr ""
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Add Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed sha256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Reverse sorting."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/project_settings_editor.cpp
+msgid "Category:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene (for images to be saved in the same dir), or pick a save "
+"path from the BakedLightmap properties."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move pivot"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated 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 ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr ""
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Convex Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Failed creating shapes!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Shape(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Convex Collision Sibling(s)"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr ""
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon->UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV->Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Type:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Request Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Help improve the Godot documentation by giving feedback."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Source"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "(ignore)"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "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
+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
+msgid "Delete Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed (FPS):"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Icon"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output +"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete patch '%s' from list?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files from project (comma separated, e.g: *.json, *.txt)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Patches"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Make Patch"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path does not exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid '.zip' project file, does not contain a 'project.godot' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a 'project.godot' or '.zip' file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Directory already contains a Godot project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Shift+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Alt+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Control+"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per Level counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set the counter restarts for each group of child nodes"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "CamelCase to under_scored"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "under_scored to CamelCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Error"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear a script for the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script is valid."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Language"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Inherits"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Template"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Child Process Connected"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video Mem"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr ""
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Base Type:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Available Nodes:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "ADB executable not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgstr ""
+
+#: 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."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "No build apk generated at: "
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier segments must be of non-zero length."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "A digit cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid ""
+"The character '%s' cannot be the first character in a Identifier segment."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The Identifier must have at least one '.' separator."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "%d%%"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "(Time Left: %d:%02d s)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Meshes: "
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Plotting Lights:"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Lighting Meshes: "
+msgstr ""
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"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 ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the screen."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr ""
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+
+#: scene/resources/visual_shader.cpp
+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 ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index ff93299b81..df28369163 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -39,8 +39,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:47+0000\n"
-"Last-Translator: Rafał Wyszomirski <rawyszo@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -49,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -93,7 +93,6 @@ msgid "On call to '%s':"
msgstr "Przy wywołaniu \"%s\":"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Wolny"
@@ -162,6 +161,26 @@ msgid "Anim Change Call"
msgstr "Animacja - wywołanie funkcji"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Zmień czas wielu klatek animacji"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Zmień przejście wielu klatek animacji"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Zmień transformację wielu klatek animacji"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Zmień wartość wielu klatek animacji"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Zmień wywołanie wielu klatek animacji"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Zmień długość animacji"
@@ -509,7 +528,7 @@ msgstr "sekund"
#: editor/animation_track_editor.cpp
msgid "FPS"
-msgstr "Klatki na sekundÄ™"
+msgstr "klatek na sekundÄ™"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -662,16 +681,18 @@ msgid "Line Number:"
msgstr "Numer linii:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Zastąpiono %d wystąpień."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Nie znaleziono"
+#, fuzzy
+msgid "%d match."
+msgstr "Znaleziono %d dopasowań."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Zastąpiono %d wystąpień."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Znaleziono %d dopasowań."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -820,9 +841,8 @@ msgid "Connect"
msgstr "Połącz"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Sygnały:"
+msgstr "Sygnał:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -898,8 +918,7 @@ msgstr "Ulubione:"
msgid "Recent:"
msgstr "Ostatnie:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -987,9 +1006,8 @@ msgid "Owners Of:"
msgstr "Właściciele:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Usunąć wybrane pliki z projektu? (Nie można tego cofnąć)"
+msgstr "Usunąć wybrane pliki z projektu? (Nie można ich przywrócić)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1000,7 +1018,7 @@ msgstr ""
"Usuwany plik jest wymagany przez inne zasoby do działania.\n"
"Usunąć mimo to? (Nie można tego cofnąć)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nie można usunąć:"
@@ -1036,7 +1054,7 @@ msgstr "Permanentnie usuń %d obiekt(ów) (Nie można tego cofnąć)"
msgid "Show Dependencies"
msgstr "Pokaż zależności"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Eksplorator osieroconych zasobów"
@@ -1125,14 +1143,16 @@ msgid "License"
msgstr "Licencja"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licencja zewnętrzna"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine opiera się na wielu niezależnych i otwartych bibliotekach stron "
@@ -1153,7 +1173,8 @@ msgid "Licenses"
msgstr "Licencje"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "BÅ‚Ä…d otwierania pliku pakietu (nie jest w formacie zip)."
#: editor/editor_asset_installer.cpp
@@ -1170,7 +1191,6 @@ msgid "Success!"
msgstr "Sukces!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Zainstaluj"
@@ -1539,7 +1559,7 @@ msgstr "Nie znaleziono pliku szablonu:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "W eksportach 32-bitowych dołączony PCK nie może być większy niż 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1646,12 +1666,11 @@ msgid "New"
msgstr "Nowy"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importuj"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Eksportuj"
@@ -1712,7 +1731,7 @@ msgstr "Pokaż w menedżerze plików"
msgid "New Folder..."
msgstr "Utwórz katalog..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Odśwież"
@@ -1763,7 +1782,7 @@ msgstr "Dalej"
msgid "Go Up"
msgstr "W górę"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Przełącz ukryte pliki"
@@ -1788,23 +1807,27 @@ msgid "Move Favorite Down"
msgstr "Przesuń Ulubiony w dół"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Poprzedni folder"
+msgid "Go to previous folder."
+msgstr "Przejdź do poprzedniego folderu."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Następny folder"
+msgid "Go to next folder."
+msgstr "Przejdź do następnego folderu."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Przejdź folder wyżej."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Odśwież pliki."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Dodaj/usuń aktualny folder z ulubionych."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Przełącz widoczność ukrytych plików."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1934,7 +1957,7 @@ msgid ""
"url][/color]."
msgstr ""
"Obecnie nie ma żadnych samouczków dla tej klasy, możesz [color=$color][url="
-"$url]dodać jeden[/url][/color] lub [color=$color] [url=$url2]poprosić o "
+"$url]dodać jeden[/url][/color] lub [color=$color][url=$url2]poprosić o "
"jakiÅ›[/url][/color]."
#: editor/editor_help.cpp
@@ -2044,6 +2067,11 @@ msgstr "Wyczyść"
msgid "Clear Output"
msgstr "Wyczyść dane wyjściowe"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Okno"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Eksport projektu nie powiódł się, kod błędu to %d."
@@ -2367,6 +2395,15 @@ msgid "Pick a Main Scene"
msgstr "Wybierz główną scenę"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Zamknij scenÄ™"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Zamknij 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ę."
@@ -2479,6 +2516,11 @@ msgstr "Odtwórz tę scenę"
msgid "Close Tab"
msgstr "Zamknij kartÄ™"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Zamknij kartÄ™"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Zamknij inne karty"
@@ -2532,6 +2574,10 @@ msgid "Go to previously opened scene."
msgstr "Wróć do poprzednio otwartej sceny."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Skopiuj tekst"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Następna zakładka"
@@ -2559,6 +2605,10 @@ msgstr "Nowa scena dziedziczÄ…ca..."
msgid "Open Scene..."
msgstr "Otwórz scenę..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Ostatnio otwierane"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Zapisz scenÄ™"
@@ -2568,14 +2618,6 @@ msgid "Save All Scenes"
msgstr "Zapisz wszystkie sceny"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Zamknij scenÄ™"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Ostatnio otwierane"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konwertuj na..."
@@ -2599,31 +2641,42 @@ msgstr "Ponów"
#: editor/editor_node.cpp
msgid "Revert Scene"
-msgstr "Resetuj scenÄ™"
+msgstr "Przywróć scenę"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
msgstr "Różne narzędzia dla scen lub projektu."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Ustawienia projektu"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Narzędzia"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Eksport..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Zainstaluj szablon eksportu dla Androida"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Otwórz folder danych projektu"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Narzędzia"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Zainstaluj szablon eksportu dla Androida"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Eksplorator osieroconych zasobów"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2718,12 +2771,13 @@ msgstr ""
"(działające instancje będą zrestartowane). Opcja ta działa szybciej z "
"użyciem sieciowych systemów plików."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Edytor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Ustawienia edytora"
#: editor/editor_node.cpp
@@ -2739,14 +2793,6 @@ 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"
@@ -2767,14 +2813,16 @@ msgid "Open Editor Settings Folder"
msgstr "Otwórz folder ustawień edytora"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Zarządzaj funkcjonalnościami edytora"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "ZarzÄ…dzaj szablonami eksportu"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Pomoc"
@@ -2782,12 +2830,13 @@ msgstr "Pomoc"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Szukaj"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentacja online"
@@ -3063,6 +3112,10 @@ msgstr "Czas"
msgid "Calls"
msgstr "Wywołania"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Edytuj tekst:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "WÅ‚Ä…cz"
@@ -3235,7 +3288,8 @@ msgid "Import From Node:"
msgstr "Zaimportuj z węzła:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Pobierz ponownie"
#: editor/export_template_manager.cpp
@@ -3252,6 +3306,10 @@ msgid "Download"
msgstr "Pobierz"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Nie znaleziono)"
@@ -3315,12 +3373,10 @@ msgid "No response."
msgstr "Brak odpowiedzi."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Żądanie nie powiodło się."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Pętla przekierowań."
@@ -3334,15 +3390,22 @@ msgid "Download Complete."
msgstr "Pobieranie zakończone."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nie mogę zapisać motywu do pliku:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Instalacja szablonów się nie udała. Problematyczne archiwa szablonów mogą "
"być znalezione w \"%s\"."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Błąd podczas żądania adresu url: "
#: editor/export_template_manager.cpp
@@ -3427,21 +3490,11 @@ msgstr "Pobierz szablony eksportu"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Wybierz serwer z listy: (Shift+Klik: Otwórz w przeglądarce)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Nie udało się otworzyć pliku file_type_cache.cch do zapisu, pamięć podręczna "
-"typu plików nie będzie zapisana!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
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!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Status: Importowanie pliku nie powiodło się. Proszę naprawić plik i ponownie "
@@ -3476,14 +3529,14 @@ msgid "Provided name contains invalid characters."
msgstr "Podana nazwa zawiera niedozwolone znaki."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Nazwa zawiera niedozwolone znaki."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Plik lub katalog o tej nazwie już istnieje."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Nazwa zawiera niedozwolone znaki."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Zmiana nazwy pliku:"
@@ -3539,6 +3592,11 @@ msgstr "Duplikuj..."
msgid "Move To..."
msgstr "PrzenieÅ› do..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nowa scena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Nowy skrypt..."
@@ -3604,6 +3662,11 @@ msgstr "W tej lokalizacji istnieje już plik lub folder o podanej nazwie."
msgid "Overwrite"
msgstr "Nadpisz"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Utwórz ze sceny"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Utwórz Skrypt"
@@ -3666,6 +3729,14 @@ msgid "Search complete"
msgstr "Wyszukiwanie zakończone"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Dodaj do Grupy"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Usuń z Grupy"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Nazwa grupy już istnieje."
@@ -3673,12 +3744,23 @@ msgstr "Nazwa grupy już istnieje."
msgid "Invalid group name."
msgstr "Niewłaściwa nazwa grupy."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "ZarzÄ…dzaj grupami"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Usuń grupę obrazków"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupy"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Węzły nie w grupie"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3691,12 +3773,13 @@ msgid "Nodes in Group"
msgstr "Węzły w grupie"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Dodaj do Grupy"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Usuń z Grupy"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Edytor skryptów"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3906,7 +3989,8 @@ msgid "MultiNode Set"
msgstr "Zestaw wielowęzłowy"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Wybierz węzeł do edycji sygnałów i grup."
#: editor/plugin_config_dialog.cpp
@@ -4521,7 +4605,7 @@ msgstr "Przejście: "
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr "AnimationTree"
+msgstr "Drzewo animacji"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -4666,10 +4750,6 @@ msgid "View Files"
msgstr "Pokaż pliki"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Nie udało się odnaleźć hosta:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Błąd połączenia. Spróbuj ponownie."
@@ -4682,14 +4762,47 @@ msgid "No response from host:"
msgstr "Brak odpowiedzi hosta:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Nie udało się odnaleźć hosta:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Żądanie nie powiodło się, zwracany kod:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Żądanie nie powiodło się."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nie mogę zapisać motywu do pliku:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Żądanie nieudane, zbyt dużo przekierowań"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Pętla przekierowań."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Żądanie nie powiodło się, zwracany kod:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Czas"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
"Zły hash pobranego pliku. Zakładamy, że ktoś przy nim majstrował, lub został "
@@ -4732,6 +4845,10 @@ msgid "Idle"
msgstr "Bezczynny"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Zainstaluj..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Ponów Próbę"
@@ -4760,13 +4877,17 @@ msgid "Last"
msgstr "Koniec"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Wszystko"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importuj ponownie..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Wtyczki"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4774,8 +4895,8 @@ msgid "Sort:"
msgstr "Sortuj:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Odwróć"
+msgid "Reverse sorting."
+msgstr "Odwróć sortowanie."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4787,7 +4908,8 @@ msgid "Site:"
msgstr "Źródło:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Wsparcie..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4799,6 +4921,11 @@ msgid "Testing"
msgstr "Testowanie"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Wczytaj..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Plik ZIP assetów"
@@ -4856,32 +4983,32 @@ msgid "Rotation Step:"
msgstr "Krok obrotu:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Przesuń Pionową Prowadnicę"
+msgid "Move Vertical Guide"
+msgstr "Przesuń pionową prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Utwórz nową prowadnicę pionową"
+msgid "Create Vertical Guide"
+msgstr "Utwórz pionową prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Usuń prowadnicę pionową"
+msgid "Remove Vertical Guide"
+msgstr "Usuń pionową prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Przesuń prowadnicę poziomą"
+msgid "Move Horizontal Guide"
+msgstr "Przesuń poziomą prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Utwórz nową prowadnicę poziomą"
+msgid "Create Horizontal Guide"
+msgstr "Utwórz poziomą prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Usuń prowadnicę poziomą"
+msgid "Remove Horizontal Guide"
+msgstr "Usuń poziomą prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Utwórz nowe prowadnice: poziomą oraz pionową"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Utwórz poziomą i pionową prowadnicę"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4965,6 +5092,11 @@ msgid "Paste Pose"
msgstr "Wklej pozÄ™"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Wyczyść kości"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Utwórz własne kości z węzłów"
@@ -4995,6 +5127,7 @@ msgid "Zoom Reset"
msgstr "Zresetuj powiększenie"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Tryb zaznaczenia"
@@ -5017,14 +5150,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + RMB: Głębokość listy"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Tryb przesuwania"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Tryb Rotacji"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Tryb skalowania"
@@ -5050,6 +5186,7 @@ msgid "Toggle snapping."
msgstr "Przełącz przyciąganie."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Użyj przyciągania"
@@ -5066,11 +5203,6 @@ msgid "Use Rotation Snap"
msgstr "Użyj kroków obrotu"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Konfiguruj przyciÄ…ganie..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Przyciągaj względnie"
@@ -5083,6 +5215,11 @@ msgid "Smart Snapping"
msgstr "Inteligentne przyciÄ…ganie"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Konfiguruj przyciÄ…ganie..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "PrzyciÄ…gaj do rodzica"
@@ -5297,16 +5434,6 @@ msgstr "Ustaw Uchwyt"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "BÅ‚Ä…d wczytywania obrazu:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Brak pikseli z przeźroczystością > 128 w obrazie..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Wczytaj maskÄ™ emisji"
@@ -5448,7 +5575,7 @@ msgstr "Edytor listy elementów"
#: editor/plugins/light_occluder_2d_editor_plugin.cpp
msgid "Create Occluder Polygon"
-msgstr "Stwórz Occluder Polygon"
+msgstr "Utwórz wielokąt przesłaniający"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
@@ -5617,14 +5744,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Płaszczyzna jest niepoprawna (brak ścian)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Rodzic nie ma stałych powierzchni do zapełnienia."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Nie można zmapować obszaru."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Wybierz siatkę źródłową:"
@@ -5708,20 +5827,27 @@ msgid "Generation Time (sec):"
msgstr "Czas generowania (sek):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Åšciana nie ma powierzchni!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Węzeł nie zawiera geometrii (ściany)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Brak ścian!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Węzeł nie zawiera geometrii."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Węzeł nie zawiera geometrii (ściany)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Węzeł nie zawiera geometrii."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6053,7 +6179,6 @@ msgid "Grid Settings"
msgstr "Ustawienia siatki"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "PrzyciÄ…gaj"
@@ -6159,12 +6284,9 @@ msgid "Error writing TextFile:"
msgstr "BÅ‚Ä…d pisania pliku tekstowego:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Błąd: nie udało się wczytać pliku."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Błąd nie udało się wczytać pliku."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Nie mogłem znaleźć tile:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6187,7 +6309,8 @@ msgid "Error Importing"
msgstr "BÅ‚Ä…d importowania"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Nowy plik tekstowy..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6268,6 +6391,11 @@ msgid "Open..."
msgstr "Otwórz..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Otwórz skrypt"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Zapisz wszystko"
@@ -6305,13 +6433,13 @@ msgid "Save Theme"
msgstr "Zapisz motyw"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Zamknij pliki pomocy"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Zamknij wszystkie"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Zamknij pliki pomocy"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Uruchom"
@@ -6379,7 +6507,7 @@ msgid ""
"What action should be taken?:"
msgstr ""
"Następujące pliki są nowsze na dysku.\n"
-"Jakie działania należy podjąć?:"
+"Jakie działania powinny zostać podjęte?:"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -6399,6 +6527,11 @@ msgstr "Debugger"
msgid "Search Results"
msgstr "Wyniki wyszukiwania"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Wyczyść listę ostatnio otwieranych scen"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Połączenia do metody:"
@@ -6467,8 +6600,9 @@ msgid "Syntax Highlighter"
msgstr "Podświetlacz składni"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Idź do"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6476,9 +6610,8 @@ msgid "Bookmarks"
msgstr "Zakładki"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Utwórz punkty."
+msgstr "Punkty wstrzymania"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6502,22 +6635,6 @@ msgid "Toggle Comment"
msgstr "Przełącz komentarz"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Przełącz zakładkę"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Przejdź do następnej zakładki"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Przejdź do poprzedniej zakładki"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Usuń wszystkie zakładki"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Zwiń/rozwiń wiersz"
@@ -6538,6 +6655,11 @@ msgid "Complete Symbol"
msgstr "Uzupełnij symbol"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skaluj zaznaczone"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Przytnij końcowe spacje"
@@ -6554,29 +6676,32 @@ msgid "Auto Indent"
msgstr "Automatyczne wcięcie"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Przełącz punkt wstrzymania"
+msgid "Find Previous"
+msgstr "Znajdź poprzedni"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Usuń wszystkie punkty wstrzymania"
+msgid "Find in Files..."
+msgstr "Znajdź w plikach..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Przejdź do następnego punktu wstrzymania"
+msgid "Contextual Help"
+msgstr "Pomoc kontekstowa"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Przejdź do poprzedniego punktu wstrzymania"
+msgid "Toggle Bookmark"
+msgstr "Przełącz zakładkę"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Znajdź poprzedni"
+msgid "Go to Next Bookmark"
+msgstr "Przejdź do następnej zakładki"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Znajdź w plikach..."
+msgid "Go to Previous Bookmark"
+msgstr "Przejdź do poprzedniej zakładki"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Usuń wszystkie zakładki"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6587,8 +6712,21 @@ msgid "Go to Line..."
msgstr "Przejdź do linii..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Pomoc kontekstowa"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Przełącz punkt wstrzymania"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Usuń wszystkie punkty wstrzymania"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Przejdź do następnego punktu wstrzymania"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Przejdź do poprzedniego punktu wstrzymania"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6767,8 +6905,12 @@ msgid "Rear"
msgstr "Tył"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Dopasuj do widoku"
+msgid "Align Transform with View"
+msgstr "Dopasuj położenie do widoku"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Dopasuj obrót do widoku"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6823,8 +6965,9 @@ msgid "Audio Listener"
msgstr "Słuchacz dźwięku"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Efekt Dopplera"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "WÅ‚Ä…cz filtrowanie"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6879,8 +7022,8 @@ msgid "Snap Nodes To Floor"
msgstr "Przyciągnij węzły do podłogi"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Tryb zaznaczenia (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6893,30 +7036,11 @@ msgstr ""
"Alt+PPM: Lista wyboru głębi"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Tryb Przesuwania (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Tryb Rotacji (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Tryb skalowania (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Lokalne koordynaty"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Tryb lokalny przestrzeni (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Tryb przyciÄ…gania (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Widok z dołu"
@@ -6957,26 +7081,6 @@ msgid "Focus Selection"
msgstr "Wycentruj na zaznaczeniu"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Dopasuj zaznaczenie do widoku"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Narzędzie wyboru"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Narzędzie poruszania"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Narzędzie obracania"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Narzędzie skalowania"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Przełącz swobodny widok"
@@ -7031,7 +7135,8 @@ msgstr "Pokaż siatkę"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Ustawienia"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7325,10 +7430,6 @@ msgid "TextureRegion"
msgstr "Obszar tekstury"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Nie mogę zapisać motywu do pliku:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Dodaj wszystkie elementy"
@@ -7413,11 +7514,13 @@ msgid "Submenu"
msgstr "Podmenu"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Element 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Element 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7522,14 +7625,6 @@ msgid "Transpose"
msgstr "Transpozycja"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Odbij X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Odbij Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Wyłącz autokafelki"
@@ -7542,9 +7637,10 @@ msgid "Paint Tile"
msgstr "Maluj kafelek"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+PPM: Rysuj liniÄ™\n"
"Shift+Ctrl+PPM: Maluj prostokÄ…t"
@@ -7841,6 +7937,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Tylko GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Dodaj wejście+"
@@ -7917,6 +8017,11 @@ msgid "Duplicate Nodes"
msgstr "Duplikuj węzły"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Wklej węzły"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Usuń węzły"
@@ -7937,6 +8042,11 @@ msgid "Light"
msgstr "Światło"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Utwórz węzeł shadera"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Utwórz węzeł shadera"
@@ -8009,6 +8119,22 @@ msgid "Color uniform."
msgstr "Uniform koloru."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Zwraca wynik boolowski porównania %s pomiędzy dwoma parametrami."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Równe (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Większe niż (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Większe lub równe (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8017,12 +8143,48 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "Zwraca wynik boolowski porównania pomiędzy INF i parametrem skalarnym."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr "Zwraca wynik boolowski porównania pomiędzy NaN i parametrem skalarnym."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Mniejsze niż (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Mniejsze lub równe (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Nierówne (!=)"
+
+#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Zwraca wynik boolowski porównania pomiędzy dwoma parametrami."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Zwraca wynik boolowski porównania pomiędzy INF (lub NaN) i parametrem "
+"skalarnym."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Stała prawda/fałsz."
@@ -8113,16 +8275,16 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "Zwraca arcus cosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr "(Tylko GLES3) Zwraca odwrócony cosinus hiperboliczny parametru."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Zwraca odwrócony cosinus hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "Zwraca arcus sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr "(Tylko GLES3) Zwraca odwrócony sinus hiperboliczny parametru."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Zwraca odwrócony sinus hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8133,8 +8295,8 @@ msgid "Returns the arc-tangent of the parameters."
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 "(Tylko GLES3) Zwraca odwrócony tangens hiperboliczny parametru."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Zwraca odwrócony tangens hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8150,8 +8312,8 @@ msgid "Returns the cosine of the parameter."
msgstr "Zwraca cosinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(Tylko GLES3) Zwraca cosinus hiperboliczny parametru."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Zwraca cosinus hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8219,13 +8381,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / skalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Tylko GLES3) Znajduje najbliższą parametrowi liczbę całkowitą."
+msgid "Finds the nearest integer to the parameter."
+msgstr "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ą."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "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."
@@ -8240,18 +8401,19 @@ msgid "Returns the sine of the parameter."
msgstr "Zwraca sinus parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(Tylko GLES3) Zwraca sinus hiperboliczny parametru."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Zwraca sinus hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Zwraca pierwiastek kwadratowy parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8263,10 +8425,11 @@ msgstr ""
"pomiędzy 0.0 i 1.0 używając wielomianów Hermite'a."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Funkcja przejścia( skalar(krawędź), skalar(x) ).\n"
"\n"
@@ -8277,12 +8440,12 @@ msgid "Returns the tangent of the parameter."
msgstr "Zwraca tangens parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr "(Tylko GLES3) Zwraca tangens hiperboliczny parametru."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Zwraca tangens hiperboliczny parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr "(Tylko GLES3) Zwraca obciętą wartość parametru."
+msgid "Finds the truncated value of the parameter."
+msgstr "Zwraca obciętą wartość parametru."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8321,12 +8484,16 @@ msgid "Perform the texture lookup."
msgstr "Wykonaj podejrzenie tekstury."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Uniform tekstury kubicznej."
+msgid "Cubic texture uniform lookup."
+msgstr "Podejrzenie uniformu tekstury kubicznej."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr "Podejrzenie uniformu tekstury 2D."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "Uniform tekstury 2D."
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Podejrzenie uniformu tekstury 2D triplanarnej."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8334,7 +8501,7 @@ msgstr "Funkcja transformacji."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8342,6 +8509,13 @@ 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 ""
+"Oblicz iloczyn diadyczny pary wektorów.\n"
+"\n"
+"OuterProduct traktuje pierwszy parametr \"c\" jako kolumnowy wektor (macierz "
+"z jedną kolumną) i drugi parametr \"r\" jako rzędowy wektor (macierz z "
+"jednym rzędem) i wykonuje mnożenie macierzy \"c * r\" dając w wyniku "
+"macierz, której ilość rzędów odpowiada ilości komponentów w \"c\" oraz "
+"której ilość kolumn to liczba komponentów w 'r'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
@@ -8352,16 +8526,16 @@ msgid "Decomposes transform to four vectors."
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 "(Tylko GLES3) Liczy wyznacznik przekształcenia."
+msgid "Calculates the determinant of a transform."
+msgstr "Liczy wyznacznik przekształcenia."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(Tylko GLES3) Liczy odwrotność przekształcenia."
+msgid "Calculates the inverse of a transform."
+msgstr "Liczy odwrotność przekształcenia."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(Tylko GLES3) Liczy transpozycję przekształcenia."
+msgid "Calculates the transpose of a transform."
+msgstr "Liczy transpozycję przekształcenia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8409,11 +8583,16 @@ msgstr "Liczy iloczyn skalarny dwóch wektorów."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"Zwraca wektor, który wskazuje ten sam kierunek co wektor odniesienia. "
+"Funkcja posiada trzy parametry wektorowe: N, wektor do orientacji, I, wektor "
+"padający i Nref, wektor odniesienia. Jeżeli iloczyn skalarny I i Nref jest "
+"mniejszy od zera, zwracana jest wartość N. W przeciwnym razie zwracana jest "
+"wartość -N."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
@@ -8424,6 +8603,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Liniowo interpoluje pomiędzy dwoma wektorami."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Liniowo interpoluje pomiędzy dwoma wektorami."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Liczy znormalizowany wektor."
@@ -8437,21 +8621,22 @@ msgstr "1.0 / wektor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+msgid "Returns the vector that points in the direction of refraction."
msgstr "Zwraca wektor skierowany w kierunku załamania."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8463,10 +8648,11 @@ msgstr ""
"pomiędzy 0.0 i 1.0 używając wielomianów Hermite'a."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8478,20 +8664,22 @@ msgstr ""
"pomiędzy 0.0 i 1.0 używając wielomianów Hermite'a."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Funkcja przejścia( skalar(krawędź), wektor(x) ).\n"
"\n"
@@ -8531,6 +8719,9 @@ 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 ""
+"Własne wyrażenie w języku shaderów Godota, z własną ilością portów wejścia i "
+"wyjścia. To jest bezpośrednie wstrzyknięcie kodu do funkcji wierzchołków/"
+"fragmentów/światła, nie używaj tego do deklarowania tych funkcji w środku."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8541,62 +8732,67 @@ msgstr ""
"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."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
-"(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."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(Tylko tryb fragmentów/światła) Skalarna pochodna funkcji."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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."
+"(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'."
+"(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\"."
+"(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'."
+"(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\"."
+"(Tylko tryb fragmentów/światła) (Skalar) Suma bezwzględnej pochodnej po \"x"
+"\" i \"y\"."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8716,7 +8912,7 @@ msgstr "Utwórz ścieżkę"
#: editor/project_export.cpp
msgid "Features"
-msgstr "Funkcje"
+msgstr "Funkcjonalności"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -8771,6 +8967,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Brakuje eksportu szablonów dla tej platformy:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "ZarzÄ…dzaj szablonami eksportu"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Eksport z debugowaniem"
@@ -8930,6 +9130,15 @@ msgid "Unnamed Project"
msgstr "Projekt bez nazwy"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importuj istniejÄ…cy projekt"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Nie można otworzyć projektu w \"%s\"."
@@ -9026,12 +9235,13 @@ msgstr ""
"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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Usunąć wszystkie brakujące projekty z listy? (Zawartość folderów nie "
-"zostanie zmodyfikowana)"
+"Usunąć %d projektów z listy?\n"
+"Zawartość folderów projektów nie zostanie zmodyfikowana."
#: editor/project_manager.cpp
msgid ""
@@ -9055,8 +9265,9 @@ msgid "Project Manager"
msgstr "Menedżer projektów"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Lista projektów"
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9079,10 +9290,6 @@ msgid "Templates"
msgstr "Szablony"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Wyjdź"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Uruchom ponownie"
@@ -9422,6 +9629,10 @@ msgstr "Lokalizacje:"
msgid "AutoLoad"
msgstr "Autoładowanie"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Wtyczki"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9474,15 +9685,6 @@ msgstr "Wybierz metoda wirtualnÄ…"
msgid "Select Method"
msgstr "Wybierz metodÄ™"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Nie można wykonać narzędzia PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"Nie można załadować przekonwertowanego obrazka używając narzędzia PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Grupowa zmiana nazwy"
@@ -9778,6 +9980,11 @@ msgid "Remove Node(s)"
msgstr "Usuń węzeł(y)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Zmień nazwę portu wyjściowego"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9822,6 +10029,10 @@ msgid "Extend Script"
msgstr "Rozszerz skrypt"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Zmień nadrzędny węzeł"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Zmień na korzeń sceny"
@@ -9839,7 +10050,7 @@ msgstr "Skopiuj ścieżkę węzła"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
-msgstr "Usuń (bez potwierdzenie)"
+msgstr "Usuń (bez potwierdzenia)"
#: editor/scene_tree_dock.cpp
msgid "Add/Create a New Node."
@@ -9887,31 +10098,34 @@ msgstr "Grupa przycisków"
#: editor/scene_tree_editor.cpp
msgid "(Connecting From)"
-msgstr "(Połączenie z)"
+msgstr "(Å‚Ä…czony teraz)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
msgstr "Ostrzeżenie konfiguracji węzła:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Węzeł posiada połączenie(a) i grupę(y).\n"
"Kliknij, aby wyświetlić panel sygnałów."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Węzeł posiada połączenia.\n"
"Kliknij, aby wyświetlić panel sygnałów."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Węzeł jest w grupach.\n"
@@ -10010,6 +10224,11 @@ msgid "Error loading script from %s"
msgstr "BÅ‚Ä…d Å‚adowania skryptu z %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Nadpisz"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
@@ -10038,8 +10257,8 @@ msgid "Script is valid."
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 _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Dozwolone: a-z, A-Z, 0-9, _ i ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10198,6 +10417,10 @@ msgid "Change Shortcut"
msgstr "Zmień skrót"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Ustawienia edytora"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Skróty"
@@ -10615,10 +10838,30 @@ msgid "Set Variable Type"
msgstr "Ustaw typ zmiennej"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Nie może kolidować z nazwą istniejącego wbudowanego typu."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Utwórz nowy prostokąt."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Zmienne:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Utwórz nowy prostokąt."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Utwórz nowy wielokąt."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Nazwa nie jest prawidłowym identyfikatorem:"
@@ -10807,10 +11050,6 @@ msgid "Cut Nodes"
msgstr "Wytnij Węzły"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Wklej węzły"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Edytuj członka"
@@ -10924,15 +11163,20 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"Własny build wymaga poprawnej ścieżki do SDK Androida w Ustawieniach Edytora."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"Niepoprawna ścieżka do SDK Androida dla własnego builda w Ustawieniach "
+"Edytora."
#: platform/android/export/export.cpp
msgid ""
"Android project is not installed for compiling. Install from Editor menu."
msgstr ""
+"Projekt Androida nie jest zainstalowany do kompilacji. Zainstaluj z menu "
+"Edytor."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -10947,6 +11191,8 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"Próbowano zbudować z własnego szablonu, ale nie istnieje dla niego "
+"informacja o wersji. Zainstaluj ponownie z menu \"Projekt\"."
#: platform/android/export/export.cpp
msgid ""
@@ -10955,20 +11201,27 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"Niezgodna wersja buildu Androida:\n"
+" Zainstalowany szablon: %s\n"
+" Wersja Godota: %s\n"
+"Zainstaluj ponownie szablon z menu \"Projekt\"."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "Budowanie projektu Androida (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 ""
+"Budowanie projektu Androida się nie powiodło, sprawdź wyjście błędu.\n"
+"Alternatywnie, odwiedź docs.godotengine.org po dokumentację budowania dla "
+"Androida."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "Nie wygenerowano budowanego apk w: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -11092,13 +11345,12 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
-"Aby AnimatedSprite pokazywał poszczególne klatki, pole Frames musi zawierać "
-"odpowiedni zasób SpriteFrames."
+"Właściwość \"Frames\" musi zawierać odpowiedni zasób SpriteFrames, aby "
+"AnimatedSprite wyświetlał klatki."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11128,7 +11380,8 @@ msgid ""
msgstr ""
"CollisionPolygon2D 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."
+"obiektów typu Area2D, StaticBody2D, RigidBody2D, KinematicBody2D itp. by "
+"nadać im kształt."
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
@@ -11142,7 +11395,8 @@ msgid ""
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."
+"obiektów typu Area2D, StaticBody2D, RigidBody2D, KinematicBody2D itp. by "
+"nadać im kształt."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -11161,24 +11415,24 @@ msgstr ""
"\"Particles Animation\"."
#: scene/2d/light_2d.cpp
-#, fuzzy
msgid ""
"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."
+"Tekstura z kształtem promieni światła musi być dostarczona do właściwości "
+"\"Texture\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
"An occluder polygon must be set (or drawn) for this occluder to take effect."
msgstr ""
-"Wielokąt zasłaniający musi być ustawiony (lub narysowany) aby Occluder "
-"zadziałał."
+"Wielokąt przesłaniający musi być ustawiony (lub narysowany), aby ten "
+"przesłaniacz zadziałał."
#: scene/2d/light_occluder_2d.cpp
-#, fuzzy
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
-msgstr "Poligon zasłaniający jest pusty. Proszę narysować poligon!"
+msgstr ""
+"Wielokąt przesłaniający dla tego przesłaniacza jest pusty. Narysuj wielokąt."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11265,29 +11519,26 @@ msgstr ""
"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."
+"Węzeł TileMap z włączonym Use Parent potrzebuje nadrzędnego węzła "
+"CollisionObject2D, by dać mu kształty. Używaj go jako dziecko węzłów Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D itp. by nadać im kształt."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"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."
+"VisibilityEnabler2D działa najlepiej, gdy jest użyty bezpośrednio pod "
+"korzeniem aktualnie edytowanej sceny."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera musi dziedziczyć po węźle ARVROrigin"
+msgstr "ARVRCamera musi posiadać węzeł ARVROrigin jako nadrzędny."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11360,7 +11611,8 @@ msgid ""
msgstr ""
"CollisionPolygon służy jedynie do określenia kształtu kolizji dla jednego z "
"obiektów dziedziczących z CollisionObject. Używaj go tylko jako dziecko "
-"obiektów typu Area, StaticBody, RigidBody, KinematicBody itd."
+"obiektów typu Area, StaticBody, RigidBody, KinematicBody itp. by nadać im "
+"kształt."
#: scene/3d/collision_polygon.cpp
msgid "An empty CollisionPolygon has no effect on collision."
@@ -11374,16 +11626,15 @@ msgid ""
msgstr ""
"CollisionShape służy jedynie do określenia kształtu kolizji dla jednego z "
"węzłów dziedziczących z CollisionObject. Używaj go tylko jako dziecko węzłów "
-"typu Area, StaticBody, RigidBody, KinematicBody itd."
+"typu Area, StaticBody, RigidBody, KinematicBody itp. by nadać im kształt."
#: scene/3d/collision_shape.cpp
-#, fuzzy
msgid ""
"A shape must be provided for CollisionShape to function. Please create a "
"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!"
+"Kształt musi być zapewniony, aby CollisionShape zadziałał. Utwórz dla niego "
+"zasób typu CollisionShape."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11419,7 +11670,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "SpotLight z kątem szerszym niż 90 stopni nie może rzucać cieni."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11464,13 +11715,12 @@ 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'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."
+"Właściwość ROTATION_ORIENTED węzła PathFollow wymaga włączonego \"Up Vector"
+"\" w zasobie Curve jego nadrzędnego węzła Path."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11483,11 +11733,12 @@ msgstr ""
"Zamiast tego, zmień rozmiary kształtów kolizji w węzłach podrzędnych."
#: scene/3d/remote_transform.cpp
-#, 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."
+msgstr ""
+"Właściwość \"Remote Path\" musi wskazywać na poprawny węzeł typu Spatial lub "
+"pochodnego."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11504,13 +11755,12 @@ 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 "
"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."
+"Właściwość \"Frames\" musi zawierać odpowiedni zasób SpriteFrames, aby "
+"AnimatedSprite3D wyświetlał klatki."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11525,6 +11775,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment wymaga, by jego właściwość \"Environment\" posiadała zasób "
+"Environment, by mieć widoczny efekt."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11562,9 +11814,8 @@ msgid "Nothing connected to input '%s' of node '%s'."
msgstr "Nic nie podłączono do wejścia \"%s\" węzła \"%s\"."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "Korzeń dla grafu AnimationNode nie jest ustawiony."
+msgstr "Nie ustawiono korzenia AnimationNode dla grafu."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11577,7 +11828,6 @@ msgstr ""
"Ścieżka do węzła AnimationPlayer nie prowadzi do węzła AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
msgstr "Korzeń AnimationPlayer nie jest poprawnym węzłem."
@@ -11606,7 +11856,6 @@ msgid "Add current color as a preset."
msgstr "Dodaj bieżący kolor do zapisanych."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
@@ -11614,8 +11863,7 @@ msgid ""
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\"."
+"Jeśli nie zamierzasz dodać skryptu, zamiast tego użyj zwykłego węzła Control."
#: scene/gui/control.cpp
msgid ""
@@ -11634,32 +11882,28 @@ 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, 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."
+"dowolnej funkcji popup*(). Ustawienie ich jako widocznych do edycji jest w "
+"porzÄ…dku, ale zostanÄ… ukryte po uruchomieniu."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Jeśli \"Exp Edit\" jest włączone, \"Min Value\" musi być większe od 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer jest zaprojektowany do działania z jednym dzieckiem klasy "
-"Control.\n"
-"Użyj kontenera jako dziecko (VBox,HBox,etc), lub węzła klasy Control i ustaw "
-"ręcznie minimalny rozmiar."
+"ScrollContainer jest zaprojektowany do działania z jedną potomną kontrolką.\n"
+"Użyj kontenera jako dziecko (VBox, HBox, itp.) lub węzła typu Control i "
+"ustaw minimalny rozmiar ręcznie."
#: scene/gui/tree.cpp
msgid "(Other)"
@@ -11685,35 +11929,22 @@ msgstr ""
"otrzymał jakiś rozmiar. W przeciwnym wypadku ustawi opcję RenderTarget i "
"przyporządkuj jego teksturę dla któregoś węzła."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "BÅ‚Ä…d przy inicjalizacji FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Nieznany format czcionki."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "BÅ‚Ä…d Å‚adowania fonta."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Niepoprawny rozmiar fonta."
-
#: scene/resources/visual_shader.cpp
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."
+msgstr "Nieprawidłowe źródło do podglądu."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Niewłaściwe źródło dla shadera."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Niewłaściwa funkcja porównania dla tego typu."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Przypisanie do funkcji."
@@ -11730,6 +11961,128 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchołków."
msgid "Constants cannot be modified."
msgstr "Stałe nie mogą być modyfikowane."
+#~ msgid "No Matches"
+#~ msgstr "Nie znaleziono"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Nie udało się otworzyć pliku file_type_cache.cch do zapisu, pamięć "
+#~ "podręczna typu plików nie będzie zapisana!"
+
+#~ 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!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "BÅ‚Ä…d wczytywania obrazu:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Brak pikseli z przeźroczystością > 128 w obrazie..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Rodzic nie ma stałych powierzchni do zapełnienia."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Nie można zmapować obszaru."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Åšciana nie ma powierzchni!"
+
+#~ msgid "No faces!"
+#~ msgstr "Brak ścian!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Błąd: nie udało się wczytać pliku."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Błąd nie udało się wczytać pliku."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Efekt Dopplera"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Tryb zaznaczenia (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Tryb Przesuwania (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Tryb Rotacji (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Tryb skalowania (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Lokalne koordynaty"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Tryb przyciÄ…gania (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Narzędzie wyboru"
+
+#~ msgid "Tool Move"
+#~ msgstr "Narzędzie poruszania"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Narzędzie obracania"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Narzędzie skalowania"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Usunąć wszystkie brakujące projekty z listy? (Zawartość folderów nie "
+#~ "zostanie zmodyfikowana)"
+
+#~ msgid "Project List"
+#~ msgstr "Lista projektów"
+
+#~ msgid "Exit"
+#~ msgstr "Wyjdź"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Nie można wykonać narzędzia PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "Nie można załadować przekonwertowanego obrazka używając narzędzia PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "BÅ‚Ä…d przy inicjalizacji FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Nieznany format czcionki."
+
+#~ msgid "Error loading font."
+#~ msgstr "BÅ‚Ä…d Å‚adowania fonta."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Niepoprawny rozmiar fonta."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Poprzedni folder"
+
+#~ msgid "Next Folder"
+#~ msgstr "Następny folder"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Automatycznie otwórz zrzuty ekranu"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Otwórz w zewnętrznym edytorze obrazów."
+
+#~ msgid "Reverse"
+#~ msgstr "Odwróć"
+
+#~ msgid "Mirror X"
+#~ msgstr "Odbij X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Odbij Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Generowanie solucji..."
@@ -12323,9 +12676,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Erase selection"
#~ msgstr "Usuń zaznaczenie"
-#~ msgid "Could not find tile:"
-#~ msgstr "Nie mogłem znaleźć tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nazwa elementu lub ID:"
@@ -12574,9 +12924,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Info"
#~ msgstr "Informacje"
-#~ msgid "Re-Import..."
-#~ msgstr "Importuj ponownie..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Brak mask bitowych do zaimportowania!"
@@ -12944,9 +13291,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Stereo"
#~ msgstr "Stereo"
-#~ msgid "Window"
-#~ msgstr "Okno"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Skalowanie do %s%%."
@@ -13135,9 +13479,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Add Image Group"
#~ msgstr "Dodaj grupę obrazków"
-#~ msgid "Delete Image Group"
-#~ msgstr "Usuń grupę obrazków"
-
#~ msgid "Project Export Settings"
#~ msgstr "Opcje eksportu projektu"
@@ -13189,9 +13530,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Export Project PCK"
#~ msgstr "Eksport projektu PCK"
-#~ msgid "Export..."
-#~ msgstr "Eksport..."
-
#~ msgid "Project Export"
#~ msgstr "Eksport projektu"
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 95c567a176..e9d7b98fac 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -65,7 +65,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -143,6 +142,31 @@ msgid "Anim Change Call"
msgstr "Change yer Anim Call"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Change yer Anim Value"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Change yer Anim Transition"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Change yer Anim Transform"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Change yer Anim Value"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Change yer Anim Call"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -637,15 +661,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -878,8 +902,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -973,7 +996,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -1009,7 +1032,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1098,14 +1121,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1122,7 +1145,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1139,7 +1162,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1624,12 +1646,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1695,7 +1716,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1746,7 +1767,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1772,24 +1793,28 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Slit th' Node"
+msgid "Go to previous folder."
+msgstr "Toggle ye Breakpoint"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Slit th' Node"
+msgid "Go to next folder."
+msgstr "Toggle ye Breakpoint"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2031,6 +2056,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2329,6 +2358,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2424,6 +2461,11 @@ msgstr ""
msgid "Close Tab"
msgstr "Close"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Close"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2478,6 +2520,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Forge yer Node!"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2505,20 +2552,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2551,16 +2594,21 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Edit"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
@@ -2568,8 +2616,12 @@ msgstr ""
msgid "Open Project Data Folder"
msgstr "Slit th' Node"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2649,13 +2701,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "Editor"
msgstr "Edit"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2671,14 +2723,6 @@ 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 ""
@@ -2700,14 +2744,15 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr "Discharge ye' Variable"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2715,12 +2760,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2997,6 +3043,11 @@ msgstr ""
msgid "Calls"
msgstr "Call"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "th' Members:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3160,7 +3211,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3177,6 +3228,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3240,12 +3295,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3259,16 +3312,21 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
-msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+msgid "Cannot remove temporary file:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "Rename Variable"
+
+#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
msgstr ""
@@ -3356,19 +3414,11 @@ msgstr "Discharge ye' Variable"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3403,11 +3453,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3470,6 +3520,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3536,6 +3590,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Yar, Blow th' Selected Down!"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3598,6 +3657,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3606,12 +3673,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "Yer unique name be evil."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Rename Function"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Slit th' Node"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3625,12 +3702,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Edit"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3839,7 +3917,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4609,10 +4687,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4625,14 +4699,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4673,6 +4775,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4701,13 +4807,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4715,7 +4823,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4728,7 +4836,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4740,6 +4848,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4790,33 +4902,37 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Discharge ye' Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4901,6 +5017,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Change yer Anim Transform"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4930,6 +5051,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4950,14 +5072,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Slit th' Node"
@@ -4983,6 +5108,7 @@ msgid "Toggle snapping."
msgstr "Toggle ye Breakpoint"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4999,11 +5125,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5016,6 +5137,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5227,16 +5353,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5552,14 +5668,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5643,19 +5751,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5993,7 +6105,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6099,11 +6210,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6132,7 +6239,7 @@ msgid "Error Importing"
msgstr "Error loading yer Calligraphy Pen."
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6215,6 +6322,11 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Edit"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6253,11 +6365,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6347,6 +6459,10 @@ msgstr ""
msgid "Search Results"
msgstr "Discharge ye' Variable"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6416,6 +6532,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6453,26 +6570,6 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Toggle ye Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Toggle ye Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Toggle ye Breakpoint"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Discharge ye' Variable"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "Yar, Blow th' Selected Down!"
@@ -6493,6 +6590,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6509,32 +6611,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Toggle ye Breakpoint"
+msgid "Find Previous"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Find ye Node Type"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Toggle Bookmark"
msgstr "Toggle ye Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Next Bookmark"
msgstr "Toggle ye Breakpoint"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Toggle ye Breakpoint"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Find ye Node Type"
+msgid "Remove All Bookmarks"
+msgstr "Discharge ye' Variable"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6546,9 +6653,24 @@ msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Toggle ye Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Toggle ye Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Toggle ye Breakpoint"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6726,7 +6848,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6782,8 +6908,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Change"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6836,9 +6963,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Slit th' Node"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6848,27 +6974,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6912,27 +7018,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "Yar, Blow th' Selected Down!"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Toggle Freelook"
msgstr "Toggle ye Breakpoint"
@@ -6988,7 +7073,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7293,10 +7378,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7387,11 +7468,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7500,14 +7581,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7522,8 +7595,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7832,6 +7905,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Add Signal"
@@ -7916,6 +7993,11 @@ msgid "Duplicate Nodes"
msgstr "Rename Variable"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Paste yer Node"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Slit th' Node"
@@ -7937,6 +8019,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -8012,6 +8098,22 @@ msgid "Color uniform."
msgstr "Change yer Anim Transform"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8019,10 +8121,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8111,7 +8247,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8119,7 +8255,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8131,7 +8267,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8148,7 +8284,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8217,11 +8353,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8237,7 +8373,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8248,7 +8384,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8257,7 +8393,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8265,11 +8401,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8310,11 +8446,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8323,7 +8463,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8341,15 +8481,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8399,7 +8539,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8414,6 +8554,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8427,19 +8571,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8448,7 +8592,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8457,14 +8601,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8509,47 +8653,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8719,6 +8870,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8867,6 +9022,15 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Rename Function"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8936,8 +9100,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8957,8 +9121,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Rename Function"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8983,10 +9148,6 @@ msgid "Templates"
msgstr "Discharge ye' Variable"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9324,6 +9485,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9378,14 +9543,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9674,6 +9831,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9717,6 +9878,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9794,19 +9960,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9902,6 +10068,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9932,7 +10102,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10096,6 +10266,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10526,10 +10700,29 @@ msgid "Set Variable Type"
msgstr "Edit yer Variable:"
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Yar, Blow th' Selected Down!"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Yer variables:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Yar, Blow th' Selected Down!"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Yar, Blow th' Selected Down!"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Yer name's got no valid identifier:"
@@ -10731,10 +10924,6 @@ msgid "Cut Nodes"
msgstr "Slit th' Node"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Paste yer Node"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "th' Members:"
@@ -11474,22 +11663,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Cant Load the FreeType Captain."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Unknown Calligraphy format."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Error loading yer Calligraphy Pen."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Yer Calligraphy be wrongly sized."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11504,6 +11677,11 @@ msgstr "Yer Calligraphy be wrongly sized."
msgid "Invalid source for shader."
msgstr "Yer Calligraphy be wrongly sized."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Yer Calligraphy be wrongly sized."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11521,6 +11699,34 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Slit th' Node"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "Yar, Blow th' Selected Down!"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Cant Load the FreeType Captain."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Unknown Calligraphy format."
+
+#~ msgid "Error loading font."
+#~ msgstr "Error loading yer Calligraphy Pen."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Yer Calligraphy be wrongly sized."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Slit th' Node"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Slit th' Node"
+
+#, fuzzy
#~ msgid "Custom Node"
#~ msgstr "Slit th' Node"
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index c9b8697dd6..3a42ddaad7 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -64,12 +64,14 @@
# Douglas Fiedler <dognew@gmail.com>, 2019.
# Rarysson Guilherme <r_guilherme12@hotmail.com>, 2019.
# Gustavo da Silva Santos <gustavo94.rb@gmail.com>, 2019.
+# Rafael Roque <rafael.roquec@gmail.com>, 2019.
+# José Victor Dias Rodrigues <zoldyakopersonal@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2019-07-09 10:46+0000\n"
-"Last-Translator: Gustavo da Silva Santos <gustavo94.rb@gmail.com>\n"
+"PO-Revision-Date: 2019-08-21 15:56+0000\n"
+"Last-Translator: Julio Yagami <juliohenrique31501234@hotmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -77,7 +79,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -119,7 +121,6 @@ msgid "On call to '%s':"
msgstr "Na chamada para '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Livre"
@@ -188,6 +189,31 @@ msgid "Anim Change Call"
msgstr "Alterar Chamada da Anim"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Alterar Tempo de Quadro-Chave da Anim"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Alterar Transição da Animação"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Alterar Transformação da Anim"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Alterar Valor de Quadro-Chave da Anim"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Alterar Chamada da Anim"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Alterar Duração da Animação"
@@ -689,16 +715,18 @@ msgid "Line Number:"
msgstr "Número da Linha:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "%d ocorrência(s) substituída(s)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Sem Correspondências"
+#, fuzzy
+msgid "%d match."
+msgstr "%d correspondência(s) encontrada(s)."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "%d ocorrência(s) substituída(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "%d correspondência(s) encontrada(s)."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -847,9 +875,8 @@ msgid "Connect"
msgstr "Conectar"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Sinais:"
+msgstr "Sinal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -925,8 +952,7 @@ msgstr "Favoritos:"
msgid "Recent:"
msgstr "Recente:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1014,7 +1040,6 @@ msgid "Owners Of:"
msgstr "Donos De:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
msgstr "Remover arquivos selecionados do projeto? (irreversível)"
@@ -1028,7 +1053,7 @@ msgstr ""
"funcionem.\n"
"Removê-los mesmo assim? (irreversível)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Não pode remover:"
@@ -1064,7 +1089,7 @@ msgstr "Excluir permanentemente %d item(s)? (Irreversível)"
msgid "Show Dependencies"
msgstr "Mostrar Dependências"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorador de Recursos Órfãos"
@@ -1153,14 +1178,16 @@ msgid "License"
msgstr "Licença"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licença de Terceiros"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"A Godot Engine conta com várias bibliotecas de código aberto e gratuitas de "
@@ -1181,7 +1208,8 @@ msgid "Licenses"
msgstr "Licenças"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Erro ao abrir arquivo de pacote, não está em formato zip."
#: editor/editor_asset_installer.cpp
@@ -1198,7 +1226,6 @@ msgid "Success!"
msgstr "Sucesso!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalar"
@@ -1567,7 +1594,7 @@ 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 ""
+msgstr "Em exportações de 32 bits, o PCK embutido não pode ser maior que 4GB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1590,14 +1617,12 @@ msgid "Import Dock"
msgstr "Importar Dock"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
-msgstr "Nó Movido"
+msgstr "Dock de Nós"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem and Import Docks"
-msgstr "Arquivos"
+msgstr "Sistema de Arquivos e Importar Docks"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
@@ -1676,12 +1701,11 @@ msgid "New"
msgstr "Novo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importar"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportar"
@@ -1742,7 +1766,7 @@ msgstr "Mostrar no Gerenciador de Arquivos"
msgid "New Folder..."
msgstr "Nova Pasta..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Atualizar"
@@ -1793,7 +1817,7 @@ msgstr "Avançar"
msgid "Go Up"
msgstr "Acima"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Alternar Arquivos Ocultos"
@@ -1818,25 +1842,28 @@ msgid "Move Favorite Down"
msgstr "Mover Favorito Abaixo"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Pasta Anterior"
+msgid "Go to previous folder."
+msgstr "Ir para a pasta anterior."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Próxima Pasta"
+msgid "Go to next folder."
+msgstr "Ir para a próxima pasta."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Ir para diretório (pasta) pai."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Atualizar arquivos."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "(Des)favoritar pasta atual."
-#: editor/editor_file_dialog.cpp
-#, fuzzy
-msgid "Toggle visibility of hidden files."
-msgstr "Alternar Arquivos Ocultos"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "Alternar a visibilidade de arquivos ocultos."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1873,6 +1900,8 @@ msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Existem múltiplos importadores para diferentes tipos que apontam para o "
+"arquivo %s, importação abortada"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -2075,6 +2104,11 @@ msgstr "Limpar"
msgid "Clear Output"
msgstr "Limpar Saída"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Janela"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Falha na exportação do projeto com código de erro %d."
@@ -2397,6 +2431,15 @@ msgid "Pick a Main Scene"
msgstr "Escolha uma Cena Principal"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Fechar Cena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Fechar Cena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Não foi possível ativar o plugin em: '%s' processamento da configuração "
@@ -2513,6 +2556,11 @@ msgstr "Rodar Cena"
msgid "Close Tab"
msgstr "Fechar aba"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Fechar aba"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Fechas as outras abas"
@@ -2566,6 +2614,10 @@ msgid "Go to previously opened scene."
msgstr "Ir para cena aberta anteriormente."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar Texto"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Próxima guia"
@@ -2593,6 +2645,10 @@ msgstr "Nova Cena Herdada..."
msgid "Open Scene..."
msgstr "Abrir Cena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Abrir Recente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Salvar Cena"
@@ -2602,14 +2658,6 @@ msgid "Save All Scenes"
msgstr "Salvar Todas as Cenas"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Fechar Cena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Abrir Recente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Converter Para..."
@@ -2639,25 +2687,36 @@ msgstr "Reverter Cena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Ferramentas diversas atuantes no projeto ou cena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projeto"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Configurações do Projeto"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Ferramentas"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Exportar..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Instalar o Modelo de Compilação do Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Abrir Pasta do Projeto"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Ferramentas"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorador de Recursos Órfãos"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2755,12 +2814,13 @@ msgstr ""
"Quando usado remotamente em um dispositivo, isso é mais eficiente com o "
"sistema de arquivos via rede."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Configurações do Editor"
#: editor/editor_node.cpp
@@ -2768,32 +2828,20 @@ msgid "Editor Layout"
msgstr "Layout do Editor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Fazer Raiz de Cena"
+msgstr "Tirar Captura de Tela"
#: 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"
+msgstr "Capturas de Telas ficam salvas na Pasta Editor Data/Settings."
#: 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"
+msgstr "Alternar Console do Sistema"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2809,14 +2857,15 @@ msgstr "Abrir Configurações do Editor"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
-msgstr "Gerenciar Modelos de Exportação"
+msgid "Manage Editor Features..."
+msgstr "Gerenciar Recursos do Editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gerenciar Modelos de Exportação"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ajuda"
@@ -2824,12 +2873,13 @@ msgstr "Ajuda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Pesquisar"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentação Online"
@@ -2903,19 +2953,16 @@ msgid "Spins when the editor window redraws."
msgstr "Gira quando a janela do editor atualiza."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Contínuo"
+msgstr "Atualizar Continuamente"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Atualizar Alterações"
+msgstr "Atualizar quando Alterado"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Desabilitar Spinner de Atualização"
+msgstr "Ocultar Spinner de Atualização"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -2944,6 +2991,8 @@ msgstr "Não Salvar"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
msgstr ""
+"O modelo de compilação do Android não foi encontrado, por favor instale "
+"modelos relevantes."
#: editor/editor_node.cpp
msgid "Manage Templates"
@@ -2954,6 +3003,9 @@ 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 ""
+"Isso instalará o projeto Android para compilações personalizadas.\n"
+"Note que, para usá-lo, ele precisa estar habilitado por predefinição de "
+"exportação."
#: editor/editor_node.cpp
msgid ""
@@ -2961,6 +3013,8 @@ msgid ""
"Remove the \"build\" directory manually before attempting this operation "
"again."
msgstr ""
+"O modelo de compilação do Android já está instalado e não será substituído.\n"
+"Remova a pasta \"build\" manualmente antes de tentar esta operação novamente."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
@@ -3070,7 +3124,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)"
@@ -3078,11 +3132,11 @@ msgstr "Tempo Médio (seg)"
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr "% de Quadro"
+msgstr "Frame %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr "Quadro Físico %"
+msgstr "Frame de Física %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
@@ -3104,6 +3158,10 @@ msgstr "Tempo"
msgid "Calls"
msgstr "Chamadas"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Editar Texto:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Ativo"
@@ -3277,7 +3335,8 @@ msgid "Import From Node:"
msgstr "Importar a Partir do Nó:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Baixar Novamente"
#: editor/export_template_manager.cpp
@@ -3294,6 +3353,10 @@ msgid "Download"
msgstr "Baixar"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Faltando)"
@@ -3357,12 +3420,10 @@ msgid "No response."
msgstr "Sem resposta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Solicitação Falhou."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Loop de Redirecionamento."
@@ -3376,15 +3437,22 @@ msgid "Download Complete."
msgstr "Download completo."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Não pôde salvar tema ao arquivo:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Instalação de templates falhou. Os arquivos problemáticos podem ser achados "
"em '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Erro ao solicitar url: "
#: editor/export_template_manager.cpp
@@ -3434,9 +3502,8 @@ msgid "SSL Handshake Error"
msgstr "Erro SSL Handshake"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "Descompactando Assets"
+msgstr "Descompactando Fontes de Compilação do Android"
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3455,9 +3522,8 @@ msgid "Remove Template"
msgstr "Remover Modelo"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select Template File"
-msgstr "Selecione o arquivo de modelo"
+msgstr "Selecionar o Arquivo de Modelo"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
@@ -3471,21 +3537,11 @@ msgstr "Baixar Modelos"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Selecione um espelho da lista: (Shift+Click: Abrir no Navegador)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Falha ao abrir file_type_cache.cch para escrita, cache de tipos de arquivo "
-"não salvo!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoritos"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Impossível navegar até '%s' pois não existe no sistema de arquivos!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Estado: Falha na importação do arquivo. Por favor, conserte o arquivo e "
@@ -3520,14 +3576,14 @@ msgid "Provided name contains invalid characters."
msgstr "O nome fornecido contém caracteres inválidos."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Nome contém caracteres inválidos."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Um arquivo ou pasta com esse nome já existe."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Nome contém caracteres inválidos."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Renomear arquivo:"
@@ -3583,6 +3639,11 @@ msgstr "Duplicar..."
msgid "Move To..."
msgstr "Mover Para..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nova Cena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Novo Script..."
@@ -3621,9 +3682,8 @@ msgid "Re-Scan Filesystem"
msgstr "Re-escanear Sistema de Arquivos"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Toggle Split Mode"
-msgstr "Alternar modo"
+msgstr "Alternar Modo Split"
#: editor/filesystem_dock.cpp
msgid "Search files"
@@ -3649,6 +3709,11 @@ msgstr "Já há uma pasta ou arquivo neste caminho com o nome especificado."
msgid "Overwrite"
msgstr "Sobrescrever"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Criar a partir de Cena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Criar Script"
@@ -3711,6 +3776,14 @@ msgid "Search complete"
msgstr "Pesquisa concluída"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Adicionar ao Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Remover do Grupo"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Nome do grupo já existe."
@@ -3718,12 +3791,23 @@ msgstr "Nome do grupo já existe."
msgid "Invalid group name."
msgstr "Nome de grupo inválido."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gerenciar Grupos"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Excluir Imagem do Grupo"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupos"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nós fora do Grupo"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3736,12 +3820,12 @@ msgid "Nodes in Group"
msgstr "Nós no Grupo"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Adicionar ao Grupo"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Remover do Grupo"
+msgid "Group Editor"
+msgstr "Editor de Grupos"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3950,7 +4034,8 @@ msgid "MultiNode Set"
msgstr "Múltiplos Nodes definidos"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Selecione um nó para editar Sinais e Grupos."
#: editor/plugin_config_dialog.cpp
@@ -4402,9 +4487,8 @@ msgid "Enable Onion Skinning"
msgstr "Ativar Papel Vegetal"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Onion Skinning Options"
-msgstr "Papel Vegetal"
+msgstr "Opções do Onion Skinning"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
@@ -4715,10 +4799,6 @@ msgid "View Files"
msgstr "Ver Arquivos"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Não foi possível resolver o hostname:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Erro na conexão, por favor tente novamente."
@@ -4731,14 +4811,47 @@ msgid "No response from host:"
msgstr "Sem resposta do host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Não foi possível resolver o hostname:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Solicitação falhou, código de retorno:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Solicitação Falhou."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Não pôde salvar tema ao arquivo:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Solicitação falhou, redirecionamentos demais"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Loop de Redirecionamento."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Solicitação falhou, código de retorno:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tempo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Hash de download ruim, assumindo que o arquivo foi adulterado."
@@ -4779,6 +4892,10 @@ msgid "Idle"
msgstr "Ocioso"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instalar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Tentar Novamente"
@@ -4807,13 +4924,17 @@ msgid "Last"
msgstr "Último"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Todos"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Re-importar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4821,8 +4942,8 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Reverso"
+msgid "Reverse sorting."
+msgstr "Inverter ordenação."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4834,7 +4955,8 @@ msgid "Site:"
msgstr "Site:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Suporte..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4846,6 +4968,11 @@ msgid "Testing"
msgstr "Testando"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Carregar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Arquivo ZIP de Assets"
@@ -4903,32 +5030,32 @@ msgid "Rotation Step:"
msgstr "Passo de Rotação:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Mover guia vertical"
+msgid "Move Vertical Guide"
+msgstr "Mover Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Criar novo guia vertical"
+msgid "Create Vertical Guide"
+msgstr "Criar Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Remover guia vertical"
+msgid "Remove Vertical Guide"
+msgstr "Remover Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Mover guia horizontal"
+msgid "Move Horizontal Guide"
+msgstr "Mover Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Criar novo guia horizontal"
+msgid "Create Horizontal Guide"
+msgstr "Criar Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Remover guia horizontal"
+msgid "Remove Horizontal Guide"
+msgstr "Remover Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Criar novos guias horizontais e verticais"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Criar Guias Horizontais e Verticais"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4972,6 +5099,8 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
+"Quando ativo, os nós de Controle móveis mudam suas âncoras em vez de suas "
+"margens."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5011,13 +5140,16 @@ msgstr "Colar Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Limpar Esqueletos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
-msgstr "Criar esqueleto(s) customizado do(s) nó(s)"
+msgstr "Criar esqueleto(s) customizado(s) do(s) nó(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Bones"
-msgstr "Limpar Pose"
+msgstr "Limpar Esqueletos"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
@@ -5042,6 +5174,7 @@ msgid "Zoom Reset"
msgstr "Restaurar Ampliação"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Modo de Seleção"
@@ -5064,14 +5197,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + botão direito do mouse: Lista de seleção de profundidade"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Modo Mover"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Modo Rotacionar"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Modo Escala"
@@ -5097,6 +5233,7 @@ msgid "Toggle snapping."
msgstr "Alternar o snap."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Usar Snap"
@@ -5105,7 +5242,6 @@ msgid "Snapping Options"
msgstr "Opções de agarramento"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Grid"
msgstr "Encaixar na grade"
@@ -5114,11 +5250,6 @@ msgid "Use Rotation Snap"
msgstr "Usar Snap de Rotação"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurar Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relativo"
@@ -5127,39 +5258,37 @@ msgid "Use Pixel Snap"
msgstr "Usar Snap de Pixel"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Smart Snapping"
msgstr "Encaixe inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
-msgstr "Encaixar no pai"
+msgstr "Encaixar no Pai"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Anchor"
-msgstr "Encaixar na âncora do nó"
+msgstr "Encaixar na Âncora do Nó"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Sides"
-msgstr "Encaixar nos lados do nó"
+msgstr "Encaixar nos Lados do Nó"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Center"
-msgstr "Encaixar no centro do nó"
+msgstr "Encaixar no Centro do Nó"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
-msgstr "Encaixar em outros nós"
+msgstr "Encaixar em Outros Nós"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
-msgstr "Encaixar nas guias"
+msgstr "Encaixar nas Guias"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5240,9 +5369,8 @@ msgid "Frame Selection"
msgstr "Seleção de Quadros"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Preview Canvas Scale"
-msgstr "Prever Atlas"
+msgstr "Visualizar Canvas Scale"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
@@ -5298,9 +5426,8 @@ msgid "Divide grid step by 2"
msgstr "Dividir o passo da grade por 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Visão Traseira"
+msgstr "Vista Panorâmica"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -5354,16 +5481,6 @@ msgstr "Definir Manipulador"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Erro ao carregar imagem:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Nenhum pixel com transparência > 128 na imagem."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Carregar Máscara de Emissão"
@@ -5371,9 +5488,8 @@ msgstr "Carregar Máscara de Emissão"
#: 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"
+msgstr "Reiniciar"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5461,19 +5577,16 @@ 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 definição"
+msgstr "Carregar Predefinição"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Remove Curve Point"
@@ -5528,9 +5641,8 @@ 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!"
@@ -5682,14 +5794,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Superfície de origem é inválida (sem faces)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Pai não tem faces sólidas para popular."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Não foi possível mapear área."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selecione uma Malha de origem:"
@@ -5774,20 +5878,27 @@ msgid "Generation Time (sec):"
msgstr "Gerando Tempo (seg):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "As faces não têm área!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Nenhuma face!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "O nó não contém geometria (faces)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "O nó não contém geometria."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "O nó não contém geometria (faces)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "O nó não contém geometria."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -5958,9 +6069,8 @@ msgid "Split Segment (in curve)"
msgstr "Dividir Segmentos (na curva)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
-msgstr "Mover junta"
+msgstr "Mover Junta"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
@@ -6122,7 +6232,6 @@ msgid "Grid Settings"
msgstr "Configurações da grade"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Snap"
@@ -6228,12 +6337,9 @@ msgid "Error writing TextFile:"
msgstr "Erro ao escrever arquivo:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Erro: Não foi possível carregar o arquivo."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Erro: não pôde carregar o arquivo."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Não se pôde achar tile:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6256,7 +6362,8 @@ msgid "Error Importing"
msgstr "Erro ao importar"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Novo arquivo de texto ..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6293,18 +6400,16 @@ msgid "Find Next"
msgstr "Localizar próximo"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "Filtrar propriedades"
+msgstr "Filtrar scripts"
#: 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:"
+msgstr "Métodos de filtragem"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6339,6 +6444,11 @@ msgid "Open..."
msgstr "Abrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Abrir script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Salvar Tudo"
@@ -6376,13 +6486,13 @@ msgid "Save Theme"
msgstr "Salvar Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Fechar Docs"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Fechar Tudo"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Fechar Docs"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Rodar"
@@ -6470,6 +6580,11 @@ msgstr "Depurador"
msgid "Search Results"
msgstr "Pesquisar resultados"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Limpar Cenas Recentes"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Conexões com o método:"
@@ -6536,8 +6651,9 @@ msgid "Syntax Highlighter"
msgstr "Realce de sintaxe"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Ir Para"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6547,7 +6663,7 @@ msgstr "Marcadores"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Breakpoints"
-msgstr "Criar pontos."
+msgstr "Pontos de interrupção(Breakpoints)"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6571,25 +6687,6 @@ msgid "Toggle Comment"
msgstr "Alternar Comentário"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Alternar Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Vá para o próximo ponto de interrupção"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Ir para ponto de interrupção anterior"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Remover Todos os Itens"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Dobrar/Desdobrar Linha"
@@ -6610,6 +6707,11 @@ msgid "Complete Symbol"
msgstr "Completar Símbolo"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Selecionar Escala"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Apagar Espaços em Branco"
@@ -6626,29 +6728,32 @@ msgid "Auto Indent"
msgstr "Auto Recuar"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Alternar Ponto de interrupção"
+msgid "Find Previous"
+msgstr "Encontrar Anterior"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Remover Todos os Pontos de Interrupção"
+msgid "Find in Files..."
+msgstr "Procurar nos Arquivos..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Vá para o próximo ponto de interrupção"
+msgid "Contextual Help"
+msgstr "Ajuda Contextual"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Ir para ponto de interrupção anterior"
+msgid "Toggle Bookmark"
+msgstr "Alternar Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Encontrar Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Ir para o Próximo Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Procurar nos Arquivos..."
+msgid "Go to Previous Bookmark"
+msgstr "Ir para o Marcador Anterior"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Remover Todos os Marcadores"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6659,8 +6764,21 @@ msgid "Go to Line..."
msgstr "Ir para Linha..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Ajuda Contextual"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Alternar Ponto de interrupção"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Remover Todos os Pontos de Interrupção"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Vá para o próximo ponto de interrupção"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Ir para ponto de interrupção anterior"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6668,8 +6786,8 @@ msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
-"Os seguintes arquivos são mais recentes no disco.\n"
-"Que ação deve ser tomada?:"
+"Este shader foi modificado no disco.\n"
+"Que ação deve ser tomada?"
#: editor/plugins/shader_editor_plugin.cpp
msgid "Shader"
@@ -6840,8 +6958,14 @@ msgid "Rear"
msgstr "Traseira"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "Alinhar com a Vista"
+#, fuzzy
+msgid "Align Transform with View"
+msgstr "Alinhar Transformação com a Vista"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Alinhar Rotação com a Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6896,8 +7020,9 @@ msgid "Audio Listener"
msgstr "Ouvinte de Ãudio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Habilitar Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Habilitar Filtragem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6952,8 +7077,8 @@ msgid "Snap Nodes To Floor"
msgstr "Encaixar Nó(s) no Chão"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Modo de Seleção (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6966,30 +7091,11 @@ msgstr ""
"Alt + botão direito do mouse: Lista de Profundidade"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Modo Mover (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Modo Rotacionar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Modo Escala (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Local Coords"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Modo Espaço Local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Modo Encaixe (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Visão inferior"
@@ -7030,26 +7136,6 @@ msgid "Focus Selection"
msgstr "Focar Seleção"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Alinhar Seleção com Visualização"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Ferramenta Selecionar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Ferramenta Mover"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Ferramenta Rotacionar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Ferramenta Escalar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Alternar Visão Livre"
@@ -7104,7 +7190,8 @@ msgstr "Ver Grade"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Configurações"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7249,21 +7336,20 @@ msgid "Settings:"
msgstr "Configurações:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "Seleção de Quadros"
+msgstr "Nenhum Frame Selecionado"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr "Adicionar %d Quadro(s)"
+msgstr "Adicionar %d Frame(s)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr "Adicionar Quadro"
+msgstr "Adicionar Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
-msgstr "ERRO: Não foi possível carregar recurso de quadro!"
+msgstr "ERRO: Não foi possível carregar o recurso de frame!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Resource clipboard is empty or not a texture!"
@@ -7271,7 +7357,7 @@ msgstr "Recurso da área de transferência está vazio ou não é uma textura!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
-msgstr "Colar Quadro"
+msgstr "Colar Frame"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
@@ -7303,7 +7389,7 @@ msgstr "Repetir"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Animation Frames:"
-msgstr "Quadros da Animação:"
+msgstr "Frames da Animação:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add a Texture from File"
@@ -7311,7 +7397,7 @@ msgstr "Adicionar Textura de um Arquivo"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr ""
+msgstr "Adicionar Frames de uma Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -7330,9 +7416,8 @@ msgid "Move (After)"
msgstr "Mover (Depois)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "Pilha de Quadros"
+msgstr "Selecionar Frames"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
@@ -7343,14 +7428,13 @@ msgid "Vertical:"
msgstr "Vertical:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select/Clear All Frames"
-msgstr "Selecionar Tudo"
+msgstr "Selecionar/Deselecionar Todos os Frames"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
msgid "Create Frames from Sprite Sheet"
-msgstr "Criar a partir de Cena"
+msgstr "Criar Frames a partir da Planilha de Sprites"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
@@ -7402,10 +7486,6 @@ msgid "TextureRegion"
msgstr "Região da Textura"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Não pôde salvar tema ao arquivo:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Adicionar Todos os Itens"
@@ -7422,9 +7502,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."
@@ -7451,23 +7530,20 @@ msgid "Create From Current Editor Theme"
msgstr "Criar a Partir do Tema Atual do Editor"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Button"
-msgstr "Botão do Mous"
+msgstr "Alternar Botão"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Button"
-msgstr "Botão do Meio"
+msgstr "Botão Desativado"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
msgstr "Item"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled Item"
-msgstr "Desabilitado"
+msgstr "Item Desativado"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Check Item"
@@ -7487,7 +7563,7 @@ 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"
@@ -7495,13 +7571,13 @@ msgstr "Submenu"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
-msgstr "Item"
+msgid "Subitem 1"
+msgstr "Item 1"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
-msgstr "Item"
+msgid "Subitem 2"
+msgstr "Item 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
@@ -7512,9 +7588,8 @@ msgid "Many"
msgstr "Muitas"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Disabled LineEdit"
-msgstr "Desabilitado"
+msgstr "LineEdit Desativado"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
@@ -7529,9 +7604,8 @@ msgid "Tab 3"
msgstr "Guia 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"
@@ -7607,31 +7681,22 @@ msgid "Transpose"
msgstr "Transpor"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Espelhar X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Espelhar Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Disable Autotile"
-msgstr "Autotiles"
+msgstr "Desativar Autotile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Enable Priority"
-msgstr "Editar prioridade da telha"
+msgstr "Ativar Prioridade"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
msgstr "Pintar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+RMB: Desenhar Linha\n"
"Shift+Ctrl+RMB: Pintar Retângulo"
@@ -7641,27 +7706,22 @@ msgid "Pick Tile"
msgstr "Pegar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
msgstr "Rotacionar para a esquerda"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
msgstr "Rotacionar para a direita"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Flip Horizontally"
-msgstr "Girar horizontalmente"
+msgstr "Inverter Horizontalmente"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Flip Vertically"
-msgstr "Girar verticalmente"
+msgstr "Inverter Verticalmente"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Transform"
msgstr "Limpar Transformação"
@@ -7700,42 +7760,35 @@ msgstr "Selecione a forma, subtile ou tile anterior."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
msgid "Region Mode"
-msgstr "Modo de Início:"
+msgstr "Modo de Região"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "Modo de Interpolação"
+msgstr "Modo de Colisão"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion Mode"
-msgstr "Editar polígono de oclusão"
+msgstr "Modo de Oclusão"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Mode"
-msgstr "Criar Malha de Navegação"
+msgstr "Modo de Navegação"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask Mode"
-msgstr "Modo Rotacionar"
+msgstr "Modo Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "Modo de Exportação:"
+msgstr "Modo de Prioridade"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "Modo Panorâmico"
+msgstr "Modo de Ãcone"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index Mode"
-msgstr "Modo Panorâmico"
+msgstr "Modo Ãndice Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
@@ -7825,8 +7878,9 @@ msgid ""
"Shift+LMB: Set wildcard bit.\n"
"Click on another Tile to edit it."
msgstr ""
-"LMB: ligar bit.\n"
-"RMB: desligar bit.\n"
+"BEM: ligar bit.\n"
+"BDM: desligar bit.\n"
+"Shift+BEM: Escolher wildcard.\n"
"Clique em outro Mosaico para editá-lo."
#: editor/plugins/tile_set_editor_plugin.cpp
@@ -7857,7 +7911,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Region"
-msgstr "Definir a região da Telha"
+msgstr "Definir a região do Mosaico"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Tile"
@@ -7940,19 +7994,20 @@ msgid "TileSet"
msgstr "Conjunto de Telha"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
+msgid "(GLES3 only)"
+msgstr "(Apenas GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
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
msgid "Vector"
@@ -7963,53 +8018,44 @@ msgid "Boolean"
msgstr "Booleano"
#: 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 "Adicionar porta de saída"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port type"
-msgstr "Mudar tipo padrão"
+msgstr "Alterar tipo da porta de entrada"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "Mudar tipo padrão"
+msgstr "Alterar tipo da porta de saída"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "Alterar Nome da Entrada"
+msgstr "Alterar nome da porta de entrada"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port name"
-msgstr "Alterar Nome da Entrada"
+msgstr "Alterar nome da 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 "Alterar 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"
@@ -8028,6 +8074,11 @@ msgid "Duplicate Nodes"
msgstr "Duplicar Nó(s)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Colar Nodes"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Excluir Nós"
@@ -8049,22 +8100,25 @@ msgstr "Luz"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Create Shader Node"
-msgstr "Criar Nó"
+msgid "Show resulted shader code."
+msgstr "Criar Nó Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Create Shader Node"
+msgstr "Criar Nó Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
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 "Fazer Função"
+msgstr "Função Escala de Cinza."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
@@ -8075,56 +8129,70 @@ msgid "Converts RGB vector to HSV equivalent."
msgstr "Converter vetor RGB para um HSV equivalente."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Renomear Função"
+msgstr "Função Sépia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
-msgstr ""
+msgstr "Operador de gravação."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Operador de escurecimento."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Apenas Diferenças"
+msgstr "Operador de diferença."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Operador de 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 de iluminação."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Operador de sobreposição."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Operador de tela."
#: 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 "Cor constante."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Color uniform."
-msgstr "Limpar Transformação"
+msgstr "Cor uniforme."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Retorna o resultado booleano da comparação %s entre dois parâmetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Igual (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Maior Que (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Maior ou Igual (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8135,62 +8203,106 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Retorna o resultado booleano da comparação entre INF e o parâmetro escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Retorna o resultado booleano da comparação entre NaN e um parâmetro escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Menor Que (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Menor ou Igual (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Diferente (!=)"
+
+#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Retorna o resultado booleano da comparação entre dois parâmetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Retorna o resultado booleano da comparação entre INF (ou NaN) e um parâmetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
-msgstr "Alterar Constante Vet"
+msgstr "Constante booleana."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "Booleano uniforme."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "Parâmetro de entrada '%s' para todos os modos de sombreamento."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "Encaixar no pai"
+msgstr "Parâmetro de entrada."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader modes."
msgstr ""
+"Parâmetro de entrada '%s' para os modos de sombreamento de vértice e "
+"fragmento."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for fragment and light shader modes."
msgstr ""
+"Parâmetro de entrada '%s' para os modos de sombreamento de fragmento e luz."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "Parâmetro de entrada '%s' para o modo de sombreamento de fragmento."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "Parâmetro de entrada '%s' para o modo de sombreamento de luz."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "Parâmetro de entrada '%s' para o modo de sombreamento de vértice."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for vertex and fragment shader mode."
msgstr ""
+"Parâmetro de entrada '%s' para o modo de sombreamento de vértice e fragmento."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Alterar Função Escalar"
+msgstr "Função escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "Alterar Operador Escalar"
+msgstr "Operador escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
@@ -8233,16 +8345,16 @@ msgid "Returns the arc-cosine of the parameter."
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 "(Somente em GLES3) Retorna o coseno hiperbólico inverso do parâmetro."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Retorna o cosseno hiperbólico inverso do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
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 "(Somente em GLES3) Retorna o seno hiperbólico inverso do parâmetro."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Retorna o seno hiperbólico inverso do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8253,9 +8365,8 @@ msgid "Returns the arc-tangent of the parameters."
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."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Retorna a tangente hiperbólica inversa do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8264,20 +8375,19 @@ 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."
-msgstr ""
+msgstr "Limita um valor para permanecer entre dois outros valores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
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 "(Somente em GLES3) Retorna o coseno hiperbólico do parâmetro."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Retorna o cosseno hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Converts a quantity in radians to degrees."
-msgstr "Converte uma quantidade em radianos para graus."
+msgstr "Converte um valor em radianos para graus."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
@@ -8293,8 +8403,9 @@ msgid "Finds the nearest integer less than or equal to the parameter."
msgstr "Encontra o inteiro mais próximo que é menor ou igual ao parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "Calcula a parte decimal do argumento."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
@@ -8311,11 +8422,11 @@ msgstr "Logaritmo de Base-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "Retorna o maior entre dois valores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "Retorna o menor entre dois valores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
@@ -8343,18 +8454,16 @@ msgid "1.0 / scalar"
msgstr "1,0 / escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Somente em GLES3) Encontra o inteiro mais próximo ao parâmetro."
+msgid "Finds the nearest integer to the parameter."
+msgstr "Encontra o inteiro mais próximo do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr "(Somente em GLES3) Encontra o inteiro par mais próximo ao parâmetro."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Encontra o inteiro par 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."
@@ -8365,40 +8474,50 @@ msgid "Returns the sine of the parameter."
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 "(Somente em GLES3) Retorna o seno hiperbólico do parâmetro."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Retorna o seno hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Retorna a raiz quadrada do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Função SmoothStep( escalar(edge0), escalar(edge1), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge0' e 1.0 se 'x' é maior que 'edge1'. "
+"Caso contrário o valor retornado é interpolado entre 0.0 e 1.0 utilizando "
+"polinômios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Função Step( escalar(edge), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge' e 1.0 caso contrário."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
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 "(Somente em GLES3) Retorna a tangente hiperbólica do parâmetro."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "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 "(Somente em GLES3) Encontra o valor truncado do parâmetro."
+msgid "Finds the truncated value of the parameter."
+msgstr "Encontra o valor truncado do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8406,19 +8525,17 @@ msgid "Adds scalar to scalar."
msgstr "Adiciona escalar a escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Divides scalar by scalar."
msgstr "Divide escalar por escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Multiplies scalar by scalar."
msgstr "Multiplica escalar por escalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Returns the remainder of the two scalars."
-msgstr "Retorna o resto das duas escalares."
+msgstr "Retorna o resto de dois escalares."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8436,21 +8553,28 @@ msgid "Scalar uniform."
msgstr "Alterar Uniforme Escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "Faça a pesquisa da textura cúbica."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "Fazer pesquisa da textura."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "Alterar Uniforme da Textura"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "Alterar Uniforme da Textura"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "Alterar Uniforme da Textura"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8460,7 +8584,7 @@ msgstr "Diálogo Transformação..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8479,17 +8603,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
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."
+msgid "Calculates the inverse of a transform."
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."
+msgid "Calculates the transpose of a transform."
msgstr "(Somente em GLES3) Calcula a transposta da transform."
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8543,8 +8667,9 @@ msgid "Calculates the dot product of two vectors."
msgstr "Calcula o produto escalar de dois vetores."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8564,6 +8689,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Interpolação linear entre dois vetores."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolação linear entre dois vetores."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Calcula o produto normalizado do vetor."
@@ -8576,48 +8706,70 @@ msgid "1.0 / vector"
msgstr "1,0 / vetor"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+#, fuzzy
+msgid "Returns the vector that points in the direction of refraction."
msgstr "Retorna um vetor que aponta na direção da refração."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Função SmoothStep( escalar(edge0), escalar(edge1), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge0' e 1.0 se 'x' é maior que 'edge1'. "
+"Caso contrário o valor retornado é interpolado entre 0.0 e 1.0 utilizando "
+"polinômios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Função SmoothStep( escalar(edge0), escalar(edge1), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge0' e 1.0 se 'x' é maior que 'edge1'. "
+"Caso contrário o valor retornado é interpolado entre 0.0 e 1.0 utilizando "
+"polinômios de Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Função Step( escalar(edge), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge' e 1.0 caso contrário."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Função Step( escalar(edge), escalar(x) ).\n"
+"\n"
+"Retorna 0.0 se 'x' é menor que 'edge' e 1.0 caso contrário."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
@@ -8663,47 +8815,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8881,6 +9040,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Modelos de exportação para esta plataforma não foram encontrados:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gerenciar Modelos de Exportação"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exportar Com Depuração"
@@ -9040,6 +9203,15 @@ msgid "Unnamed Project"
msgstr "Projeto Sem Nome"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importar Projeto Existente"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Não é possível abrir o projeto em '%s'."
@@ -9138,8 +9310,8 @@ msgstr "Remover projeto da lista? (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)"
+"Remove all missing 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)"
#: editor/project_manager.cpp
@@ -9166,8 +9338,9 @@ msgid "Project Manager"
msgstr "Gerenciador de Projetos"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Lista de Projetos"
+#, fuzzy
+msgid "Projects"
+msgstr "Projeto"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9191,10 +9364,6 @@ msgid "Templates"
msgstr "Modelos"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Sair"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Reiniciar Agora"
@@ -9539,6 +9708,10 @@ msgstr "Idiomas:"
msgid "AutoLoad"
msgstr "AutoLoad"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9591,14 +9764,6 @@ msgstr "Selecionar Método Virtual"
msgid "Select Method"
msgstr "Selecionar Mtéodo"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Não se pôde executar a ferramenta PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "Não se pôde carregar de volta imagem convertida por PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Renomear em lote"
@@ -9896,6 +10061,11 @@ msgid "Remove Node(s)"
msgstr "Remover Nó(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Alterar nome da porta de saída"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9942,6 +10112,11 @@ msgid "Extend Script"
msgstr "Estender Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Reparentar Nó"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Fazer Raiz de Cena"
@@ -10018,24 +10193,27 @@ msgid "Node configuration warning:"
msgstr "Aviso de configuração de nó:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"O nó tem conexão(ões) e grupo(s)\n"
"Clique para mostrar o painel de sinais."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"O nó tem conexões.\n"
"Clique para mostrar o painel de sinais."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"O nó está em grupo(s).\n"
@@ -10142,6 +10320,11 @@ msgid "Error loading script from %s"
msgstr "Erro ao carregar script de %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sobrescrever"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/D"
@@ -10175,7 +10358,8 @@ msgid "Script is valid."
msgstr "Script válido"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Permitidos: a-z, A-Z, 0-9 e _"
#: editor/script_create_dialog.cpp
@@ -10338,6 +10522,10 @@ msgid "Change Shortcut"
msgstr "Modificar Atalho"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Configurações do Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Atalhos"
@@ -10759,10 +10947,30 @@ msgid "Set Variable Type"
msgstr "Definir o Tipo da Variável"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Não deve coincidir com um nome de tipo interno existente."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Criar um novo retângulo."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variáveis:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Criar um novo retângulo."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Criar um novo polígono."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "O nome não é um identificador valido:"
@@ -10952,10 +11160,6 @@ msgid "Cut Nodes"
msgstr "Recortar Nodes"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Colar Nodes"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Editar Membro"
@@ -11839,22 +12043,6 @@ msgstr ""
"para que ele possa ter um tamanho. Caso contrário, defina-o como destino de "
"render e atribua sua textura interna a algum nó para exibir."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Erro ao inicializar FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Formato de fonte desconhecido."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Erro ao carregar fonte."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Tamanho de fonte inválido."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrada"
@@ -11868,6 +12056,11 @@ msgstr "Fonte inválida para o shader."
msgid "Invalid source for shader."
msgstr "Fonte inválida para o shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Fonte inválida para o shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Atribuição à função."
@@ -11884,6 +12077,126 @@ msgstr "Variáveis só podem ser atribuídas na função de vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem serem modificadas."
+#~ msgid "No Matches"
+#~ msgstr "Sem Correspondências"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Falha ao abrir file_type_cache.cch para escrita, cache de tipos de "
+#~ "arquivo não salvo!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Impossível navegar até '%s' pois não existe no sistema de arquivos!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Erro ao carregar imagem:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Nenhum pixel com transparência > 128 na imagem."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Pai não tem faces sólidas para popular."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Não foi possível mapear área."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "As faces não têm área!"
+
+#~ msgid "No faces!"
+#~ msgstr "Nenhuma face!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Erro: Não foi possível carregar o arquivo."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Erro: não pôde carregar o arquivo."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Habilitar Doppler"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Modo de Seleção (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Modo Mover (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Modo Rotacionar"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Modo Escala (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Local Coords"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Modo Encaixe (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Ferramenta Selecionar"
+
+#~ msgid "Tool Move"
+#~ msgstr "Ferramenta Mover"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Ferramenta Rotacionar"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Ferramenta Escalar"
+
+#, 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)"
+
+#~ msgid "Project List"
+#~ msgstr "Lista de Projetos"
+
+#~ msgid "Exit"
+#~ msgstr "Sair"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Não se pôde executar a ferramenta PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "Não se pôde carregar de volta imagem convertida por PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Erro ao inicializar FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Formato de fonte desconhecido."
+
+#~ msgid "Error loading font."
+#~ msgstr "Erro ao carregar fonte."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Tamanho de fonte inválido."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Pasta Anterior"
+
+#~ msgid "Next Folder"
+#~ msgstr "Próxima Pasta"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Abrir Capturas de Tela Automaticamente"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Abrir em um editor de imagens externo."
+
+#~ msgid "Reverse"
+#~ msgstr "Reverso"
+
+#~ msgid "Mirror X"
+#~ msgstr "Espelhar X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Espelhar Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Gerando solução..."
@@ -12467,9 +12780,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Erase selection"
#~ msgstr "Apagar Seleção"
-#~ msgid "Could not find tile:"
-#~ msgstr "Não se pôde achar tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nome ou ID do item:"
@@ -12737,9 +13047,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Info"
#~ msgstr "Informação"
-#~ msgid "Re-Import..."
-#~ msgstr "Re-importar..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Sem máscaras de bits para importar!"
@@ -13132,9 +13439,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Stereo"
#~ msgstr "Estéreo"
-#~ msgid "Window"
-#~ msgstr "Janela"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Escalonando para %s%%."
@@ -13355,9 +13659,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Add Image Group"
#~ msgstr "Adicionar Grupo de Imagens"
-#~ msgid "Delete Image Group"
-#~ msgstr "Excluir Imagem do Grupo"
-
#~ msgid "Project Export Settings"
#~ msgstr "Configurações de Exportação de Projeto"
@@ -13442,9 +13743,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Export Project PCK"
#~ msgstr "Exportar PCK do Projeto"
-#~ msgid "Export..."
-#~ msgstr "Exportar..."
-
#~ msgid "Project Export"
#~ msgstr "Exportação de Projeto"
@@ -13536,9 +13834,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Deploy File Server Clients"
#~ msgstr "Instalar Clientes do Servidor de Arquivos"
-#~ msgid "Group Editor"
-#~ msgstr "Editor de Grupos"
-
#~ msgid "Overwrite Existing Scene"
#~ msgstr "Sobrescrever Cena Existente"
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 4bc53e53db..7016f39d39 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-07-09 10:47+0000\n"
+"PO-Revision-Date: 2019-07-29 19:20+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"
@@ -70,7 +70,6 @@ msgid "On call to '%s':"
msgstr "Em chamada para '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Livre"
@@ -139,6 +138,31 @@ msgid "Anim Change Call"
msgstr "Anim Mudar Chamada"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Mudar Tempo do Keyframe"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Mudar Transição"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Mudar Transformação"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Mudar Valor do Keyframe"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Mudar Chamada"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Mudar Duração da Animação"
@@ -641,16 +665,18 @@ msgid "Line Number:"
msgstr "Numero da linha:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Substituído %d ocorrência(s)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Sem combinações"
+#, fuzzy
+msgid "%d match."
+msgstr "Encontrada(s) %d correspondência(s)."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Substituído %d ocorrência(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Encontrada(s) %d correspondência(s)."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -800,9 +826,8 @@ msgid "Connect"
msgstr "Ligar"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Sinais:"
+msgstr "Sinal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -878,8 +903,7 @@ msgstr "Favoritos:"
msgid "Recent:"
msgstr "Recente:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -967,9 +991,8 @@ msgid "Owners Of:"
msgstr "Proprietários de:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Remover arquivos selecionados do Projeto? (sem desfazer)"
+msgstr "Remover arquivos selecionados do Projeto? (Sem desfazer)"
#: editor/dependency_editor.cpp
msgid ""
@@ -981,7 +1004,7 @@ msgstr ""
"funcionem.\n"
"Remover mesmo assim? (sem anular)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Impossível remover:"
@@ -1017,7 +1040,7 @@ msgstr "Apagar permanentemente %d itens? (Sem desfazer!)"
msgid "Show Dependencies"
msgstr "Mostra Dependências"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorador de Recursos Órfãos"
@@ -1106,14 +1129,16 @@ msgid "License"
msgstr "Licença"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licença de Terceiros"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"O Godot Engine conta com várias Bibliotecas abertas e gratuitas de "
@@ -1134,7 +1159,8 @@ msgid "Licenses"
msgstr "Licenças"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Error ao abrir Ficheiro comprimido, não está no formato zip."
#: editor/editor_asset_installer.cpp
@@ -1151,7 +1177,6 @@ msgid "Success!"
msgstr "Sucesso!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalar"
@@ -1522,6 +1547,7 @@ 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 ""
+"Em exportações de 32 bits o PCK incorporado não pode ser maior do que 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1628,12 +1654,11 @@ msgid "New"
msgstr "Novo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importar"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportar"
@@ -1694,7 +1719,7 @@ msgstr "Mostrar no Gestor de Ficheiros"
msgid "New Folder..."
msgstr "Nova Diretoria..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Atualizar"
@@ -1745,7 +1770,7 @@ msgstr "Avançar"
msgid "Go Up"
msgstr "Subir"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Alternar Ficheiros escondidos"
@@ -1770,23 +1795,31 @@ msgid "Move Favorite Down"
msgstr "Mover Favorito para Baixo"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Pasta Anterior"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Ir para a pasta acima."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Próxima Pasta"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Ir para a pasta acima."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Ir para a pasta acima."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Procurar ficheiros"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "(Não) tornar favorita atual pasta."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Toggle the visibility of hidden files."
msgstr "Alternar visibilidade de ficheiros escondidos."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2028,6 +2061,10 @@ msgstr "Limpar"
msgid "Clear Output"
msgstr "Limpar Saída"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Exportação do projeto falhou com código de erro %d."
@@ -2352,6 +2389,15 @@ msgid "Pick a Main Scene"
msgstr "Escolha a Cena Principal"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Fechar Cena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Fechar Cena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "Incapaz de ativar plugin em: '%s' falha de análise ou configuração."
@@ -2465,6 +2511,11 @@ msgstr "Executar esta Cena"
msgid "Close Tab"
msgstr "Fechar Separador"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Fechar Separador"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Fechar outros separadores"
@@ -2518,6 +2569,10 @@ msgid "Go to previously opened scene."
msgstr "Ir para Cena aberta anteriormente."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar Texto"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Próxima guia"
@@ -2545,6 +2600,10 @@ msgstr "Nova Cena Herdada..."
msgid "Open Scene..."
msgstr "Abrir Cena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Abrir Recente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Guardar Cena"
@@ -2554,14 +2613,6 @@ msgid "Save All Scenes"
msgstr "Guardar todas as Cenas"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Fechar Cena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Abrir Recente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Converter Para..."
@@ -2591,25 +2642,37 @@ msgstr "Reverter Cena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Ferramentas diversas atuantes no Projeto ou Cena."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projeto"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Configurações de Projeto"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Ferramentas"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportar"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Instalar Modelo Android de Compilação"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Abrir Pasta de Dados do Projeto"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Ferramentas"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Instalar Modelo Android de Compilação"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorador de Recursos Órfãos"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2706,12 +2769,13 @@ msgstr ""
"Quando usada num dispositivo remoto, é mais eficiente com um Sistema de "
"Ficheiros em rede."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Configurações do Editor"
#: editor/editor_node.cpp
@@ -2728,14 +2792,6 @@ 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"
@@ -2756,14 +2812,16 @@ msgid "Open Editor Settings Folder"
msgstr "Abrir Pasta de Configurações do Editor"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "Gerir Características do Editor"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Gerir Modelos de Exportação"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ajuda"
@@ -2771,12 +2829,13 @@ msgstr "Ajuda"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Procurar"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentação Online"
@@ -3052,6 +3111,11 @@ msgstr "Tempo"
msgid "Calls"
msgstr "Chamadas"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Editar Tema"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "On"
@@ -3223,7 +3287,8 @@ msgid "Import From Node:"
msgstr "Importar do Nó:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Transferir novamente"
#: editor/export_template_manager.cpp
@@ -3240,6 +3305,10 @@ msgid "Download"
msgstr "Download"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Em Falta)"
@@ -3303,12 +3372,10 @@ msgid "No response."
msgstr "Sem resposta."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Pedido falhado."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Redirecionar ciclo."
@@ -3322,15 +3389,22 @@ msgid "Download Complete."
msgstr "Download Completo."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Impossível guardar tema para Ficheiro:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Falhou a instalação de Modelos. Os ficheiros problemáticos podem ser "
"encontrados em '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Erro ao solicitar url: "
#: editor/export_template_manager.cpp
@@ -3415,21 +3489,11 @@ msgstr "Transferir Modelos"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Selecionar servidor da lista: (Shift+Click: Abrir no Navegador)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"file_type_cache.cch não for guardada, por não se conseguir abrir para "
-"leitura!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoritos"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "'%s' não foi encontrado no Sistema de Ficheiros!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Estado: A importação do Ficheiro falhou. Corrija o Ficheiro e importe "
@@ -3464,14 +3528,14 @@ msgid "Provided name contains invalid characters."
msgstr "O nome fornecido contém carateres inválidos."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "O nome contém carateres inválidos."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Um Ficheiro ou diretoria já existe com este nome."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "O nome contém carateres inválidos."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Mudar nome do Ficheiro:"
@@ -3527,6 +3591,11 @@ msgstr "Duplicar..."
msgid "Move To..."
msgstr "Mover para..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nova Cena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Novo Script..."
@@ -3592,6 +3661,11 @@ msgstr "Já existe um ficheiro ou pasta com o mesmo nome nesta localização."
msgid "Overwrite"
msgstr "Sobrescrever"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Criar a partir da Cena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Criar Script"
@@ -3654,6 +3728,14 @@ msgid "Search complete"
msgstr "Pesquisa completa"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Adicionar ao Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Remover do Grupo"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Já existe o nome de grupo ."
@@ -3661,12 +3743,23 @@ msgstr "Já existe o nome de grupo ."
msgid "Invalid group name."
msgstr "Nome de grupo inválido."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Gerir Grupos"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Apagar Modelo"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupos"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nós fora do Grupo"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3679,12 +3772,13 @@ msgid "Nodes in Group"
msgstr "Nós no Grupo"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Adicionar ao Grupo"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Remover do Grupo"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Editor de Script"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3892,7 +3986,8 @@ msgid "MultiNode Set"
msgstr "Conjunto MultiNode"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Selecionar um Nó para editar sinais e grupos."
#: editor/plugin_config_dialog.cpp
@@ -4651,10 +4746,6 @@ msgid "View Files"
msgstr "Ver Ficheiros"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Impossível resolver hostname:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Erro de ligação, tente novamente."
@@ -4667,14 +4758,47 @@ msgid "No response from host:"
msgstr "Sem resposta do host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Impossível resolver hostname:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Falha na solicitação, código de retorno:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Pedido falhado."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Impossível guardar tema para Ficheiro:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Falha na solicitação, demasiados redirecionamentos"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Redirecionar ciclo."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Falha na solicitação, código de retorno:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tempo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Mau hash na transferência, assume-se que o Ficheiro foi manipulado."
@@ -4715,6 +4839,10 @@ msgid "Idle"
msgstr "Inativo"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instalar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Repetir"
@@ -4743,13 +4871,17 @@ msgid "Last"
msgstr "Último"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Todos"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importar"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugins"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4757,8 +4889,8 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Inverter"
+msgid "Reverse sorting."
+msgstr "Inverter ordenação."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4770,7 +4902,8 @@ msgid "Site:"
msgstr "Site:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Suporte..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4782,6 +4915,11 @@ msgid "Testing"
msgstr "Em teste"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Carregar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Ficheiro ZIP de Ativos"
@@ -4837,32 +4975,32 @@ msgid "Rotation Step:"
msgstr "Passo da rotação:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr "Mover guia vertical"
+msgid "Move Vertical Guide"
+msgstr "Mover Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Criar nova guia vertical"
+msgid "Create Vertical Guide"
+msgstr "Criar Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Remover guia vertical"
+msgid "Remove Vertical Guide"
+msgstr "Remover Guia Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr "Mover guia horizontal"
+msgid "Move Horizontal Guide"
+msgstr "Mover Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Criar nova guia horizontal"
+msgid "Create Horizontal Guide"
+msgstr "Criar Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr "Remover guia horizontal"
+msgid "Remove Horizontal Guide"
+msgstr "Remover Guia Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Criar guias horizontal e vertical"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Criar Guias Horizontais e Verticais"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4945,6 +5083,11 @@ msgid "Paste Pose"
msgstr "Colar Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Apagar Ossos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Criar Osso(s) Personalizado(s) a partis de Nó(s)"
@@ -4975,6 +5118,7 @@ msgid "Zoom Reset"
msgstr "Repor zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Modo seleção"
@@ -4996,14 +5140,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+RMB: seleção da lista de profundidade"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Modo mover"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Modo rodar"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Modo Escalar"
@@ -5029,6 +5176,7 @@ msgid "Toggle snapping."
msgstr "Alternar Ajuste."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Usar Ajuste"
@@ -5045,11 +5193,6 @@ msgid "Use Rotation Snap"
msgstr "Usar Ajuste de rotação"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurar Ajuste..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Ajuste relativo"
@@ -5062,6 +5205,11 @@ msgid "Smart Snapping"
msgstr "Ajuste Inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Ajuste..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "Ajustar ao Parente"
@@ -5276,16 +5424,6 @@ msgstr "Definir Manipulador"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Erro ao carregar imagem:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Sem pixeis com transparência > 128 na imagem..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Carregar máscara de emissão"
@@ -5596,14 +5734,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "A fonte de superfície é inválida (sem faces)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "O parente não tem faces sólidas para povoar."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Ãrea não pode ser mapeada."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selecione uma fonte Malha:"
@@ -5687,20 +5817,27 @@ msgid "Generation Time (sec):"
msgstr "Tempo de geração (s):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "As faces não contêm Ãrea!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "O Nó não contêm geometria (faces)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Sem faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "O Nó não contêm geometria."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "O Nó não contêm geometria (faces)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "O Nó não contêm geometria."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6032,7 +6169,6 @@ msgid "Grid Settings"
msgstr "Configurações da Grelha"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Ajustar"
@@ -6138,12 +6274,9 @@ msgid "Error writing TextFile:"
msgstr "Erro ao escrever TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Erro ao carregar ficheiro."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Erro ao carregar ficheiro."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Tile não encontrado:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6166,7 +6299,8 @@ msgid "Error Importing"
msgstr "Erro ao importar"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Novo TextFile..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6247,6 +6381,11 @@ msgid "Open..."
msgstr "Abrir..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Abrir Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Guardar tudo"
@@ -6284,13 +6423,13 @@ msgid "Save Theme"
msgstr "Guardar tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Fechar documentos"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Fechar tudo"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Fechar documentos"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Executar"
@@ -6378,6 +6517,11 @@ msgstr "Depurador"
msgid "Search Results"
msgstr "Resultados da Pesquisa"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Limpar Cenas Recentes"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "Conecções ao método:"
@@ -6444,8 +6588,9 @@ msgid "Syntax Highlighter"
msgstr "Destaque de Sintaxe"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Ir Para"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6453,9 +6598,8 @@ msgid "Bookmarks"
msgstr "Marcadores"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Criar pontos."
+msgstr "Pontos de paragem"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6479,22 +6623,6 @@ msgid "Toggle Comment"
msgstr "Alternar comentário"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Alternar Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Ir para Próximo Marcador"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Ir para Marcador Anterior"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Remover todos os Marcadores"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Fechar/Abrir Linha"
@@ -6515,6 +6643,11 @@ msgid "Complete Symbol"
msgstr "Completar símbolo"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Escalar Selecção"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Apagar espaços nos limites"
@@ -6531,29 +6664,32 @@ msgid "Auto Indent"
msgstr "Indentação automática"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Alternar Breakpoint"
+msgid "Find Previous"
+msgstr "Localizar Anterior"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Remover todos os Breakpoints"
+msgid "Find in Files..."
+msgstr "Localizar em Ficheiros..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Ir para Próximo Breakpoint"
+msgid "Contextual Help"
+msgstr "Ajuda contextual"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Ir para Breakpoint Anterior"
+msgid "Toggle Bookmark"
+msgstr "Alternar Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Localizar Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Ir para Próximo Marcador"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Localizar em Ficheiros..."
+msgid "Go to Previous Bookmark"
+msgstr "Ir para Marcador Anterior"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Remover todos os Marcadores"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6564,8 +6700,21 @@ msgid "Go to Line..."
msgstr "Ir para Linha..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Ajuda contextual"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Alternar Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Remover todos os Breakpoints"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Ir para Próximo Breakpoint"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Ir para Breakpoint Anterior"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6744,9 +6893,15 @@ msgid "Rear"
msgstr "Trás"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+#, fuzzy
+msgid "Align Transform with View"
msgstr "Alinhar com a Vista"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Alinhar seleção com vista"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "Sem parente para criar instância de filho."
@@ -6800,8 +6955,9 @@ msgid "Audio Listener"
msgstr "Audição de áudio"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Doppler Ativo"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Ativar Filtragem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6856,8 +7012,8 @@ msgid "Snap Nodes To Floor"
msgstr "Ajustar Nós ao Fundo"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Modo seleção (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6870,30 +7026,11 @@ msgstr ""
"Alt+RMB: Seleção lista de profundidade"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Modo mover (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Modo rodar (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Modo escalar (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Coordenadas Locais"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Modo Espaço Local (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Modo Ajuste (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Vista de fundo"
@@ -6934,26 +7071,6 @@ msgid "Focus Selection"
msgstr "Focar na seleção"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Alinhar seleção com vista"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Seleção de ferramenta"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Ferramenta Mover"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Ferramenta Rodar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Ferramenta escalar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Alternar Freelook"
@@ -7008,7 +7125,8 @@ msgstr "Ver grelha"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Configuração"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7301,10 +7419,6 @@ msgid "TextureRegion"
msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Impossível guardar tema para Ficheiro:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Adicionar todos os itens"
@@ -7389,11 +7503,13 @@ msgid "Submenu"
msgstr "Sub-menu"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Item 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Item 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7498,14 +7614,6 @@ msgid "Transpose"
msgstr "Transpor"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Espelho X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Espelho Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Desativar Autotile"
@@ -7518,9 +7626,10 @@ msgid "Paint Tile"
msgstr "Pintar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+RMB: Desenho de Linha\n"
"Shift+Ctrl+RMB: Pintura de Retângulo"
@@ -7817,6 +7926,10 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(Apenas GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Adicionar entrada +"
@@ -7893,6 +8006,11 @@ msgid "Duplicate Nodes"
msgstr "Duplicar Nós"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Colar Nós"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Apagar Nós"
@@ -7913,6 +8031,11 @@ msgid "Light"
msgstr "Luz"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Criar Nó Shader"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Criar Nó Shader"
@@ -7985,6 +8108,22 @@ msgid "Color uniform."
msgstr "Uniforme Cor."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Devolve o resultado lógico da comparação %s entre dois parâmetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "Igual (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Maior Que (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Maior ou Igual a (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7993,12 +8132,50 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+"Devolve o resultado lógico da comparação entre INF e um parâmetro escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+"Devolve o resultado lógico da comparação entre NaN e um parâmetro escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Menor Que (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Menor ou Igual a (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Diferente (!=)"
+
+#: 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
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Devolve o resultado lógico da comparação entre dois parâmetros."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Devolve o resultado lógico da comparação entre INF (ou NaN) e um parâmetro "
+"escalar."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Constante Lógica."
@@ -8087,16 +8264,16 @@ msgid "Returns the arc-cosine of the parameter."
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 "(Apenas GLES3) Devolve o arco cosseno hiperbólico do parâmetro."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "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 "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 "(Apenas GLES3) Devolve o arco seno hiperbólico do parâmetro."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Devolve o arco seno hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8107,8 +8284,8 @@ msgid "Returns the arc-tangent of the parameters."
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 "(Apenas GLES3) Devolve o arco tangente hiperbólico do parâmetro."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Devolve o arco tangente hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8124,8 +8301,8 @@ msgid "Returns the cosine of the parameter."
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 "(Apenas GLES3) Devolve o cosseno hiperbólico do parâmetro."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Devolve o cosseno hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8193,12 +8370,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / escalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Apenas GLES3) Encontra o inteiro mais próximo do parâmetro."
+msgid "Finds the nearest integer to the parameter."
+msgstr "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 "(Apenas GLES3) Encontra o inteiro ímpar mais próximo do parâmetro."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "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."
@@ -8213,18 +8390,19 @@ msgid "Returns the sine of the parameter."
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 "(Apenas GLES3) Devolve o seno hiperbólico do parâmetro."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Devolve o seno hiperbólico do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Devolve a raiz quadrada do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8235,10 +8413,11 @@ msgstr ""
"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Função Step( escalar(limite), escalar(x) ).\n"
"\n"
@@ -8249,12 +8428,12 @@ msgid "Returns the tangent of the parameter."
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 "(Apenas GLES3) Devolve a tangente hiperbólica do parâmetro."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "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 "(Apenas GLES3) Encontra o valor truncado do parâmetro."
+msgid "Finds the truncated value of the parameter."
+msgstr "Encontra o valor truncado do parâmetro."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8293,12 +8472,16 @@ msgid "Perform the texture lookup."
msgstr "Executa texture lookup."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Uniforme Textura Cúbica."
+msgid "Cubic texture uniform lookup."
+msgstr "Consulta uniforme de textura cúbica."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "Uniforme Textura 2D."
+msgid "2D texture uniform lookup."
+msgstr "Consulta uniforme de textura 2D."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Consulta uniforme de textura 2D com triplanar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8306,7 +8489,7 @@ msgstr "Função Transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8314,7 +8497,7 @@ 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"
+"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 "
@@ -8331,16 +8514,16 @@ msgid "Decomposes transform to four vectors."
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 "(Apenas GLES3) Calcula o determinante de uma transformação."
+msgid "Calculates the determinant of a transform."
+msgstr "Calcula o determinante de uma transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(Apenas GLES3) Calcula o inverso de uma transformação."
+msgid "Calculates the inverse of a transform."
+msgstr "Calcula o inverso de uma transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(Apenas GLES3) Calcula a transposta de uma transformação."
+msgid "Calculates the transpose of a transform."
+msgstr "Calcula a transposta de uma transformação."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8388,7 +8571,7 @@ msgstr "Calcula o produto escalar de dois vetores."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8407,6 +8590,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Interpolação linear entre dois vetores."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Interpolação linear entre dois vetores."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Calcula o produto normalizado do vetor."
@@ -8420,21 +8608,22 @@ msgstr "1.0 / vetor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+msgid "Returns the vector that points in the direction of refraction."
msgstr "Devolve um vetor que aponta na direção da refração."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8445,10 +8634,11 @@ msgstr ""
"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8459,20 +8649,22 @@ msgstr ""
"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than '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
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"Função Step( escalar(limite), vetor(x) ).\n"
"\n"
@@ -8526,60 +8718,64 @@ msgstr ""
"da câmara (passa entradas associadas)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
-msgstr "(Apenas GLES3) (apenas modo Fragment/Light) Função derivada escalar."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(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 "(Apenas GLES3) (apenas modo Fragment/Light) Função derivada vetorial."
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(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."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr "(Apenas modo Fragment/Light) Derivada 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."
+"(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."
+"(Apenas modo Fragment/Light) (Escalar) Derivada 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."
+"(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."
+"(Apenas modo Fragment/Light) (Vetor) Derivada 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."
+"(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."
+"(Apenas modo Fragment/Light) (Escalar) Derivada 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'."
+"(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'."
+"(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'."
+"(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'."
+"(Apenas modo Fragment/Light) (Escalar) Soma das derivadas absolutas em 'x' e "
+"'y'."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8755,6 +8951,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Não existem Modelos de exportação para esta plataforma:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Gerir Modelos de Exportação"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Exportar com depuração"
@@ -8914,6 +9114,15 @@ msgid "Unnamed Project"
msgstr "Projeto sem nome"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Importar Projeto existente"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Impossível abrir Projeto em '%s'."
@@ -9010,12 +9219,13 @@ msgstr ""
"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)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Remover da lista todos os projeto em falta? (O conteúdo da pasta não será "
-"modificado)"
+"Remover %d projetos da lista?\n"
+"O conteúdo das pastas não será modificado."
#: editor/project_manager.cpp
msgid ""
@@ -9039,8 +9249,9 @@ msgid "Project Manager"
msgstr "Gestor de Projeto"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Lista de Projetos"
+#, fuzzy
+msgid "Projects"
+msgstr "Projeto"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9063,10 +9274,6 @@ msgid "Templates"
msgstr "Modelos"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Sair"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Reiniciar agora"
@@ -9406,6 +9613,10 @@ msgstr "Localizações:"
msgid "AutoLoad"
msgstr "Carregamento automático"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugins"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Zero"
@@ -9458,14 +9669,6 @@ msgstr "Selecione Método virtual"
msgid "Select Method"
msgstr "Selecione Método"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Impossível executar ferramenta PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "Impossível carregar imagem convertida com a ferramenta PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Renomear em massa"
@@ -9759,6 +9962,11 @@ msgid "Remove Node(s)"
msgstr "Remover Nó(s)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Mudar nome de porta de saída"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9803,6 +10011,11 @@ msgid "Extend Script"
msgstr "Estender Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Recolocar Nó"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Tornar Nó Raiz"
@@ -9875,24 +10088,27 @@ msgid "Node configuration warning:"
msgstr "Aviso de configuração do Nó:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Nó tem conexões e grupos.\n"
"Clique para mostrar doca dos sinais."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Nó tem conexões.\n"
"Clique para mostrar doca dos sinais."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Nó está em grupo(s).\n"
@@ -9991,6 +10207,11 @@ msgid "Error loading script from %s"
msgstr "Erro ao carregar Script de '%s'"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Sobrescrever"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
@@ -10019,8 +10240,8 @@ msgid "Script is valid."
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 _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Permitido: a-z, A-Z, 0-9, _ e ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10179,6 +10400,10 @@ msgid "Change Shortcut"
msgstr "Alterar Atalho"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Configurações do Editor"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Atalhos"
@@ -10597,10 +10822,30 @@ msgid "Set Variable Type"
msgstr "Definir tipo de variável"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Não pode coincidir com um nome de um tipo incorporado já existente."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Criar novo retângulo."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variáveis:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Criar novo retângulo."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Criar um novo polígono."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "O nome não é um identificador válido:"
@@ -10789,10 +11034,6 @@ msgid "Cut Nodes"
msgstr "Cortar Nós"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Colar Nós"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Editar Membros"
@@ -11090,13 +11331,12 @@ 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 "
"order for AnimatedSprite to display frames."
msgstr ""
-"Um recurso SpriteFrames tem de ser criado ou definido na Propriedade "
-"'Frames' para que AnimatedSprite mostre Frames."
+"Um recurso SpriteFrames tem de ser criado ou definido na Propriedade \"Frames"
+"\" para que AnimatedSprite mostre frames."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -11159,13 +11399,12 @@ 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\" "
"property."
msgstr ""
"Uma textura com a forma da luz tem de ser disponibilizada na Propriedade "
-"'textura'."
+"\"Textura\"."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11175,9 +11414,8 @@ msgstr ""
"efeito."
#: scene/2d/light_occluder_2d.cpp
-#, 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!"
+msgstr "O polígono oclusor deste oclusor está vazio. Desenhe um polígono."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11273,18 +11511,16 @@ msgstr ""
"KinematicBody2D, etc. para lhes dar uma forma."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
-"VisibilityEnable2D funciona melhor quando usado diretamente como parente na "
+"VisibilityEnabler2D funciona melhor quando usado diretamente como parente na "
"Cena raiz editada."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera precisa de um Nó ARVROrigin como parente"
+msgstr "ARVRCamera precisa de um Nó ARVROrigin como parente."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11374,13 +11610,12 @@ 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."
msgstr ""
"Uma forma tem de ser fornecida para CollisionShape funcionar. Crie um "
-"recurso forma!"
+"recurso forma."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11416,7 +11651,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "Uma SpotLight com ângulo superior a 90 graus não cria sombras."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11461,13 +11696,12 @@ 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'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."
+"ROTATION_ORIENTED de PathFollow requer \"Up Vector\" habilitado no recurso "
+"de Curva do Caminho do seu pai."
#: scene/3d/physics_body.cpp
msgid ""
@@ -11480,13 +11714,12 @@ msgstr ""
"Mude antes o tamanho das formas de colisão filhas."
#: scene/3d/remote_transform.cpp
-#, 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."
+"Para funcionar, a Propriedade \"Caminho Remoto\" tem de apontar para um Nó "
+"Spatial válido ou seu derivado."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11503,13 +11736,12 @@ 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 "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Um recurso SpriteFrames tem de ser criado ou definido na Propriedade "
-"'Frames' de forma a que AnimatedSprite3D mostre frames."
+"Um recurso SpriteFrames tem de ser criado ou definido na Propriedade \"Frames"
+"\" de forma a que AnimatedSprite3D mostre frames."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11524,6 +11756,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment exige que a sua propriedade \"Ambiente\" contenha um "
+"Ambiente para obter efeitos visíveis."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11561,9 +11795,8 @@ msgid "Nothing connected to input '%s' of node '%s'."
msgstr "Nada conectado à entrada '%s' do nó '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
-msgstr "Não foi definida um AnimationNode raiz para o gráfico."
+msgstr "Não foi definida uma raíz AnimationNode para o gráfico."
#: scene/animation/animation_tree.cpp
msgid "Path to an AnimationPlayer node containing animations is not set."
@@ -11576,9 +11809,8 @@ msgstr ""
"O caminho definido para AnimationPlayer não conduz a um nó AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "A raiz de AnimationPlayer não é um nó válido."
+msgstr "O Nó raiz de AnimationPlayer não é um Nó válido."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
@@ -11605,7 +11837,6 @@ msgid "Add current color as a preset."
msgstr "Adicionar cor atual como predefinição."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
@@ -11613,7 +11844,7 @@ msgid ""
msgstr ""
"Por si só um Contentor não tem utilidade, a não ser que um script configure "
"a disposição dos seu filhos.\n"
-"Se não pretende adicionar um script, use antes um simples Nó 'Control'."
+"Se não pretende adicionar um script, use antes um simples Nó Control."
#: scene/gui/control.cpp
msgid ""
@@ -11633,30 +11864,27 @@ 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, 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."
+"das funções popup*(). Torná-las visíveis para edição é aceitável, mas "
+"estarão escondidas na execução."
#: scene/gui/range.cpp
-#, 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."
+msgstr "Se \"Exp Edit\" está ativado, \"Min Value\" tem de ser maior que 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 "
"minimum size manually."
msgstr ""
-"ScrollContainer está destinado a funcionar com um único controlo filho.\n"
-"Use um contentor como filho (VBox,HBox,etc), um um Control e defina o "
+"ScrollContainer deve ser usado com um único controlo filho.\n"
+"Use um contentor como filho (VBox, HBox, etc.), ou um Control e defina o "
"tamanho mínimo manualmente."
#: scene/gui/tree.cpp
@@ -11683,35 +11911,22 @@ msgstr ""
"Control de modo a que obtenha um tamanho. Caso contrário, torne-a um "
"RenderTarget e atribua a sua textura interna a outro Nó para visualizar."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Erro ao inicializar FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Formato de letra inválido."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Erro ao carregar letra."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Tamanho de letra inválido."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Entrada"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Fonte inválida para Shader."
+msgstr "Fonte inválida para previsualização."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Fonte inválida para Shader."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Função de comparação inválida para este tipo."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Atribuição a função."
@@ -11728,6 +11943,127 @@ msgstr "Variações só podem ser atribuídas na função vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem ser modificadas."
+#~ msgid "No Matches"
+#~ msgstr "Sem combinações"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "file_type_cache.cch não for guardada, por não se conseguir abrir para "
+#~ "leitura!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "'%s' não foi encontrado no Sistema de Ficheiros!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Erro ao carregar imagem:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Sem pixeis com transparência > 128 na imagem..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "O parente não tem faces sólidas para povoar."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Ãrea não pode ser mapeada."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "As faces não contêm Ãrea!"
+
+#~ msgid "No faces!"
+#~ msgstr "Sem faces!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Erro ao carregar ficheiro."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Erro ao carregar ficheiro."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Doppler Ativo"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Modo seleção (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Modo mover (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Modo rodar (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Modo escalar (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Coordenadas Locais"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Modo Ajuste (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Seleção de ferramenta"
+
+#~ msgid "Tool Move"
+#~ msgstr "Ferramenta Mover"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Ferramenta Rodar"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Ferramenta escalar"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Remover da lista todos os projeto em falta? (O conteúdo da pasta não será "
+#~ "modificado)"
+
+#~ msgid "Project List"
+#~ msgstr "Lista de Projetos"
+
+#~ msgid "Exit"
+#~ msgstr "Sair"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Impossível executar ferramenta PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "Impossível carregar imagem convertida com a ferramenta PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Erro ao inicializar FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Formato de letra inválido."
+
+#~ msgid "Error loading font."
+#~ msgstr "Erro ao carregar letra."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Tamanho de letra inválido."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Pasta Anterior"
+
+#~ msgid "Next Folder"
+#~ msgstr "Próxima Pasta"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Abrir Capturas do ecrã automaticamente"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Abrir num editor de imagem externo."
+
+#~ msgid "Reverse"
+#~ msgstr "Inverter"
+
+#~ msgid "Mirror X"
+#~ msgstr "Espelho X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Espelho Y"
+
#~ msgid "Generating solution..."
#~ msgstr "A gerar soluções..."
@@ -12478,9 +12814,6 @@ msgstr "Constantes não podem ser modificadas."
#~ msgid "Erase selection"
#~ msgstr "Apagar seleção"
-#~ msgid "Could not find tile:"
-#~ msgstr "Tile não encontrado:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Nome ou ID do item:"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index b204bf19fd..93589e06f6 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -63,7 +63,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Gratuit"
@@ -136,6 +135,31 @@ msgstr "Anim Schimbare apelare"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Schimbați Timpul Cadru Cheie"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Schimbați Tranziție"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Schimbare transformare"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Schimbare valoare cadre cheie"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Schimbare apelare"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Schimbă Numele Animației:"
@@ -655,17 +679,18 @@ msgid "Line Number:"
msgstr "Linia Numărul:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "ÃŽnlocuit %d potriviri."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Nici o Potrivire"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "ÃŽnlocuit %d potriviri."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Potrivește Caz-ul"
@@ -905,8 +930,7 @@ msgstr "Favorite:"
msgid "Recent:"
msgstr "Recent:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1010,7 +1034,7 @@ msgstr ""
"sa funcționeze.\n"
"Ștergeți oricum? (fără anulare)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nu se poate șterge:"
@@ -1048,7 +1072,7 @@ msgstr "Ștergeți permanent %d articol(e)? (Fără anulare!)"
msgid "Show Dependencies"
msgstr "Dependențe"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Explorator de Resurse Orfane"
@@ -1137,14 +1161,16 @@ msgid "License"
msgstr "Licență"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licenţe Thirdparty"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Motorul Godot se bazează pe un număr de biblioteci thirdparty gratis și "
@@ -1165,7 +1191,8 @@ msgid "Licenses"
msgstr "Licențe"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Eroare la deschiderea fişierului pachet, nu este în format zip."
#: editor/editor_asset_installer.cpp
@@ -1183,7 +1210,6 @@ msgid "Success!"
msgstr "Succes!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalați"
@@ -1680,12 +1706,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importă"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportare"
@@ -1756,7 +1781,7 @@ msgstr "Arătați în Administratorul de Fișiere"
msgid "New Folder..."
msgstr "Director Nou..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Reîmprospătați"
@@ -1807,7 +1832,7 @@ msgstr "ÃŽnainte"
msgid "Go Up"
msgstr "Sus"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Comutați Fișiere Ascunse"
@@ -1833,27 +1858,32 @@ msgstr "Deplasați Favorit Jos"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Fila anterioară"
+msgid "Go to previous folder."
+msgstr "Accesați Directorul Părinte"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Creați Director"
+msgid "Go to next folder."
+msgstr "Accesați Directorul Părinte"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Accesați Directorul Părinte"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Căutare Clase"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Directorul nu a putut fi creat."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Comutați Fișiere Ascunse"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2115,6 +2145,10 @@ msgstr "Curăță"
msgid "Clear Output"
msgstr "Curăță Afișarea"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Exportul de proiect nu a reuÅŸit cu un cod de eroare %d."
@@ -2441,6 +2475,15 @@ msgid "Pick a Main Scene"
msgstr "Alege o Scenă Principală"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "ÃŽnchide Scena"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "ÃŽnchide Scena"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Nu se poate inițializa plugin-ul la: '%s' analizarea configurației a eșuat."
@@ -2557,6 +2600,11 @@ msgstr "Rulează Scena"
msgid "Close Tab"
msgstr "Aproape"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Aproape"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2611,6 +2659,11 @@ msgid "Go to previously opened scene."
msgstr "Mergi la o scenă deschisă anterior."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Copiaţi Calea"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Fila următoare"
@@ -2638,6 +2691,10 @@ msgstr "Scenă Derivată Nouă..."
msgid "Open Scene..."
msgstr "Deschide Scena..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Deschide Recente"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Salvează Scena"
@@ -2648,14 +2705,6 @@ msgid "Save All Scenes"
msgstr "Salvează toate Scenele"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "ÃŽnchide Scena"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Deschide Recente"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Convertește În..."
@@ -2685,26 +2734,37 @@ msgstr "Restabilește Scena"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Proiect Divers sau unelte pentru scenă."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Proiect"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Setări ale Proiectului"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Unelte"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportare"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Deschizi Managerul de Proiect?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Unelte"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Explorator de Resurse Orfane"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2802,12 +2862,13 @@ msgstr ""
"Când această opțiune este folosită de la distanță pe un dispozitiv, este "
"mult mai eficient dacă este folosit un sistem de fișiere în rețea."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Setări ale Editorului"
#: editor/editor_node.cpp
@@ -2825,15 +2886,6 @@ 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"
@@ -2858,14 +2910,15 @@ msgstr "Setări ale Editorului"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Administrează Șabloanele de Export"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Administrează Șabloanele de Export"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ajutor"
@@ -2873,12 +2926,13 @@ msgstr "Ajutor"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Căutare"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentație Online"
@@ -3159,6 +3213,11 @@ msgstr "Timp"
msgid "Calls"
msgstr "Apeluri"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Membri"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3327,7 +3386,8 @@ msgid "Import From Node:"
msgstr "Importă Din Nod:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Descarcă din nou"
#: editor/export_template_manager.cpp
@@ -3344,6 +3404,10 @@ msgid "Download"
msgstr "Descarcă"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Lipsește)"
@@ -3408,12 +3472,10 @@ msgid "No response."
msgstr "Niciun răspuns."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Cerere Eșuată."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Buclă de Redirecționare."
@@ -3427,13 +3489,19 @@ msgid "Download Complete."
msgstr "Descărcare Completă."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nu se poate șterge:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Eroare la solicitarea URL: "
#: editor/export_template_manager.cpp
@@ -3521,24 +3589,12 @@ msgstr "Descarcă Șabloane"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Selectează oglinda din listă: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Nu se poate deschide file_type_cache.cch pentru scriere, nu se salvează "
-"fișierul tip cache!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Favorite:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Nu se poate naviga către '%s' pentru că nu a fost găsit în sistemul de "
-"fișiere!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Stare: Importarea fișierului eșuată. Te rog repară fișierul și reimportă "
@@ -3574,14 +3630,14 @@ msgid "Provided name contains invalid characters."
msgstr "Numele furnizat conține caractere nevalide"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Numele furnizat conține caractere nevalide."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Un fișier sau un director cu acest nume există deja."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Numele furnizat conține caractere nevalide."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Redenumind fișierul:"
@@ -3641,6 +3697,11 @@ msgstr "Duplicați..."
msgid "Move To..."
msgstr "Mută În..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Scenă Nouă"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3715,6 +3776,11 @@ msgstr "Un fișier sau un director cu acest nume există deja."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Salvează Scena"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3784,6 +3850,14 @@ msgid "Search complete"
msgstr "Căutați Text"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Adaugă în Grup"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Elimină din Grup"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "EROARE: Numele animației există deja!"
@@ -3793,13 +3867,23 @@ msgstr "EROARE: Numele animației există deja!"
msgid "Invalid group name."
msgstr "Nume nevalid."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Grupuri"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Șterge Schema"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupuri"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Adaugă în Grup"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3813,12 +3897,13 @@ msgid "Nodes in Group"
msgstr "Adaugă în Grup"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Adaugă în Grup"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Elimină din Grup"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Deschide Editorul de Scripturi"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4030,7 +4115,8 @@ msgid "MultiNode Set"
msgstr "Set MultiNod"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Selectează un Nod pentru a edita Semnalele și Grupurile."
#: editor/plugin_config_dialog.cpp
@@ -4830,10 +4916,6 @@ msgid "View Files"
msgstr "Vizualizează Fișierele"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Nu se poate rezolva numele gazdei:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Eroare la conectare, te rog încearcă din nou."
@@ -4846,14 +4928,47 @@ msgid "No response from host:"
msgstr "Nciun răspuns de la gazda:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Nu se poate rezolva numele gazdei:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Cerere eșuată, cod returnat:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Cerere Eșuată."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nu se poate șterge:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Cerere eșuată, prea multe redirecționări"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Buclă de Redirecționare."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Cerere eșuată, cod returnat:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Timp"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Hash eronat de descărcare, se presupune că fișierul este falsificat."
@@ -4896,6 +5011,11 @@ msgid "Idle"
msgstr "Inactiv"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Instalați"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Reîncearcă"
@@ -4927,13 +5047,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Toate"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importă"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Plugin-uri"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4941,8 +5065,9 @@ msgid "Sort:"
msgstr "Sorare:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Revers"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Se Solicită..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4954,7 +5079,8 @@ msgid "Site:"
msgstr "Site:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Suport..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4966,6 +5092,11 @@ msgid "Testing"
msgstr "Se Testează"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Încărcați"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Fișier ZIP cu Asset-uri"
@@ -5023,31 +5154,38 @@ msgid "Rotation Step:"
msgstr "Pas Rotație:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Mută ghidul vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Creează un nou ghid vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Elimină ghidul vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Mută ghidul orizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Creează un nou ghid orizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Elimină ghidul orizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Creează ghizi noi orizontal și vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5137,6 +5275,11 @@ msgstr "Lipește Postura"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Curăță Postura"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Creează Puncte de Emisie Din Mesh"
@@ -5167,6 +5310,7 @@ msgid "Zoom Reset"
msgstr "Zoom-ați Afară"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Mod Selectare"
@@ -5189,14 +5333,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+RMB: Selecție adâncime listă"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Mod Mutare"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Mod Rotație"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Mod Redimensionare (R)"
@@ -5224,6 +5371,7 @@ msgid "Toggle snapping."
msgstr "Comutare snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Utilizează Snap"
@@ -5242,11 +5390,6 @@ msgid "Use Rotation Snap"
msgstr "Folosește Rotația Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Configurare Snap..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Snap Relativ"
@@ -5260,6 +5403,11 @@ msgid "Smart Snapping"
msgstr "Snapping inteligent"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurare Snap..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Snap către părinte"
@@ -5482,16 +5630,6 @@ msgstr "Setează Mâner"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Eroare la încărcarea imaginii:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Nici un pixel cu transparența > 128 în imagine..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Încărcare Mască de Emisie"
@@ -5814,14 +5952,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Sursa suprafeței nevalidă (nu există fețe)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Părintele nu are fețe solide pentru a fi populate."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Nu s-a putut mapa zona."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Selectează un Mesh Sursă:"
@@ -5908,20 +6038,27 @@ msgid "Generation Time (sec):"
msgstr "Timp de Generare (sec):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Unele fețe nu conțin zonă!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Nici o zonă!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Nodul nu conține geometrie (fețe)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Nodul nu conține geometrie."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Nodul nu conține geometrie (fețe)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Nodul nu conține geometrie."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6263,7 +6400,6 @@ msgid "Grid Settings"
msgstr "Setări ale Editorului"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Aliniere"
@@ -6378,12 +6514,7 @@ msgstr "Eroare la salvarea TileSet!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Directorul nu a putut fi creat."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Directorul nu a putut fi creat."
#: editor/plugins/script_editor_plugin.cpp
@@ -6413,7 +6544,7 @@ msgstr "Eroare mutând:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Director Nou..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6499,6 +6630,11 @@ msgid "Open..."
msgstr "Deschide"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Execută Scriptul"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6538,11 +6674,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6633,6 +6769,11 @@ msgstr ""
msgid "Search Results"
msgstr "Căutați în Ajutor"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Curăță Scenele Recente"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6705,6 +6846,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6740,26 +6882,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Modul de Comutare"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Mergeți la Pasul Următor"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Mergeți la Pasul Anterior"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Eliminați Autoload"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6780,6 +6902,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Scalați Selecția"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6796,32 +6923,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtrează fișierele..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Mergeți la Pasul Următor"
+msgid "Toggle Bookmark"
+msgstr "Modul de Comutare"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Mergeți la Pasul Anterior"
+msgid "Go to Next Bookmark"
+msgstr "Mergeți la Pasul Următor"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Mergeți la Pasul Anterior"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtrează fișierele..."
+msgid "Remove All Bookmarks"
+msgstr "Eliminați Autoload"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6834,9 +6966,24 @@ msgid "Go to Line..."
msgstr "Duceți-vă la Linie"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Mergeți la Pasul Următor"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Mergeți la Pasul Anterior"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -7017,7 +7164,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7074,8 +7225,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Activare mod Doppler"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Schimbați Lung Anim"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7131,7 +7283,7 @@ msgid "Snap Nodes To Floor"
msgstr "Snap pe grilă"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7142,30 +7294,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Mod Redimensionare (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Mod Snap (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7206,26 +7338,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Unealtă Dimensiune"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7281,8 +7393,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Setări Snap"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7592,10 +7705,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7685,12 +7794,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Obiect %d"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Obiect %d"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7800,14 +7909,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7822,8 +7923,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8140,6 +8241,10 @@ msgid "TileSet"
msgstr "Set_de_Plăci..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Adaugă Intrare(Input)"
@@ -8229,6 +8334,11 @@ msgid "Duplicate Nodes"
msgstr "Anim Clonare Chei"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Creează Nod"
@@ -8251,6 +8361,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Creează Nod"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Creează Nod"
@@ -8329,6 +8444,22 @@ msgid "Color uniform."
msgstr "Anim Schimbare transformare"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8336,10 +8467,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8431,7 +8596,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8439,7 +8604,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8451,7 +8616,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8468,7 +8633,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8537,11 +8702,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8557,7 +8722,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8568,7 +8733,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8577,7 +8742,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8585,11 +8750,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8630,11 +8795,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8644,7 +8813,7 @@ msgstr "Crează Poligon"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8662,15 +8831,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8722,7 +8891,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8737,6 +8906,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8750,19 +8923,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8771,7 +8944,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8780,14 +8953,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8832,47 +9005,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9046,6 +9226,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Administrează Șabloanele de Export"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9193,6 +9377,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Proiect"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Imposibil de deschis '%s'."
@@ -9269,8 +9462,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9290,8 +9483,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Proiect"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9315,10 +9509,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9661,6 +9851,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Plugin-uri"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9713,14 +9907,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10022,6 +10208,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10068,6 +10258,11 @@ msgstr "Execută Scriptul"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Creați %s Nou"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Salvează Scena"
@@ -10144,19 +10339,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10253,6 +10448,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10285,7 +10484,7 @@ msgid "Script is valid."
msgstr "Arborele Animației este valid."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10450,6 +10649,10 @@ msgid "Change Shortcut"
msgstr "Modifică Ancorele"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Setări ale Editorului"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10867,10 +11070,32 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Nume nevalid. Nu trebuie să se lovească cu un nume de tip deja existent în "
+"motor tip."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Creați %s Nou"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Creați %s Nou"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Creează un nou poligon de la zero."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11058,10 +11283,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Membri"
@@ -11804,22 +12025,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11833,6 +12038,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11849,6 +12058,66 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Nu se poate deschide file_type_cache.cch pentru scriere, nu se salvează "
+#~ "fișierul tip cache!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Nu se poate naviga către '%s' pentru că nu a fost găsit în sistemul de "
+#~ "fișiere!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Eroare la încărcarea imaginii:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Nici un pixel cu transparența > 128 în imagine..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Părintele nu are fețe solide pentru a fi populate."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Nu s-a putut mapa zona."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Unele fețe nu conțin zonă!"
+
+#~ msgid "No faces!"
+#~ msgstr "Nici o zonă!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Directorul nu a putut fi creat."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Activare mod Doppler"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Mod Redimensionare (R)"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Mod Snap (%s)"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Unealtă Dimensiune"
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Fila anterioară"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Creați Director"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Deschide Editorul următor"
+
+#~ msgid "Reverse"
+#~ msgstr "Revers"
+
#~ msgid "View log"
#~ msgstr "Vizualizează fișiere log"
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index a3e64f65b0..3e61d4d683 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -51,12 +51,16 @@
# Teashrock <kajitsu22@gmail.com>, 2019.
# Дмитрий Ефимов <daefimov@gmail.com>, 2019.
# Sergey <www.window1@mail.ru>, 2019.
+# Vladislav <onion.ring@mail.ru>, 2019.
+# knightpp <kotteam99@gmail.com>, 2019.
+# КонÑтантин Рин <email.to.rean@gmail.com>, 2019.
+# Maxim Samburskiy <alpacones@outlook.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-09 10:46+0000\n"
-"Last-Translator: Sergey <www.window1@mail.ru>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: КонÑтантин Рин <email.to.rean@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -65,7 +69,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -108,7 +112,6 @@ msgid "On call to '%s':"
msgstr "Ðа вызове '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "ОÑвободить"
@@ -118,7 +121,7 @@ msgstr "СбаланÑированный"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr "Отобразить"
+msgstr "Отразить"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -177,6 +180,31 @@ msgid "Anim Change Call"
msgstr "Изменить вызов анимации"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Изменить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ð¾Ð³Ð¾ кадра"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Изменить переход"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Изменить положение"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Измененить значение ключевого кадра"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Изменить вызов анимации"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Изменить длину анимации"
@@ -211,7 +239,7 @@ msgstr "Трек ВоÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ðнимации"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "ПродолжительноÑÑ‚ÑŒ анимации (в кадрах)"
+msgstr "Длина анимации (в кадрах)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
@@ -482,7 +510,7 @@ 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
@@ -502,9 +530,8 @@ msgid "Group tracks by node or display them as plain list."
msgstr "Группировать треки по узлам или показывать их как проÑтой ÑпиÑок."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "ПривÑзка"
+msgstr "ПривÑзка:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -669,16 +696,18 @@ msgid "Line Number:"
msgstr "Ðомер Ñтроки:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Заменено %d Ñовпадений."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Ðет Ñовпадений"
+#, fuzzy
+msgid "%d match."
+msgstr "Ðайдено %d Ñовпадений."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Заменено %d Ñовпадений."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Ðайдено %d Ñовпадений."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -731,7 +760,7 @@ msgstr "Ðомера Ñтрок и Ñтолбцов."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr "Метод должен быть указан в целевом Узле. "
+msgstr "Метод должен быть указан в целевом узле."
#: editor/connections_dialog.cpp
msgid ""
@@ -755,9 +784,8 @@ msgid "From Signal:"
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
@@ -797,6 +825,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"
@@ -829,7 +859,6 @@ msgid "Connect"
msgstr "ПриÑоединить"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "Сигналы:"
@@ -855,9 +884,8 @@ msgid "Disconnect"
msgstr "ОтÑоединить"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect a Signal to a Method"
-msgstr "Подключить Ñигнал: "
+msgstr "Подключить Сигнал к Методу"
#: editor/connections_dialog.cpp
msgid "Edit Connection:"
@@ -908,8 +936,7 @@ msgstr "Избранное:"
msgid "Recent:"
msgstr "Ðедавнее:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -997,9 +1024,8 @@ msgid "Owners Of:"
msgstr "Владельцы:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Удалить выбранный файл из проекта? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)"
+msgstr "Удалить выбранные файлы из проекта? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)"
#: editor/dependency_editor.cpp
msgid ""
@@ -1010,7 +1036,7 @@ msgstr ""
"УдалÑемый файл требуетÑÑ Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ работы других реÑурÑов.\n"
"Ð’ÑÑ‘ равно удалить его? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Ðе удаётÑÑ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ:"
@@ -1046,7 +1072,7 @@ msgstr "ÐавÑегда удалить %d Ñлемент(ов)? (ÐÐµÐ»ÑŒÐ·Ñ Ð
msgid "Show Dependencies"
msgstr "Показать завиÑимоÑти"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Обзор подключённых реÑурÑов"
@@ -1135,14 +1161,16 @@ msgid "License"
msgstr "ЛицензиÑ"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Сторонние Лицензии"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Движок Godot опираетÑÑ Ð½Ð° Ñ€Ñд Ñторонних беÑплатных и открытых библиотек, "
@@ -1163,7 +1191,8 @@ msgid "Licenses"
msgstr "Лицензии"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Ошибка при открытии файла пакета, не в формате zip."
#: editor/editor_asset_installer.cpp
@@ -1180,7 +1209,6 @@ msgid "Success!"
msgstr "УÑпех!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "УÑтановить"
@@ -1307,7 +1335,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"
@@ -1377,7 +1405,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!"
@@ -1462,9 +1490,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"
@@ -1550,6 +1577,7 @@ msgstr "Файл шаблона не найден:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"Ðа 32-Ñ… битных ÑиÑтемах вÑтроенный PCK файл не может быть больше 4 Гбит."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1592,23 +1620,21 @@ msgstr "Заменить вÑÑ‘ (без возможноÑти отмены)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
msgstr ""
+"Ðазвание Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть корректным именем файла и не Ñодержать '.'"
#: editor/editor_feature_profile.cpp
msgid "Profile with this name already exists."
msgstr "Профиль Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled, Properties Disabled)"
msgstr "(Редактор отключен, СвойÑтва отключены)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Properties Disabled)"
msgstr "(СвойÑтва отключены)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
msgstr "(Редактор отключен)"
@@ -1623,29 +1649,27 @@ msgid "Enable Contextual Editor"
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. Remove it first before importing, import "
"aborted."
msgstr ""
+"Профиль '%s' уже ÑущеÑтвует. Удалите его перед импортом, импорт отменен."
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1654,7 +1678,7 @@ msgstr "Ошибка при загрузке шаблона '%s'"
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "СброÑить"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1672,12 +1696,11 @@ msgid "New"
msgstr "Ðовый"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Импорт"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "ЭкÑпорт"
@@ -1745,7 +1768,7 @@ msgstr "ПроÑмотреть в проводнике"
msgid "New Folder..."
msgstr "ÐÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Обновить"
@@ -1796,7 +1819,7 @@ msgstr "Вперёд"
msgid "Go Up"
msgstr "Вверх"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Скрыть файлы"
@@ -1821,24 +1844,30 @@ msgid "Move Favorite Down"
msgstr "ПеремеÑтить избранное вниз"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°"
+msgid "Go to previous folder."
+msgstr "Перейти к родительÑкой папке."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Перейти к родительÑкой папке."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Перейти к родительÑкой папке."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "ПоиÑк файлов"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Добавить или удалить текущую папку из избранных."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Скрыть файлы"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2078,6 +2107,11 @@ msgstr "ОчиÑтить"
msgid "Clear Output"
msgstr "ОчиÑтить вывод"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Окно"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "ЭкÑпорт проекта не удалÑÑ, код %d."
@@ -2281,9 +2315,8 @@ msgid "Open Base Scene"
msgstr "Открыть оÑновную Ñцену"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "БыÑтро открыть Ñцену..."
+msgstr "БыÑтрый доÑтуп..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2403,6 +2436,15 @@ msgid "Pick a Main Scene"
msgstr "Выберите главную Ñцену"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Закрыть Ñцену"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Закрыть Ñцену"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "Ðе удаётÑÑ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ плагин: '%s' ошибка конфигурации."
@@ -2419,8 +2461,8 @@ 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
msgid ""
@@ -2516,18 +2558,22 @@ msgstr "ЗапуÑтить Ñцену"
msgid "Close Tab"
msgstr "Закрыть вкладку"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Закрыть вкладку"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Закрыть другие вкладки"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Закрыть вкладки Ñправа"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "Закрыть вÑÑ‘"
+msgstr "Закрыть вÑе вкладки"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2570,6 +2616,11 @@ msgid "Go to previously opened scene."
msgstr "Перейти к предыдущей открытой Ñцене."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Копировать путь"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°"
@@ -2597,6 +2648,10 @@ msgstr "ÐÐ¾Ð²Ð°Ñ ÑƒÐ½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¡Ñ†ÐµÐ½Ð°..."
msgid "Open Scene..."
msgstr "Открыть Ñцену..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Открыть поÑледнее"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Сохранить Ñцену"
@@ -2606,14 +2661,6 @@ msgid "Save All Scenes"
msgstr "Сохранить вÑе Ñцены"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Закрыть Ñцену"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Открыть поÑледнее"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Конвертировать в..."
@@ -2643,25 +2690,36 @@ msgstr "ВоÑÑтановить Ñцену"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Прочие инÑтрументы."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Проект"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Параметры проекта"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ИнÑтрументы"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "ЭкÑпортировать..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "УÑтановить шаблон Ñборки Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Открыть папку Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ проекта"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ИнÑтрументы"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Обзор подключённых реÑурÑов"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2759,12 +2817,13 @@ msgstr ""
"При удалённом иÑпользовании на уÑтройÑтве, Ñто работает более Ñффективно Ñ "
"Ñетевой файловой ÑиÑтемой."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Редактор"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "ÐаÑтройки редактора"
#: editor/editor_node.cpp
@@ -2772,9 +2831,8 @@ msgid "Editor Layout"
msgstr "Макет редактора"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Создать корневой узел Ñцены"
+msgstr "Сделать Ñнимок Ñкрана"
#: editor/editor_node.cpp
#, fuzzy
@@ -2782,15 +2840,6 @@ 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 "Переключить полноÑкранный режим"
@@ -2813,14 +2862,15 @@ msgstr "Открыть папку наÑтроек редактора"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Управление шаблонами ÑкÑпорта"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Управление шаблонами ÑкÑпорта"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Справка"
@@ -2828,12 +2878,13 @@ msgstr "Справка"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "ПоиÑк"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлайн ДокументациÑ"
@@ -2907,9 +2958,8 @@ msgid "Spins when the editor window redraws."
msgstr "ВращаетÑÑ, когда окно редактора перериÑовываетÑÑ."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "ÐепрерывнаÑ"
+msgstr "Ðепрерывное обновление"
#: editor/editor_node.cpp
#, fuzzy
@@ -2917,9 +2967,8 @@ msgid "Update When Changed"
msgstr "ОбновлÑÑ‚ÑŒ при изменениÑÑ…"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Hide Update Spinner"
-msgstr "Отключить Ñчётчик обновлений"
+msgstr "Скрыть индикатор обновлений"
#: editor/editor_node.cpp
msgid "FileSystem"
@@ -2948,6 +2997,8 @@ msgstr "Ðе ÑохранÑÑ‚ÑŒ"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
msgstr ""
+"Шаблон Ñборки Android отÑутÑтвует, пожалуйÑта, уÑтановите ÑоответÑтвующие "
+"шаблоны."
#: editor/editor_node.cpp
#, fuzzy
@@ -3109,6 +3160,11 @@ msgstr "ВремÑ"
msgid "Calls"
msgstr "Вызовы"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Редактировать тему..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Вкл"
@@ -3280,7 +3336,8 @@ msgid "Import From Node:"
msgstr "Импортировать из Узла:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Перезагрузить"
#: editor/export_template_manager.cpp
@@ -3297,6 +3354,10 @@ msgid "Download"
msgstr "Загрузка"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(ОтÑутÑтвует)"
@@ -3360,12 +3421,10 @@ msgid "No response."
msgstr "Ðет ответа."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Ðе удалоÑÑŒ выполнить запроÑ."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "ЦикличеÑкое перенаправление."
@@ -3379,14 +3438,21 @@ msgid "Download Complete."
msgstr "Загрузка завершена."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Ðевозможно Ñохранить тему в файл:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Ошибка уÑтановки шаблона. Ðрхив Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð½Ñ‹Ð¼ шаблоном можно найти в '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Ошибка запроÑа адреÑа ÑÑылки: "
#: editor/export_template_manager.cpp
@@ -3457,7 +3523,6 @@ msgid "Remove Template"
msgstr "Удалить шаблон"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Select Template File"
msgstr "Выбрать файл шаблона"
@@ -3473,22 +3538,11 @@ msgstr "Загрузить Шаблоны"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Выберите зеркало из ÑпиÑка: (Shift+Click: Открыть в браузере)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Ðевозможно открыть file_type_cache.cch Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ðе будет Ñохранён кÑш "
-"типов файлов!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Избранное"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Ðе удаетÑÑ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸ к '%s', так как он не был найден в файловой ÑиÑтеме!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"СтатуÑ: Импорт файла не удалÑÑ. ПожалуйÑта, иÑправьте файл и "
@@ -3519,12 +3573,7 @@ msgid "No name provided."
msgstr "Ðе предоÑтавлено имÑ."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Provided name contains invalid characters."
-msgstr "Ð˜Ð¼Ñ Ñодержит недопуÑтимые Ñимволы"
-
-#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
msgstr "Ð˜Ð¼Ñ Ñодержит недопуÑтимые Ñимволы."
#: editor/filesystem_dock.cpp
@@ -3532,6 +3581,10 @@ msgid "A file or folder with this name already exists."
msgstr "Файл или папка Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Ð˜Ð¼Ñ Ñодержит недопуÑтимые Ñимволы."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Переименование файла:"
@@ -3548,26 +3601,22 @@ 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 "Добавить в избранное"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Remove from Favorites"
msgstr "Удалить из избранного"
@@ -3591,6 +3640,11 @@ msgstr "Дублировать..."
msgid "Move To..."
msgstr "ПеремеÑтить в..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "ÐÐ¾Ð²Ð°Ñ Ñцена"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Ðовый Ñкрипт..."
@@ -3617,21 +3671,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 "Переключить режим разделениÑ"
@@ -3659,6 +3710,11 @@ msgstr "По Ñтому пути уже ÑущеÑтвует файл или пÐ
msgid "Overwrite"
msgstr "ПерезапиÑать"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Создать из Ñцены"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Создать Ñкрипт"
@@ -3719,6 +3775,14 @@ msgid "Search complete"
msgstr "ПоиÑк завершен"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Добавить в группу"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Удалить из группы"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Ð˜Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ уже ÑущеÑтвует."
@@ -3726,12 +3790,23 @@ msgstr "Ð˜Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ уже ÑущеÑтвует."
msgid "Invalid group name."
msgstr "Ðеверное название группы."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Управление Группами"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Удалено изображение группы"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Группы"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Узлы не в Группе"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3744,12 +3819,12 @@ msgid "Nodes in Group"
msgstr "Узлы в Группе"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Добавить в группу"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Удалить из группы"
+msgid "Group Editor"
+msgstr "Редактор групп"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3957,7 +4032,8 @@ msgid "MultiNode Set"
msgstr "Мульти-узловый набор"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Выберите узел Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñигналов и групп."
#: editor/plugin_config_dialog.cpp
@@ -4123,9 +4199,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"
@@ -4195,9 +4270,8 @@ msgstr "Добавить узел к BlendTree"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node Moved"
-msgstr "Режим перемещениÑ"
+msgstr "Узел перемещён"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
@@ -4215,9 +4289,8 @@ msgid "Nodes Disconnected"
msgstr "Узлы разъединены"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "ÐнимациÑ"
+msgstr "Задать Ðнимацию"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4722,10 +4795,6 @@ msgid "View Files"
msgstr "ПроÑмотр Файлов"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Ðевозможно определить Ð¸Ð¼Ñ Ñ…Ð¾Ñта:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Ошибка подключениÑ, попробуйте ещё раз."
@@ -4738,14 +4807,47 @@ msgid "No response from host:"
msgstr "Ðет ответа от хоÑта:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Ðевозможно определить Ð¸Ð¼Ñ Ñ…Ð¾Ñта:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ удалÑÑ, код:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Ðе удалоÑÑŒ выполнить запроÑ."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Ðевозможно Ñохранить тему в файл:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ прошёл, Ñлишком много перенаправлений"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "ЦикличеÑкое перенаправление."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ удалÑÑ, код:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ВремÑ"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "ÐеÑовпадение Ñ…Ñша загрузки, возможно файл был изменён."
@@ -4786,6 +4888,10 @@ msgid "Idle"
msgstr "ПроÑтой"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "УÑтановить..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Повторить"
@@ -4814,13 +4920,17 @@ msgid "Last"
msgstr "ПоÑледнÑÑ"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Ð’Ñе"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Переимпортировать..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Плагины"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4828,8 +4938,8 @@ msgid "Sort:"
msgstr "Сортировать:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Обратно"
+msgid "Reverse sorting."
+msgstr "ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ñортировка."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4841,7 +4951,8 @@ msgid "Site:"
msgstr "Сайт:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Поддержка..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4853,6 +4964,11 @@ msgid "Testing"
msgstr "ТеÑтируемые"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Загрузка..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP файл аÑÑетов"
@@ -4909,32 +5025,34 @@ msgid "Rotation Step:"
msgstr "Шаг поворота:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Перемещение вертикальной направлÑющей"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "Создать вертикальную направлÑющую"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr "Убрать вертикальную направлÑющую"
+msgid "Remove Vertical Guide"
+msgstr "Удалить вертикальную направлÑющую"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "ПеремеÑтить горизонтальную направлÑющую"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Создать новую горизонтальную направлÑющую"
+msgid "Create Horizontal Guide"
+msgstr "Создать горизонтальную направлÑющую"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Удалить горизонтальную направлÑющую"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Создание новых горизонтальных и вертикальных направлÑющих"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Создать горизонтальные и вертикальные направлÑющие"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4990,27 +5108,23 @@ 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"
@@ -5018,6 +5132,11 @@ msgstr "Ð’Ñтавить позу"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "ОчиÑтить позу"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Сделать ПользовательÑкие КоÑÑ‚ÑŒ(и) от Узла(ов)"
@@ -5049,6 +5168,7 @@ msgid "Zoom Reset"
msgstr "СброÑить маÑштабирование"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Режим выделениÑ"
@@ -5071,14 +5191,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+ПКМ: СпиÑок выбора глубины"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Режим перемещениÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Режим поворота"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Режим маÑштабированиÑ"
@@ -5104,6 +5227,7 @@ msgid "Toggle snapping."
msgstr "Переключить привÑзки."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "ИÑпользовать привÑзку"
@@ -5112,7 +5236,6 @@ msgid "Snapping Options"
msgstr "Параметры ПривÑзки"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Grid"
msgstr "ПривÑзка к Ñетке"
@@ -5121,11 +5244,6 @@ msgid "Use Rotation Snap"
msgstr "ИÑпользовать привÑзку вращениÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "ÐаÑтроить привÑзку..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "ОтноÑÐ¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¸Ð²Ñзка"
@@ -5134,12 +5252,15 @@ 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
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "ÐаÑтроить привÑзку..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "ПривÑзка к родителю"
@@ -5164,7 +5285,6 @@ msgid "Snap to Other Nodes"
msgstr "ПривÑзка к другим узлам"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
msgstr "ПривÑзка к направлÑющим"
@@ -5368,16 +5488,6 @@ msgstr "Задать обработчик"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Ошибка при загрузке изображениÑ:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Ðикаких пикÑелей Ñ Ð¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ð¾Ñтью > 128 в изображении..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "МаÑка выброÑа загружена"
@@ -5385,9 +5495,8 @@ msgstr "МаÑка выброÑа загружена"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "ПерезапуÑтить ÑейчаÑ"
+msgstr "ПерезапуÑтить"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5469,12 +5578,10 @@ 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 "Удалить точку"
@@ -5555,9 +5662,8 @@ msgid "Failed creating shapes!"
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"
@@ -5699,14 +5805,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "ПоверхноÑÑ‚ÑŒ иÑточника недопуÑтима (нет граней)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Родитель не имеет твёрдых граней Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Ðе удалоÑÑŒ отобразить облаÑÑ‚ÑŒ."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Выберите иÑточник полиÑетки:"
@@ -5790,20 +5888,27 @@ msgid "Generation Time (sec):"
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ (Ñек):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Грани не Ñодержат зоны!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Узел не Ñодержит геометрии (грани)."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Ðет граней!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Узел не Ñодержит геометрии."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Узел не Ñодержит геометрии (грани)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Узел не Ñодержит геометрии."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6137,7 +6242,6 @@ msgid "Grid Settings"
msgstr "Параметры Ñетки"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "ПривÑзка"
@@ -6243,12 +6347,9 @@ msgid "Error writing TextFile:"
msgstr "Ошибка при запиÑи:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Ошибка: Ðе удалоÑÑŒ загрузить файл."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Ðе удалоÑÑŒ загрузить файл."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Ðевозможно найти тайл:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6271,7 +6372,8 @@ msgid "Error Importing"
msgstr "Ошибка Импорта"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Создать текÑтовый файл..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6355,6 +6457,11 @@ msgid "Open..."
msgstr "Открыть..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Открыть Ñкрипт"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Сохранить вÑÑ‘"
@@ -6392,13 +6499,13 @@ msgid "Save Theme"
msgstr "Сохранить тему"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Закрыть документацию"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Закрыть вÑÑ‘"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Закрыть документацию"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "ЗапуÑтить"
@@ -6488,20 +6595,23 @@ msgstr "Отладчик"
msgid "Search Results"
msgstr "Результаты поиÑка"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ОчиÑтить поÑледние Ñцены"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
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"
@@ -6558,18 +6668,18 @@ msgid "Syntax Highlighter"
msgstr "ПодÑветка СинтакÑиÑа"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+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 "Создать точки."
+msgstr "Точки оÑтанова"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6593,26 +6703,6 @@ msgid "Toggle Comment"
msgstr "Переключить комментарий"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Переключить Ñвободный обзор"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Перейти к Ñледующей точке оÑтановки"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Перейти к предыдущей точке оÑтановки"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Удалить вÑе Ñлементы"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Свернуть/Развернуть Ñтроку"
@@ -6633,6 +6723,11 @@ msgid "Complete Symbol"
msgstr "СпиÑок автозавершениÑ"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "МаÑштабировать выбранное"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Удаление пробелов в конце Ñтрок"
@@ -6649,29 +6744,33 @@ msgid "Auto Indent"
msgstr "ÐвтоотÑтуп"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Точка оÑтановки"
+msgid "Find Previous"
+msgstr "Ðайти предыдущее"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Удалить вÑе точки оÑтановок"
+msgid "Find in Files..."
+msgstr "Ðайти в файлах..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Перейти к Ñледующей точке оÑтановки"
+msgid "Contextual Help"
+msgstr "КонтекÑÑ‚Ð½Ð°Ñ Ñправка"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Перейти к предыдущей точке оÑтановки"
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "Переключить Ñвободный обзор"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Ðайти предыдущее"
+msgid "Go to Next Bookmark"
+msgstr "Перейти к Ñледующей закладке"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Ðайти в файлах..."
+msgid "Go to Previous Bookmark"
+msgstr "Перейти к предыдущей закладке"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Удалить вÑе закладки"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6682,8 +6781,21 @@ msgid "Go to Line..."
msgstr "Перейти к Ñтроке..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "КонтекÑÑ‚Ð½Ð°Ñ Ñправка"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Точка оÑтановки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Удалить вÑе точки оÑтановок"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Перейти к Ñледующей точке оÑтановки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Перейти к предыдущей точке оÑтановки"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6866,9 +6978,14 @@ msgstr "Зад"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "ВыравнÑÑ‚ÑŒ Ñ Ð¾Ð±Ð»Ð°Ñтью проÑмотра"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "СовмеÑтить выбранное Ñ Ð²Ð¸Ð´Ð¾Ð¼"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "Ðе выбран родитель Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ°."
@@ -6922,8 +7039,9 @@ msgid "Audio Listener"
msgstr "ПроÑлушиватель звука"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "ДоплеровÑкий режим"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Включить фильтр"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6980,8 +7098,8 @@ msgid "Snap Nodes To Floor"
msgstr "ПодравнÑÑ‚ÑŒ Узел Ñ ÐŸÐ¾Ð»Ð¾Ð¼"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Режим Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6994,30 +7112,11 @@ msgstr ""
"Alt+ПКМ: Выбор по ÑпиÑку"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Режим Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Режим поворота (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Режим маÑÑˆÑ‚Ð°Ð±Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Локальные координаты"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Режим локального проÑтранÑтва (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Режим привÑзки (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Вид Снизу"
@@ -7059,26 +7158,6 @@ msgid "Focus Selection"
msgstr "Показать выбранное"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "СовмеÑтить выбранное Ñ Ð²Ð¸Ð´Ð¾Ð¼"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "ИнÑтрумент выбора"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "ИнÑтрумент перемещениÑ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "ИнÑтрумент поворот"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "ИнÑтрумент маÑштаб"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Переключить Ñвободный обзор"
@@ -7134,7 +7213,8 @@ msgstr "Отображать Ñетку"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "ÐаÑтройки"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7207,19 +7287,16 @@ msgid "Create Mesh2D"
msgstr "Создать 2D Mesh"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon2D"
-msgstr "Создать Polygon3D"
+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
msgid "Sprite is empty!"
@@ -7235,9 +7312,8 @@ msgid "Invalid geometry, can't replace by mesh."
msgstr "ÐÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ, не может быть заменена Ñеткой."
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Convert to Mesh2D"
-msgstr "Преобразовать в 2D Mesh"
+msgstr "Преобразовать в Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -7293,9 +7369,8 @@ msgid "No Frames Selected"
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"
@@ -7346,13 +7421,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)"
@@ -7445,10 +7519,6 @@ msgid "TextureRegion"
msgstr "ОблаÑтьТекÑтуры"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Ðевозможно Ñохранить тему в файл:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Добавить вÑе Ñлементы"
@@ -7534,16 +7604,16 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Подменю"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Элемент"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Элемент"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7578,7 +7648,7 @@ msgstr "Редактируемые потомки"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Поддерево"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
@@ -7650,14 +7720,6 @@ msgid "Transpose"
msgstr "ТранÑпонировать"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Зеркально по X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Зеркально по Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "Ðвтотайлы"
@@ -7672,10 +7734,13 @@ msgid "Paint Tile"
msgstr "РиÑовать тайл"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift+RMB: ÐариÑовать линию\n"
+"Shift+Ctrl+RMB: ÐариÑовать прÑмоугольник"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
@@ -7982,6 +8047,10 @@ msgid "TileSet"
msgstr "Ðабор Тайлов"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(только GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Добавить вход"
@@ -7992,27 +8061,24 @@ msgid "Add output +"
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 ""
#: 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
@@ -8035,14 +8101,12 @@ msgid "Change output port name"
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
@@ -8072,6 +8136,11 @@ msgid "Duplicate Nodes"
msgstr "Дублировать узлы"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Ð’Ñтавить узлы"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Удалить узлы"
@@ -8093,13 +8162,17 @@ msgstr "Свет"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Create Shader Node"
+msgid "Show resulted shader code."
msgstr "Создать узел"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Create Shader Node"
+msgstr "Создать узел"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color function."
-msgstr "Перейти к функции"
+msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
@@ -8112,11 +8185,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
@@ -8171,6 +8244,22 @@ msgid "Color uniform."
msgstr "ОчиÑтить преобразование"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8178,10 +8267,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Меньше, чем (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "Изменить векторную конÑтанту"
@@ -8224,14 +8347,12 @@ msgid "'%s' input parameter for vertex and fragment 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."
@@ -8274,7 +8395,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8282,7 +8403,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8294,13 +8415,13 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr ""
+msgstr "ВычиÑлÑет ближайшее целое чиÑло, большее или равное аргументу."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
@@ -8308,15 +8429,15 @@ 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 ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Возвращает гиперболичеÑкий коÑÐ¸Ð½ÑƒÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "Переводит значение из радиан в градуÑÑ‹."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
@@ -8328,35 +8449,35 @@ msgstr ""
#: 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."
@@ -8373,23 +8494,23 @@ 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 ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "ВычиÑлÑет ближайшее целое чиÑло."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "ВычиÑлÑет ближайшее чётное чиÑло."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "Ограничивает значение в пределах от 0.0 до 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
@@ -8400,7 +8521,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8411,7 +8532,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8420,7 +8541,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8428,11 +8549,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8441,11 +8562,11 @@ 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."
@@ -8475,12 +8596,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "Изменить текÑтурную единицу"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "Изменить текÑтурную единицу"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "Изменить текÑтурную единицу"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8490,7 +8616,7 @@ msgstr "Окно преобразованиÑ..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8508,15 +8634,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "ВычиÑлÑет обратную транÑформацию."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8549,27 +8675,27 @@ 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 ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8577,11 +8703,16 @@ msgstr ""
#: 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
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
@@ -8597,19 +8728,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8618,7 +8749,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8627,27 +8758,27 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds vector to vector."
-msgstr ""
+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."
@@ -8681,47 +8812,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8899,6 +9037,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Шаблоны ÑкÑпорта Ð´Ð»Ñ Ñтой платформы отÑутÑтвуют:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Управление шаблонами ÑкÑпорта"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "ЭкÑпорт в режиме отладки"
@@ -9058,6 +9200,15 @@ msgid "Unnamed Project"
msgstr "БезымÑнный проект"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Импортировать ÑущеÑтвующий проект"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ проект в \"%s\"."
@@ -9156,8 +9307,8 @@ msgstr "Удалить проект из ÑпиÑка? (Содержимое пÐ
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "Удалить проект из ÑпиÑка? (Содержимое папки не будет изменено)"
#: editor/project_manager.cpp
@@ -9170,21 +9321,21 @@ msgstr ""
"ПользовательÑкий Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð±ÑƒÐ´ÐµÑ‚ обновлен при Ñледующем запуÑке редактора."
#: 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. "
-"Подтверждаете?"
+"Ð’Ñ‹ дейÑтвительно хотите поиÑкать ÑущеÑтвующие проекты Godot в %s папках?\n"
+"Это может занÑÑ‚ÑŒ много времени."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "Менеджер проектов"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "СпиÑок проектов"
+#, fuzzy
+msgid "Projects"
+msgstr "Проект"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9208,10 +9359,6 @@ msgid "Templates"
msgstr "Шаблоны"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Выход"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "ПерезапуÑтить ÑейчаÑ"
@@ -9253,9 +9400,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"
@@ -9474,9 +9620,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"
@@ -9535,7 +9680,6 @@ msgid "Locales Filter"
msgstr "Фильтры локализации"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
msgstr "Показать вÑе Ñзыки"
@@ -9556,6 +9700,10 @@ msgstr "Языки:"
msgid "AutoLoad"
msgstr "Ðвтозагрузка"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Плагины"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Ðоль"
@@ -9608,16 +9756,6 @@ msgstr "Выбрать виртуальный метод"
msgid "Select Method"
msgstr "Выбрать метод"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Ðевозможно запуÑтить PVRTC инÑтрумент:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"Ðе возможно загрузить обратно конвертированное изображение иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ PVRTC "
-"инÑтрумент:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Пакетное переименование"
@@ -9897,9 +10035,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!"
@@ -9918,6 +10055,11 @@ msgid "Remove Node(s)"
msgstr "Удалить узел(узлы)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Изменить Ð¸Ð¼Ñ Ð²Ñ…Ð¾Ð´Ð°"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9942,7 +10084,6 @@ msgid "Clear Inheritance"
msgstr "ОчиÑтить наÑледование"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Open Documentation"
msgstr "Открыть документацию"
@@ -9951,9 +10092,8 @@ msgid "Add Child Node"
msgstr "Добавить дочерний узел"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Expand/Collapse All"
-msgstr "Свернуть вÑе"
+msgstr "Развернуть/Ñвернуть вÑе"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -9964,6 +10104,11 @@ msgid "Extend Script"
msgstr "РаÑширить Ñкрипт"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Переподчинить узел"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Создать корневой узел Ñцены"
@@ -10040,24 +10185,27 @@ msgid "Node configuration warning:"
msgstr "Конфигурации узла, предупреждение:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Узел Ñодержит ÑвÑзи и группы\n"
"Ðажмите, чтобы показать панель Ñигналов."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Узел Ñодержит ÑвÑзи.\n"
"Ðажмите, чтобы показать панель Ñигналов."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Узел принадлежит к группе.\n"
@@ -10164,6 +10312,11 @@ msgid "Error loading script from %s"
msgstr "Ошибка при загрузке Ñкрипта из %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "ПерезапиÑать"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Ð/Д"
@@ -10197,7 +10350,8 @@ msgid "Script is valid."
msgstr "Скрипт корректен"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "ДопуÑкаютÑÑ: a-z, A-Z, 0-9 и _"
#: editor/script_create_dialog.cpp
@@ -10361,6 +10515,10 @@ msgid "Change Shortcut"
msgstr "Изменить ПривÑзанную Кнопку"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "ÐаÑтройки редактора"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "ПривÑзанные кнопки"
@@ -10780,10 +10938,30 @@ msgid "Set Variable Type"
msgstr "УÑтановить тип переменной"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Ðе должно конфликтовать Ñ ÑущеÑтвующим вÑтроенным именем типа."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Создать новый прÑмоугольник."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Переменные:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Создать новый прÑмоугольник."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Создать новый полигон."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Ð˜Ð¼Ñ Ð½Ðµ ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым идентификатором:"
@@ -10973,10 +11151,6 @@ msgid "Cut Nodes"
msgstr "Вырезать узлы"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Ð’Ñтавить узлы"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Редактировать Ñлемент"
@@ -11733,7 +11907,6 @@ msgid "Nothing connected to input '%s' of node '%s'."
msgstr "Ðичего не подключено к входу \"%s\" узла \"%s\"."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
msgstr "Ðе задан корневой AnimationNode Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„Ð°."
@@ -11760,12 +11933,11 @@ msgstr "Выбрать цвет Ñ Ñкрана."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Raw"
-msgstr "РыÑкание"
+msgstr "Raw"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -11856,35 +12028,22 @@ msgstr ""
"Ñделайте её целью рендеринга и назначьте её внутреннюю текÑтуру какому-либо "
"узлу Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Ошибка инициализации FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "ÐеизвеÑтный формат шрифта."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Ошибка загрузки шрифта."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "ÐедопуÑтимый размер шрифта."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Вход"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "ÐедейÑтвительный иÑточник шейдера."
+msgstr "Ðеверный иÑточник Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "ÐедейÑтвительный иÑточник шейдера."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого типа."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "Ðазначение функции."
@@ -11901,6 +12060,130 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð
msgid "Constants cannot be modified."
msgstr "КонÑтанты не могут быть изменены."
+#~ msgid "No Matches"
+#~ msgstr "Ðет Ñовпадений"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Ðевозможно открыть file_type_cache.cch Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Ðе будет Ñохранён кÑш "
+#~ "типов файлов!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Ðе удаетÑÑ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸ к '%s', так как он не был найден в файловой ÑиÑтеме!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Ошибка при загрузке изображениÑ:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Ðикаких пикÑелей Ñ Ð¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ð¾Ñтью > 128 в изображении..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Родитель не имеет твёрдых граней Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Ðе удалоÑÑŒ отобразить облаÑÑ‚ÑŒ."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Грани не Ñодержат зоны!"
+
+#~ msgid "No faces!"
+#~ msgstr "Ðет граней!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Ошибка: Ðе удалоÑÑŒ загрузить файл."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Ðе удалоÑÑŒ загрузить файл."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "ДоплеровÑкий режим"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Режим Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Режим Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Режим поворота (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Режим маÑÑˆÑ‚Ð°Ð±Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Локальные координаты"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Режим привÑзки (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "ИнÑтрумент выбора"
+
+#~ msgid "Tool Move"
+#~ msgstr "ИнÑтрумент перемещениÑ"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "ИнÑтрумент поворот"
+
+#~ msgid "Tool Scale"
+#~ msgstr "ИнÑтрумент маÑштаб"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "Удалить проект из ÑпиÑка? (Содержимое папки не будет изменено)"
+
+#~ msgid "Project List"
+#~ msgstr "СпиÑок проектов"
+
+#~ msgid "Exit"
+#~ msgstr "Выход"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Ðевозможно запуÑтить PVRTC инÑтрумент:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "Ðе возможно загрузить обратно конвертированное изображение иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ "
+#~ "PVRTC инÑтрумент:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Ошибка инициализации FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "ÐеизвеÑтный формат шрифта."
+
+#~ msgid "Error loading font."
+#~ msgstr "Ошибка загрузки шрифта."
+
+#~ msgid "Invalid font size."
+#~ msgstr "ÐедопуÑтимый размер шрифта."
+
+#~ msgid "Previous Folder"
+#~ msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°"
+
+#~ msgid "Next Folder"
+#~ msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "ÐвтоматичеÑки открывать Ñкриншоты"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Открыть Ñледующий редактор"
+
+#~ msgid "Reverse"
+#~ msgstr "Обратно"
+
+#~ msgid "Mirror X"
+#~ msgstr "Зеркально по X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Зеркально по Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ..."
@@ -12478,9 +12761,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Erase selection"
#~ msgstr "ОчиÑтить выделенное"
-#~ msgid "Could not find tile:"
-#~ msgstr "Ðевозможно найти тайл:"
-
#~ msgid "Item name or ID:"
#~ msgstr "ID или Ð¸Ð¼Ñ Ñлемента:"
@@ -12744,9 +13024,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Info"
#~ msgstr "ИнформациÑ"
-#~ msgid "Re-Import..."
-#~ msgstr "Переимпортировать..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Ðет битовой маÑки Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°!"
@@ -13141,9 +13418,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Stereo"
#~ msgstr "Стерео"
-#~ msgid "Window"
-#~ msgstr "Окно"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "МаÑштабирование до %s%%."
@@ -13381,9 +13655,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Add Image Group"
#~ msgstr "Добавлено изображение группы"
-#~ msgid "Delete Image Group"
-#~ msgstr "Удалено изображение группы"
-
#~ msgid "Project Export Settings"
#~ msgstr "Параметры ÑкÑпорта проекта"
@@ -13468,9 +13739,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Export Project PCK"
#~ msgstr "ЭкÑпортировать PCK проекта"
-#~ msgid "Export..."
-#~ msgstr "ЭкÑпортировать..."
-
#~ msgid "Project Export"
#~ msgstr "ЭкÑпортирование проекта"
@@ -13576,9 +13844,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Deploy File Server Clients"
#~ msgstr "Развернуть файловый Ñервер Ð´Ð»Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð¾Ð²"
-#~ msgid "Group Editor"
-#~ msgstr "Редактор групп"
-
#~ msgid "Overwrite Existing Scene"
#~ msgstr "ПерезапиÑать ÑущеÑтвующую Ñцену"
diff --git a/editor/translations/si.po b/editor/translations/si.po
index 3f62079f19..2492f11666 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -58,7 +58,6 @@ msgid "On call to '%s':"
msgstr "'%s' ඇමතීම:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "නිදහස්"
@@ -128,6 +127,31 @@ msgstr "Anim කà·à¶¯à·€à·“ම් වෙනස් කරන්න"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim කීෆ්â€à¶»à·šà¶¸à·Š කà·à¶½à¶º වෙනස් කරන්න"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim සංක්රමණය වෙනස් කරන්න"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim පරිවර්තනය වෙනස් කරන්න"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim කීෆ්â€à¶»à·šà¶¸à·Š අගය වෙනස් කරන්න"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim කà·à¶¯à·€à·“ම් වෙනස් කරන්න"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "සජීවීකරණ පුනරà·à·€à¶»à·Šà¶®à¶±à¶º"
@@ -626,15 +650,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -859,8 +883,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -954,7 +977,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -990,7 +1013,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1079,14 +1102,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1103,7 +1126,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1120,7 +1143,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1587,12 +1609,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1653,7 +1674,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1704,7 +1725,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1729,23 +1750,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1978,6 +2003,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2274,6 +2303,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2367,6 +2404,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2420,6 +2461,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2447,20 +2492,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2493,24 +2534,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2590,12 +2639,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2611,14 +2660,6 @@ 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 ""
@@ -2639,14 +2680,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2654,12 +2695,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2932,6 +2974,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3093,7 +3139,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3110,6 +3156,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3171,12 +3221,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3190,13 +3238,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3281,19 +3333,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3326,11 +3370,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3389,6 +3433,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3452,6 +3500,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3512,6 +3565,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3519,12 +3580,21 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "යතුරු මක෠දමන්න"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3537,11 +3607,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3748,7 +3818,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4496,10 +4566,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4512,14 +4578,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4560,6 +4654,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4588,13 +4686,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4602,7 +4702,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4615,7 +4715,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4627,6 +4727,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4677,31 +4781,33 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "මෙම ලුහුබදින්න෠ඉවත් කරන්න."
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4781,6 +4887,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Anim පරිවර්තනය වෙනස් කරන්න"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4810,6 +4921,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4830,14 +4942,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4861,6 +4976,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4877,11 +4993,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4894,6 +5005,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5102,16 +5218,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5426,14 +5532,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5517,19 +5615,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5856,7 +5958,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5962,11 +6063,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5990,7 +6087,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6071,6 +6168,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6108,11 +6209,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6200,6 +6301,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6267,6 +6372,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6301,92 +6407,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6564,7 +6674,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6620,7 +6734,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6674,7 +6788,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6685,27 +6799,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6749,26 +6843,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6823,7 +6897,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7120,10 +7194,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7208,11 +7278,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7317,14 +7387,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7338,8 +7400,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7624,6 +7686,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7702,6 +7768,11 @@ msgid "Duplicate Nodes"
msgstr "යතුරු පිටපත් කරන්න"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "යතුරු මක෠දමන්න"
@@ -7723,6 +7794,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7797,6 +7872,22 @@ msgid "Color uniform."
msgstr "Anim පරිවර්තනය වෙනස් කරන්න"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7804,10 +7895,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7896,7 +8021,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7904,7 +8029,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7916,7 +8041,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7933,7 +8058,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8002,11 +8127,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8022,7 +8147,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8033,7 +8158,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8042,7 +8167,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8050,11 +8175,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8095,11 +8220,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8108,7 +8237,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8126,15 +8255,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8185,7 +8314,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8200,6 +8329,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8213,19 +8346,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8234,7 +8367,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8243,14 +8376,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8295,47 +8428,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8502,6 +8642,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8648,6 +8792,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8717,8 +8869,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8738,7 +8890,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8762,10 +8914,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9099,6 +9247,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9151,14 +9303,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9445,6 +9589,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9487,6 +9635,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9558,19 +9710,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9661,6 +9813,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9689,7 +9845,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9849,6 +10005,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10259,10 +10419,28 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "à·à·Šâ€à¶»à·’ත:"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10447,10 +10625,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11180,22 +11354,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11208,6 +11366,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index aeef25389e..98d594e40d 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -64,7 +64,6 @@ msgid "On call to '%s':"
msgstr "Pri volaní '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Voľné"
@@ -134,6 +133,31 @@ msgid "Anim Change Call"
msgstr "Animácia Zmeniť Hovor"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animácia Zmeniť Keyframe Čas"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animácia zmeniť prechod"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animácia zmeniť prechod"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animácia Zmeniť Keyframe Hodnotu"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animácia Zmeniť Hovor"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Zmeniť Dĺžku Animácie"
@@ -634,16 +658,17 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr ""
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Zhody:"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -874,8 +899,7 @@ msgstr "Obľúbené:"
msgid "Recent:"
msgstr "Nedávne:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -978,7 +1002,7 @@ msgstr ""
"Súbory ktoré budú odstránené vyžadujú ÄalÅ¡ie zdroje, aby mohli pracovaÅ¥.\n"
"Odstrániť aj napriek tomu? (nedá sa vrátiť späť)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nemôžete odstrániť:"
@@ -1015,7 +1039,7 @@ msgstr "Natrvalo odstrániť %d položky? (Nedá sa vrátiť späť!)"
msgid "Show Dependencies"
msgstr "Závislostí"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1104,14 +1128,15 @@ msgid "License"
msgstr "Licencia"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Thirdparty Licencie"
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1129,7 +1154,8 @@ msgid "Licenses"
msgstr "Licencie"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Chyba pri otváraní súboru balíka, nie je vo formáte zip."
#: editor/editor_asset_installer.cpp
@@ -1146,7 +1172,6 @@ msgid "Success!"
msgstr "Úspech!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Inštalovať"
@@ -1623,12 +1648,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1697,7 +1721,7 @@ msgstr "Otvoriť súbor"
msgid "New Folder..."
msgstr "Vytvoriť adresár"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1748,7 +1772,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1774,12 +1798,12 @@ msgstr ""
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr "Vytvoriť adresár"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr "Vytvoriť adresár"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
@@ -1787,12 +1811,16 @@ msgstr "Vytvoriť adresár"
msgid "Go to parent folder."
msgstr "Vytvoriť adresár"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2041,6 +2069,10 @@ msgstr ""
msgid "Clear Output"
msgstr "Popis:"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2340,6 +2372,15 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Otvoriť súbor(y)"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2433,6 +2474,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2487,6 +2532,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopírovať"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2514,6 +2564,10 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr ""
@@ -2524,14 +2578,6 @@ msgid "Save All Scenes"
msgstr "Uložiť súbor"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr ""
@@ -2561,24 +2607,33 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Upraviť..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2658,13 +2713,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Prechody"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2679,14 +2735,6 @@ 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 ""
@@ -2707,14 +2755,15 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr "Všetky vybrané"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2722,12 +2771,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3006,6 +3056,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Súbor:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3170,7 +3225,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3187,6 +3242,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3248,12 +3307,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3267,13 +3324,18 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nemôžete odstrániť:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3361,19 +3423,11 @@ msgstr "Všetky vybrané"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3406,11 +3460,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3473,6 +3527,11 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Popis:"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3540,6 +3599,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Vytvoriť adresár"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3603,6 +3667,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3611,12 +3683,22 @@ msgstr ""
msgid "Invalid group name."
msgstr "Nesprávna veľkosť písma."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Všetky vybrané"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Všetky vybrané"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3630,12 +3712,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "Otvorit prieÄinok"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3844,7 +3927,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4614,10 +4697,6 @@ msgid "View Files"
msgstr "Súbor:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4630,14 +4709,44 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nemôžete odstrániť:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ÄŒas:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4678,6 +4787,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Inštalovať"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4706,13 +4820,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4720,7 +4836,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4733,7 +4849,7 @@ msgid "Site:"
msgstr "Stránka:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4745,6 +4861,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4795,35 +4915,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "Popis:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "Popis:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Všetky vybrané"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "Všetky vybrané"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "Popis:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Všetky vybrané"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Popis:"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -4907,6 +5031,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Všetky vybrané"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4936,6 +5065,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4956,14 +5086,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4987,6 +5120,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5003,11 +5137,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5020,6 +5149,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5232,16 +5366,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5563,14 +5687,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5654,19 +5770,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6006,7 +6126,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6112,12 +6231,9 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr ""
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Popis:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6141,7 +6257,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Vytvoriť adresár"
#: editor/plugins/script_editor_plugin.cpp
@@ -6228,6 +6344,11 @@ msgid "Open..."
msgstr "Otvoriť"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Popis:"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6265,11 +6386,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6359,6 +6480,11 @@ msgstr ""
msgid "Search Results"
msgstr "Vložiť"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Popis:"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6429,6 +6555,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6464,25 +6591,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "PrejsÅ¥ na Äalší krok"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Prejsť na predchádzajúci krok"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Všetky vybrané"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6503,6 +6611,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Zmeniť veľkosť výberu"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6519,31 +6632,35 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Go to Next Bookmark"
msgstr "PrejsÅ¥ na Äalší krok"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr "Prejsť na predchádzajúci krok"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr ""
+#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr "Všetky vybrané"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6555,9 +6672,24 @@ msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "PrejsÅ¥ na Äalší krok"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Prejsť na predchádzajúci krok"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6734,7 +6866,12 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr "Všetky vybrané"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr "Všetky vybrané"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6791,8 +6928,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Filter:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6845,7 +6983,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6856,27 +6994,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6921,28 +7039,6 @@ msgid "Focus Selection"
msgstr "Všetky vybrané"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Align Selection With View"
-msgstr "Všetky vybrané"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "Všetky vybrané"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6997,7 +7093,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7301,10 +7397,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7395,11 +7487,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7508,14 +7600,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7530,8 +7614,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7841,6 +7925,10 @@ msgid "TileSet"
msgstr "Súbor:"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Signály:"
@@ -7925,6 +8013,12 @@ msgid "Duplicate Nodes"
msgstr "Duplikovať výber"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Paste Nodes"
+msgstr "Vložiť"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Všetky vybrané"
@@ -7947,6 +8041,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Vytvoriť adresár"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Vytvoriť adresár"
@@ -8022,6 +8121,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8029,10 +8144,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8122,7 +8271,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8130,7 +8279,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8142,7 +8291,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8159,7 +8308,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8228,11 +8377,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8248,7 +8397,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8259,7 +8408,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8268,7 +8417,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8276,11 +8425,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8320,11 +8469,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8334,7 +8487,7 @@ msgstr "Vytvoriť adresár"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8352,15 +8505,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8412,7 +8565,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8427,6 +8580,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8440,19 +8597,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8461,7 +8618,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8470,14 +8627,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8522,47 +8679,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8731,6 +8895,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8880,6 +9048,15 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Všetky vybrané"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8949,8 +9126,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8970,8 +9147,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Zakladatelia Projektu"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8996,10 +9174,6 @@ msgid "Templates"
msgstr "Všetky vybrané"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9339,6 +9513,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9392,14 +9570,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9689,6 +9859,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9733,6 +9907,11 @@ msgid "Extend Script"
msgstr "Popis:"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Vytvoriť adresár"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9809,19 +9988,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9915,6 +10094,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9945,7 +10128,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10112,6 +10295,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10529,10 +10716,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Vytvoriť adresár"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Vytvoriť adresár"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Vytvoriť adresár"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10725,11 +10931,6 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "Vložiť"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "Súbor:"
@@ -11482,22 +11683,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Nesprávna veľkosť písma."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11512,6 +11697,11 @@ msgstr "Nesprávna veľkosť písma."
msgid "Invalid source for shader."
msgstr "Nesprávna veľkosť písma."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Nesprávna veľkosť písma."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11529,6 +11719,21 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "Všetky vybrané"
+
+#~ msgid "Invalid font size."
+#~ msgstr "Nesprávna veľkosť písma."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Vytvoriť adresár"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Vytvoriť adresár"
+
+#, fuzzy
#~ msgid "View log"
#~ msgstr "Súbor:"
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 673ed15421..e369352868 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-05-16 18:49+0000\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
"Last-Translator: Andrej Poženel <andrej.pozenel@outlook.com>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/"
"godot/sl/>\n"
@@ -23,7 +23,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3;\n"
-"X-Generator: Weblate 3.7-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -46,9 +46,8 @@ msgid "self can't be used because instance is null (not passed)"
msgstr "self ne more biti uporabljen, ker instanca ni null (ni podano)"
#: core/math/expression.cpp
-#, fuzzy
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "Neveljaven indeks lastnosti imena '%s' v vozliÅ¡Äu %s."
+msgstr "Neveljaven operand za operator %s, %s ter %s."
#: core/math/expression.cpp
#, fuzzy
@@ -68,7 +67,6 @@ msgid "On call to '%s':"
msgstr "Na klic '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Prosto"
@@ -141,6 +139,31 @@ msgstr "Animacija Spremeni klic"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animacija Spremeni Äas kljuÄne slike"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animacija Spremeni prehod"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animacija Spremeni transformacijo"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animacija Spremeni vrednost kljuÄne slike"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animacija Spremeni klic"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Spremeni Ime Animacije:"
@@ -659,17 +682,18 @@ msgid "Line Number:"
msgstr "Å tevilka Vrste:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Zamenjana %d ponovitev/e."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Ni Zadetkov"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Zamenjana %d ponovitev/e."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Ujemanje Velikih ÄŒrk"
@@ -907,8 +931,7 @@ msgstr "Priljubljene:"
msgid "Recent:"
msgstr "Nedavni:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1011,7 +1034,7 @@ msgstr ""
"Izbrisane datoteke so potrebne za delovanje drugih virov.\n"
"Ali jih vseeno odstranim? (brez vrnitve)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Ni mogoÄe odstraniti:"
@@ -1049,7 +1072,7 @@ msgstr "Trajno izbrišem %d predmet(e)? (Brez vrnitve!)"
msgid "Show Dependencies"
msgstr "Odvisnosti"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Raziskovalec Osamljenih Virov"
@@ -1138,14 +1161,16 @@ msgid "License"
msgstr "Licenca"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Licenca Tretjih Oseb"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine se nanaÅ¡a na Å¡tevilne brezplaÄne in odprokodne knjižnice tretih "
@@ -1166,7 +1191,8 @@ msgid "Licenses"
msgstr "Licence"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Napaka pri odpiranju datoteke paketa, ker ni v formatu zip."
#: editor/editor_asset_installer.cpp
@@ -1184,7 +1210,6 @@ msgid "Success!"
msgstr "Uspelo je!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Namesti"
@@ -1677,12 +1702,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Uvozi"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Izvozi"
@@ -1753,7 +1777,7 @@ msgstr "Pokaži V Upravitelju Datotek"
msgid "New Folder..."
msgstr "Nova Mapa..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Osveži"
@@ -1804,7 +1828,7 @@ msgstr "Pojdi Naprej"
msgid "Go Up"
msgstr "Pojdi Navzgor"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Preklopi na Skrite Datoteke"
@@ -1830,27 +1854,32 @@ msgstr "Premakni Priljubljeno Navzdol"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Prejšnji zavihek"
+msgid "Go to previous folder."
+msgstr "Pojdi v nadrejeno mapo"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Ustvarite Mapo"
+msgid "Go to next folder."
+msgstr "Pojdi v nadrejeno mapo"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Pojdi v nadrejeno mapo"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "IÅ¡Äi Razrede"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Mape ni mogoÄe ustvariti."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Preklopi na Skrite Datoteke"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2110,6 +2139,10 @@ msgstr "PoÄisti"
msgid "Clear Output"
msgstr "PoÄisti Izhod"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Izvoz projekta ni uspelo s kodno napako %d."
@@ -2427,6 +2460,15 @@ msgid "Pick a Main Scene"
msgstr "Izberi Glavno Sceno"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Zapri Prizor"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Zapri Prizor"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Ni mogoÄe omogoÄiti dodatnega vtiÄnika na: '%s'. RazÄlenjevanje "
@@ -2544,6 +2586,11 @@ msgstr "Zaženi Prizor"
msgid "Close Tab"
msgstr "Zapri"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Zapri"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2598,6 +2645,11 @@ msgid "Go to previously opened scene."
msgstr "Pojdi na predhodno odprti prizor."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopiraj Pot"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Naslednji zavihek"
@@ -2625,6 +2677,10 @@ msgstr "Nov Podedovan Prizor..."
msgid "Open Scene..."
msgstr "Odpri Prizor..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Odpri Nedavne"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Shrani Prizor"
@@ -2635,14 +2691,6 @@ msgid "Save All Scenes"
msgstr "Shrani vse Prizore"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Zapri Prizor"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Odpri Nedavne"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Pretvori V..."
@@ -2672,26 +2720,37 @@ msgstr "Povrni Prizor"
msgid "Miscellaneous project or scene-wide tools."
msgstr "RazliÄna projektna ali prizorska orodja."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Nastavitve Projekta"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Orodja"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Izvozi"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Odprem Upravljalnik Projekta?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Orodja"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Raziskovalec Osamljenih Virov"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2787,12 +2846,13 @@ msgstr ""
"ÄŒe se uporablja napravo na daljavo, je to bolj uÄinkovito pri omrežnem "
"datoteÄnem sistemu."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Urejevalnik"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Nastavitve Urejevalnika"
#: editor/editor_node.cpp
@@ -2810,15 +2870,6 @@ 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"
@@ -2843,14 +2894,15 @@ msgstr "Nastavitve Urejevalnika"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Upravljaj Izvozne Predloge"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Upravljaj Izvozne Predloge"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "PomoÄ"
@@ -2858,12 +2910,13 @@ msgstr "PomoÄ"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Iskanje"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Spletna Dokumentacija"
@@ -3145,6 +3198,11 @@ msgstr "ÄŒas"
msgid "Calls"
msgstr "Klici"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "ÄŒlani"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3312,7 +3370,8 @@ msgid "Import From Node:"
msgstr "Uvozi iz Gradnika:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Ponovno Prenesi"
#: editor/export_template_manager.cpp
@@ -3329,6 +3388,10 @@ msgid "Download"
msgstr "Prenesi"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(ManjkajoÄe)"
@@ -3393,12 +3456,10 @@ msgid "No response."
msgstr "Ni odgovora."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Zahteva Ni Uspela."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Preusmeritev Zanke."
@@ -3412,13 +3473,19 @@ msgid "Download Complete."
msgstr "Prenos je DokonÄan."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Ni mogoÄe odstraniti:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Napaka pri zahtevi URL-ja: "
#: editor/export_template_manager.cpp
@@ -3506,24 +3573,12 @@ msgstr "Prenesi Predloge"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Izberi vire s seznama: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Za pisanje ni mogoÄe odpreti file_type_cache.cch, ne da bi shranili "
-"predpomnilnik tipa datoteke!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Priljubljene:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Ne morem se postaviti na mesto '%s', ker ni bilo najdeno v datoteÄnem "
-"sistemu!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Stanje: Uvoz datoteke ni uspel. Popravi datoteko in ponovno roÄno uvozi."
@@ -3558,14 +3613,14 @@ msgid "Provided name contains invalid characters."
msgstr "Vnešeno ime vsebuje neveljavne znake"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Ime vsebuje neveljavne znake."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Datoteka ali mapa s tem imenom že obstaja."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Ime vsebuje neveljavne znake."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Preimenovanje Datoteke:"
@@ -3625,6 +3680,11 @@ msgstr "Podvoji..."
msgid "Move To..."
msgstr "Premakni V..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Nov Prizor"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3699,6 +3759,11 @@ msgstr "Datoteka ali mapa s tem imenom že obstaja."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Shrani Prizor"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3768,6 +3833,14 @@ msgid "Search complete"
msgstr "IÅ¡Äi Besedilo"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Dodaj v Skupino"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Odstrani iz Skupine"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "NAPAKA: Animacija s tem imenom že obstaja!"
@@ -3777,13 +3850,23 @@ msgstr "NAPAKA: Animacija s tem imenom že obstaja!"
msgid "Invalid group name."
msgstr "Neveljavno ime."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Skupine"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Izbriši Postavitev"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Skupine"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Dodaj v Skupino"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3797,12 +3880,13 @@ msgid "Nodes in Group"
msgstr "Dodaj v Skupino"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Dodaj v Skupino"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Odstrani iz Skupine"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Odpri Urejevalnik Skript"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4013,7 +4097,8 @@ msgid "MultiNode Set"
msgstr "Niz VeÄkratnih Gradnikov"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Za urejanje Signalov in Skupin izberi Gradnik."
#: editor/plugin_config_dialog.cpp
@@ -4816,10 +4901,6 @@ msgid "View Files"
msgstr "Ogled datotek"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Ne morem razrešiti imena gostitelja:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Napaka pri povezavi, poskusi znova."
@@ -4832,14 +4913,47 @@ msgid "No response from host:"
msgstr "Gostitelj se ne odziva:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Ne morem razrešiti imena gostitelja:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Zahteva ni uspela, povratna koda:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Zahteva Ni Uspela."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Ni mogoÄe odstraniti:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Zahteva ni uspela, preveÄ preusmeritev"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Preusmeritev Zanke."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Zahteva ni uspela, povratna koda:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ÄŒas"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Slab prenos hash kode, predvidevamo, da je bila datoteka spremenjena."
@@ -4882,6 +4996,11 @@ msgid "Idle"
msgstr "Nedejaven"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Namesti"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Ponovi"
@@ -4913,13 +5032,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Vse"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Uvozi"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "VtiÄniki"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4927,8 +5050,9 @@ msgid "Sort:"
msgstr "Razvrsti:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Obrni"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Zahtevam..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4940,7 +5064,8 @@ msgid "Site:"
msgstr "Stran:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Podpora..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4952,6 +5077,11 @@ msgid "Testing"
msgstr "Preskušanje"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Naloži"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Dodatki v ZIP Datoteki"
@@ -5008,31 +5138,38 @@ msgid "Rotation Step:"
msgstr "Rotacijski Korak:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Premakni navpiÄni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Ustvari nov navpiÄni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Odstranite navpiÄni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Premakni vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Ustvari nov vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Odstrani vodoravni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Ustvari nov vodoravni in navpiÄni vodnik"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5123,6 +5260,11 @@ msgstr "Prilepi Pozicijo"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Zaženi Prizor po Meri"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Zaženi Prizor po Meri"
@@ -5153,6 +5295,7 @@ msgid "Zoom Reset"
msgstr "Oddalji"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Izberi NaÄin"
@@ -5175,14 +5318,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+RMB: Izbira globine"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "NaÄin Premika"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "NaÄin Vrtenja"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "NaÄin Obsega (R)"
@@ -5210,6 +5356,7 @@ msgid "Toggle snapping."
msgstr "Preklopi pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Uporabi Pripenjanje"
@@ -5228,11 +5375,6 @@ msgid "Use Rotation Snap"
msgstr "Uporabi Rotacijsko Pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Nastavi Pripenjanje..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Pripni Relativno"
@@ -5246,6 +5388,11 @@ msgid "Smart Snapping"
msgstr "Pametno pripenjanje"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Nastavi Pripenjanje..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Pripni na Predhodnika"
@@ -5466,16 +5613,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5794,14 +5931,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5885,19 +6014,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6237,7 +6370,6 @@ msgid "Grid Settings"
msgstr "Nastavitve Urejevalnika"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6351,12 +6483,7 @@ msgstr "Napaka pri shranjevanju PloÅ¡ÄnegaNiza!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Mape ni mogoÄe ustvariti."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Mape ni mogoÄe ustvariti."
#: editor/plugins/script_editor_plugin.cpp
@@ -6386,7 +6513,7 @@ msgstr "Napaka pri premikanju:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Nova Mapa..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6472,6 +6599,11 @@ msgid "Open..."
msgstr "Odpri"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Zaženi Skripto"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6511,13 +6643,13 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Zapri Vse"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Zaženi"
@@ -6606,6 +6738,11 @@ msgstr "RazhroÅ¡Äevalnik"
msgid "Search Results"
msgstr "IÅ¡Äi PomoÄ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "PoÄisti Nedavne Prizore"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6678,6 +6815,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6713,26 +6851,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Preklopi Svobodni Pregled"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Pojdi na naslednji korak"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Preklopi na Zaustavitev"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Odstrani Vse Stvari"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Pregibna/Nepregibna ÄŒrta"
@@ -6753,6 +6871,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "PoveÄaj izbiro"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6769,32 +6892,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Preklopi na Zaustavitev"
+msgid "Find Previous"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtriraj datoteke..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Pojdi na naslednji korak"
+msgid "Toggle Bookmark"
+msgstr "Preklopi Svobodni Pregled"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Preklopi na Zaustavitev"
+msgid "Go to Next Bookmark"
+msgstr "Pojdi na naslednji korak"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Preklopi na Zaustavitev"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtriraj datoteke..."
+msgid "Remove All Bookmarks"
+msgstr "Odstrani Vse Stvari"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6807,9 +6935,24 @@ msgid "Go to Line..."
msgstr "Pojdi na Vrstico"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Preklopi na Zaustavitev"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Pojdi na naslednji korak"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Preklopi na Zaustavitev"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6989,7 +7132,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7045,8 +7192,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Spremeni Dolžino Animacije"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7101,8 +7249,8 @@ msgid "Snap Nodes To Floor"
msgstr "Pripni na mrežo"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Izberite NaÄin (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7115,30 +7263,11 @@ msgstr ""
"Alt+RMB: Izbira globine"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "NaÄin Premika (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "NaÄin Vrtenja (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "NaÄin Obsega (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Lokalno prostorski naÄin (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "NaÄin Zaskoka (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7179,26 +7308,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Izbira Orodja"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Preklopi Svobodni Pregled"
@@ -7254,8 +7363,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Nastavitve ZaskoÄenja"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7563,10 +7673,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7655,11 +7761,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7769,14 +7875,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7791,8 +7889,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8112,6 +8210,10 @@ msgid "TileSet"
msgstr "Izvozi PloÅ¡Äno Zbirko"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Dodaj Vnos"
@@ -8201,6 +8303,11 @@ msgid "Duplicate Nodes"
msgstr "Animacija Podvoji kljuÄe"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Izberi Gradnik"
@@ -8223,6 +8330,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Ustvarite Mapo"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Ustvarite Mapo"
@@ -8301,6 +8413,22 @@ msgid "Color uniform."
msgstr "Preoblikovanje"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8308,10 +8436,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8402,7 +8564,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8410,7 +8572,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8422,7 +8584,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8439,7 +8601,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8508,11 +8670,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8528,7 +8690,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8539,7 +8701,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8548,7 +8710,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8556,11 +8718,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8601,11 +8763,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8615,7 +8781,7 @@ msgstr "Preoblikovanje Dialoga..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8633,15 +8799,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8693,7 +8859,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8708,6 +8874,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8721,19 +8891,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8742,7 +8912,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8751,14 +8921,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8803,47 +8973,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9018,6 +9195,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Upravljaj Izvozne Predloge"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9167,6 +9348,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Uvoz ObstojeÄega Projekta"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Ni mogoÄe odpreti '%s'."
@@ -9240,8 +9430,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9261,8 +9451,9 @@ msgid "Project Manager"
msgstr "Upravljalnik Projekta"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Seznam Projektov"
+#, fuzzy
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9286,10 +9477,6 @@ msgid "Templates"
msgstr "Predloge"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Izhod"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9630,6 +9817,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "VtiÄniki"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9682,14 +9873,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9989,6 +10172,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10035,6 +10222,11 @@ msgstr "Zaženi Skripto"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Ustvari Nov %s"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Shrani Prizor"
@@ -10111,19 +10303,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10221,6 +10413,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10254,7 +10450,7 @@ msgid "Script is valid."
msgstr "Drevo animacije je veljavno."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10418,6 +10614,10 @@ msgid "Change Shortcut"
msgstr "Spremeni SidriÅ¡Äa"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Nastavitve Urejevalnika"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10844,10 +11044,31 @@ msgid "Set Variable Type"
msgstr "Nastavite Tip Spremenljivke"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr ""
+"Neveljavno ime. Ne sme se prekrivati z obstojeÄim vgrajenim imenom tipa."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Ustvari Nov %s"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Spremenljivke:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Ustvari Nov %s"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Ustvarite Poligon"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Ime ni pravilen identifikator:"
@@ -11036,10 +11257,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "ÄŒlani"
@@ -11812,22 +12029,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Napaka pri inicializaciji FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Neznani format pisave."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Napaka nalaganja pisave."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Neveljavna velikost pisave."
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11842,6 +12043,11 @@ msgstr "Neveljaven vir za shader."
msgid "Invalid source for shader."
msgstr "Neveljaven vir za shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Neveljaven vir za shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11858,6 +12064,72 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Za pisanje ni mogoÄe odpreti file_type_cache.cch, ne da bi shranili "
+#~ "predpomnilnik tipa datoteke!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Ne morem se postaviti na mesto '%s', ker ni bilo najdeno v datoteÄnem "
+#~ "sistemu!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Mape ni mogoÄe ustvariti."
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Izberite NaÄin (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "NaÄin Premika (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "NaÄin Vrtenja (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "NaÄin Obsega (R)"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "NaÄin Zaskoka (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Izbira Orodja"
+
+#~ msgid "Project List"
+#~ msgstr "Seznam Projektov"
+
+#~ msgid "Exit"
+#~ msgstr "Izhod"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Napaka pri inicializaciji FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Neznani format pisave."
+
+#~ msgid "Error loading font."
+#~ msgstr "Napaka nalaganja pisave."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Neveljavna velikost pisave."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Prejšnji zavihek"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Ustvarite Mapo"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Odpri naslednji Urejevalnik"
+
+#~ msgid "Reverse"
+#~ msgstr "Obrni"
+
#, fuzzy
#~ msgid "View log"
#~ msgstr "Ogled datotek"
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index f798e780cb..61e380e91c 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -60,7 +60,6 @@ msgid "On call to '%s':"
msgstr "Në thërritje të '%s':"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Liro"
@@ -130,6 +129,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Ndrysho Gjatësin e Animacionit"
@@ -617,16 +636,17 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr ""
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Përputhjet:"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -857,8 +877,7 @@ msgstr "Të Preferuarat:"
msgid "Recent:"
msgstr "Të fundit:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -962,7 +981,7 @@ msgstr ""
"ato të funksionojnë.\n"
"Hiqi gjithsesi? (pa kthim pas)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Nuk mund të heqësh:"
@@ -999,7 +1018,7 @@ msgstr "Përfundimisht fshi %d artikuj? (pa kthim pas)"
msgid "Show Dependencies"
msgstr "Varësitë"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Eksploruesi I Resurseve Pa Zotërues"
@@ -1088,14 +1107,16 @@ msgid "License"
msgstr "Liçensa"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Liçensa të palëve të treta"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine mbështetet në nje numër librarish falas dhe 'open source' "
@@ -1116,7 +1137,8 @@ msgid "Licenses"
msgstr "Liçensat"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Gabim në hapjen e skedarit paketë, nuk është në formatin zip."
#: editor/editor_asset_installer.cpp
@@ -1133,7 +1155,6 @@ msgid "Success!"
msgstr "Sukses!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Instalo"
@@ -1631,12 +1652,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importo"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Eksporto"
@@ -1703,7 +1723,7 @@ msgstr "Shfaq në Menaxherin e Skedarëve"
msgid "New Folder..."
msgstr "Folder i Ri..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Rifresko"
@@ -1754,7 +1774,7 @@ msgstr "Shko Përpara"
msgid "Go Up"
msgstr "Shko Lartë"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Ndrysho Skedarët e Fshehur"
@@ -1779,24 +1799,31 @@ msgid "Move Favorite Down"
msgstr "Lëviz të Preferuarën Poshtë"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Folderi i Mëparshëm"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Shko te folderi prind"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Folderi Tjetër"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Shko te folderi prind"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Kërko skedarët"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Hiqe nga të preferuarat folderin aktual."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Ndrysho Skedarët e Fshehur"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2036,6 +2063,10 @@ msgstr "Pastro"
msgid "Clear Output"
msgstr "Pastro Përfundimin"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Eksportimi i projektit dështoi me kodin e gabimit %d."
@@ -2363,6 +2394,15 @@ msgid "Pick a Main Scene"
msgstr "Zgjidh një Skenë Kryesore"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Mbyll Skenën"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Mbyll Skenën"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"I paaftë të aktivizoj shtojcën në: '%s' analiza gramatikore e 'config' "
@@ -2478,6 +2518,11 @@ msgstr "Luaj Këtë Skenë"
msgid "Close Tab"
msgstr "Mbyll Tabin"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Mbyll Tabin"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2532,6 +2577,11 @@ msgid "Go to previously opened scene."
msgstr "Shko në skenën e hapur më parë."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopjo Rrugën"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Tabi tjetër"
@@ -2559,6 +2609,10 @@ msgstr "Skenë e Re e Trashëguar..."
msgid "Open Scene..."
msgstr "Hap Skenën..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Hap të Fundit"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Ruaj Skenën"
@@ -2568,14 +2622,6 @@ msgid "Save All Scenes"
msgstr "Ruaj të Gjitha Skenat"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Mbyll Skenën"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Hap të Fundit"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konverto në..."
@@ -2605,25 +2651,36 @@ msgstr "Rikthe Skenën"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Vegla të ndryshme për projektin ose skenën."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekti"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Opsionet e Projektit"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Veglat"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Eksporto"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Hap Folderin e të Dhënave të Projektit"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Veglat"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Eksploruesi I Resurseve Pa Zotërues"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2720,12 +2777,13 @@ msgstr ""
"Kur përdoret në një paisje në largësi është më efikas me rrjetin "
"'filesyetem'."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Opsionet e Editorit"
#: editor/editor_node.cpp
@@ -2742,15 +2800,6 @@ 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ë"
@@ -2773,14 +2822,15 @@ msgstr "Hap Folderin e Opsioneve të Editorit"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Menaxho Shabllonet e Eksportit"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Menaxho Shabllonet e Eksportit"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Ndihmë"
@@ -2788,12 +2838,13 @@ msgstr "Ndihmë"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Kërko"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentimi Online"
@@ -3070,6 +3121,11 @@ msgstr "Koha"
msgid "Calls"
msgstr "Thërritjet"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Modifiko:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Mbi"
@@ -3242,7 +3298,8 @@ msgid "Import From Node:"
msgstr "Importo nga Nyja:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Ri-Shkarko"
#: editor/export_template_manager.cpp
@@ -3259,6 +3316,10 @@ msgid "Download"
msgstr "Shkarko"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mungon)"
@@ -3322,12 +3383,10 @@ msgid "No response."
msgstr "Nuk u përgjigj."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Kërkimi Dështoi."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Ridrejto Ciklin."
@@ -3341,15 +3400,22 @@ msgid "Download Complete."
msgstr "Shkarkimi u Plotësua."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Nuk mund të heqësh:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Instalimi i shablloneve dështoi. Arkivat problematike të shablloneve mund të "
"gjenden në '%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Gabim duke kërkuar url: "
#: editor/export_template_manager.cpp
@@ -3436,22 +3502,11 @@ msgstr "Shkarko Shabllonet"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Zgjidh pasqyrën nga lista: (Shift+Kliko: Për ta hapur në shfletues)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Nuk mund të hapi file_type_catche.cch për të shkruajtur, skedari nuk do të "
-"ruhet!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Të Preferuarat"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Nuk mund të navigoj te '%s' sepse nuk është gjetur në sistemin e skedarëve!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Statusi: Importimi i skedarit dështoi. Please rregullo skedarin dhe ri-"
@@ -3487,14 +3542,14 @@ msgid "Provided name contains invalid characters."
msgstr "Emri i dhënë përmban karaktere të pasakta"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Emri permban karaktere të pasakta."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Një skedar ose folder me këtë emër ekziston që më parë."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Emri permban karaktere të pasakta."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Duke riemërtuar skedarin:"
@@ -3554,6 +3609,11 @@ msgstr "Dyfisho..."
msgid "Move To..."
msgstr "Lëviz në..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Skenë e Re"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Shkrim i Ri..."
@@ -3624,6 +3684,11 @@ msgstr ""
msgid "Overwrite"
msgstr "Mbishkruaj"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Ruaj Skenën"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Krijo një Shkrim"
@@ -3684,6 +3749,14 @@ msgid "Search complete"
msgstr "Kërkimi u kompletua"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Shto te Grupi"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Hiq nga Grupi"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Emri i grupit ekziston që më parë."
@@ -3691,12 +3764,23 @@ msgstr "Emri i grupit ekziston që më parë."
msgid "Invalid group name."
msgstr "Emri i grupit i pasakt."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Menaxho Grupet"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Fshi Faqosjen"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupet"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nyjet që nuk janë në Grup"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3709,12 +3793,13 @@ msgid "Nodes in Group"
msgstr "Nyjet në Grup"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Shto te Grupi"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Hiq nga Grupi"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Hap Editorin e Shkrimit"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3925,7 +4010,8 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Zgjidh një nyje për të modifikuar Sinjalet dhe Grupet."
#: editor/plugin_config_dialog.cpp
@@ -4668,10 +4754,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4684,14 +4766,47 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Kërkimi Dështoi."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Nuk mund të heqësh:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Ridrejto Ciklin."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Kërkimi Dështoi."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Koha"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4732,6 +4847,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Instalo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4760,13 +4880,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importo"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4774,8 +4897,9 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr ""
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Duke bër kërkesën..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4787,8 +4911,9 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
-msgstr ""
+#, fuzzy
+msgid "Support"
+msgstr "Importo"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -4799,6 +4924,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Ngarko…"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4849,31 +4979,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Krijo Pllakë"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Fshi keys të gabuar"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Krijo një Folder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Fshi keys të gabuar"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4955,6 +5089,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Pastro"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4984,6 +5123,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5004,14 +5144,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -5035,6 +5178,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5051,11 +5195,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5068,6 +5207,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5278,16 +5422,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5603,14 +5737,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5694,19 +5820,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6034,7 +6164,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6140,12 +6269,9 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr ""
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Nuk mund të krijoj folderin."
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6168,8 +6294,9 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
-msgstr ""
+#, fuzzy
+msgid "New Text File..."
+msgstr "Folder i Ri..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Open File"
@@ -6251,6 +6378,11 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Hap Editorin e Shkrimit"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6288,11 +6420,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6380,6 +6512,11 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Pastro Skenat e Fundit"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6449,6 +6586,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6484,26 +6622,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Ndrysho Mënyrën"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Shko tek Hapi Tjetër"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Shko tek Hapi i Mëparshëm"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Hiq Autoload-in"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6524,6 +6642,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Fshi të Selektuarat"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6540,40 +6663,60 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "Ndrysho Mënyrën"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Bookmark"
+msgstr "Shko tek Hapi Tjetër"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Shko tek Hapi i Mëparshëm"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr "Hiq Autoload-in"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6751,7 +6894,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6807,8 +6954,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Vetitë:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6861,7 +7009,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6872,27 +7020,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6936,26 +7064,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7010,8 +7118,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Duke u lidhur..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7310,10 +7419,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7399,11 +7504,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7509,14 +7614,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7530,8 +7627,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7813,6 +7910,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7896,6 +7997,11 @@ msgid "Duplicate Nodes"
msgstr "Dyfisho Nyjet"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Fshi Nyjen"
@@ -7918,6 +8024,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Krijo një Folder"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Krijo një Folder"
@@ -7991,6 +8102,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7998,10 +8125,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8090,7 +8251,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8098,7 +8259,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8110,7 +8271,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8127,7 +8288,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8196,11 +8357,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8216,7 +8377,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8227,7 +8388,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8236,7 +8397,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8244,11 +8405,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8288,11 +8449,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8301,7 +8466,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8319,15 +8484,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8377,7 +8542,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8392,6 +8557,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8405,19 +8574,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8426,7 +8595,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8435,14 +8604,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8487,47 +8656,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8694,6 +8870,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Menaxho Shabllonet e Eksportit"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8840,6 +9020,15 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Projekti"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8913,8 +9102,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8934,8 +9123,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Projekti"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8959,10 +9149,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9297,6 +9483,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9349,14 +9539,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9643,6 +9825,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9687,6 +9873,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Krijo një Folder"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9761,19 +9952,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9870,6 +10061,11 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Mbishkruaj"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9899,7 +10095,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10060,6 +10256,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Opsionet e Editorit"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10472,10 +10672,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Emër i palejuar. Nuk duhet të përplaset me emrin e një tipi 'buit-in'."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Krijo një Shtojcë"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Krijo një Folder"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Krijo %s të ri"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10660,10 +10880,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11393,22 +11609,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11421,6 +11621,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11437,15 +11641,33 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Nuk mund të hapi file_type_catche.cch për të shkruajtur, skedari nuk do "
+#~ "të ruhet!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Nuk mund të navigoj te '%s' sepse nuk është gjetur në sistemin e "
+#~ "skedarëve!"
+
+#~ msgid "Previous Folder"
+#~ msgstr "Folderi i Mëparshëm"
+
+#~ msgid "Next Folder"
+#~ msgstr "Folderi Tjetër"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Hap Editorin tjetër"
+
#~ msgid "Update Always"
#~ msgstr "Përditëso Gjithmonë"
#~ msgid "Delete selected files?"
#~ msgstr "Fshi skedarët e zgjedhur?"
-#~ msgid "Go to parent folder"
-#~ msgstr "Shko te folderi prind"
-
#~ msgid "Select device from the list"
#~ msgstr "Zgjidh paisjen nga lista"
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 024f536ebd..e6d1538c83 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -59,7 +59,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Слободно"
@@ -138,6 +137,31 @@ msgstr "Промени позив анимације"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Промени вредноÑÑ‚"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Промени прелаз"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Промени положај"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Промени вредноÑÑ‚"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Промени позив анимације"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "Промени Ñ†Ð¸ÐºÐ»ÑƒÑ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ˜Ðµ"
@@ -658,17 +682,18 @@ msgid "Line Number:"
msgstr "Број линије:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Замени %d појаве/а."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "Ðема подудара"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Замени %d појаве/а."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Подударање великих и малих Ñлова"
@@ -910,8 +935,7 @@ msgstr "Омиљене:"
msgid "Recent:"
msgstr "ЧеÑте:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1014,7 +1038,7 @@ msgstr ""
"Жељене датотеке за бриÑање Ñу потребне за рад других реÑурÑа.\n"
"Ипак их обриши? (ÐЕМРОПОЗИВÐЊÐ)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "Ðе може Ñе обриÑати:\n"
@@ -1053,7 +1077,7 @@ msgstr "Трајно обриши %d Ñтавка(и)? (ÐЕМРОПОЗИВÐÐ
msgid "Show Dependencies"
msgstr "ЗавиÑноÑти"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Преглед повезаних реÑурÑа"
@@ -1143,14 +1167,16 @@ msgid "License"
msgstr "ЛиценÑа"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "ЛиценÑа трећег лица"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine Ñе оÑлања на бројне Ñлободне и отворене библиотеке трећег лица "
@@ -1171,7 +1197,8 @@ msgid "Licenses"
msgstr "ЛиценÑе"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Грешка при отварању датотеку пакета. Датотека није zip формата."
#: editor/editor_asset_installer.cpp
@@ -1189,7 +1216,6 @@ msgid "Success!"
msgstr "УÑпех!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "ИнÑталирај"
@@ -1684,12 +1710,11 @@ msgid "New"
msgstr "Ðова"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Увоз"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Извоз"
@@ -1760,7 +1785,7 @@ msgstr "Покажи у менаџеру датотека"
msgid "New Folder..."
msgstr "Ðови директоријум..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "ОÑвежи"
@@ -1811,7 +1836,7 @@ msgstr "Ðапред"
msgid "Go Up"
msgstr "Иди горе"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Прикажи Ñакривене датотеке"
@@ -1837,27 +1862,32 @@ msgstr "Помери надоле омиљену"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Претодни Ñпрат"
+msgid "Go to previous folder."
+msgstr "Иди у родитељÑки директоријум"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Ðаправи директоријум"
+msgid "Go to next folder."
+msgstr "Иди у родитељÑки директоријум"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Иди у родитељÑки директоријум"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Потражи клаÑе"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "ÐеуÑпех при прављењу директоријума."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Прикажи Ñакривене датотеке"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2120,6 +2150,10 @@ msgstr "Обриши"
msgid "Clear Output"
msgstr "Излаз"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2438,6 +2472,15 @@ msgid "Pick a Main Scene"
msgstr "Одабери главну Ñцену"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Затвори Ñцену"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Затвори Ñцену"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "ÐеуÑпех при прикључивању додатка због конфигурационе датотеке: '%s'."
@@ -2555,6 +2598,11 @@ msgstr "Покрени Ñцену"
msgid "Close Tab"
msgstr "Затвори оÑтале зупчанике"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Затвори оÑтале зупчанике"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Затвори оÑтале зупчанике"
@@ -2609,6 +2657,11 @@ msgid "Go to previously opened scene."
msgstr "Отвори претходну Ñцену."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Копирај пут"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Следећи таб"
@@ -2636,6 +2689,10 @@ msgstr "Ðова наÑлеђена Ñцена..."
msgid "Open Scene..."
msgstr "Отвори Ñцену..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Отвори недавно коришћено"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Сачувај Ñцену"
@@ -2646,14 +2703,6 @@ msgid "Save All Scenes"
msgstr "Сачувај Ñве Ñцене"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Затвори Ñцену"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Отвори недавно коришћено"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Конвертуј у..."
@@ -2683,26 +2732,37 @@ msgstr "Поврати Ñцену"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Разни алати за пројекат или Ñцену."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Пројекат"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "ПоÑтавке пројекта"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Ðлати"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Извоз"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Отвори менаџер пројекта?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Ðлати"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Преглед повезаних реÑурÑа"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2800,12 +2860,13 @@ msgstr ""
"Када је ово коришћено на удаљеном уређају, ово је много ефикаÑније Ñа "
"мрежним датотечним ÑиÑтемом."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Уредник"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "ПоÑтавке уредника"
#: editor/editor_node.cpp
@@ -2823,15 +2884,6 @@ 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 "Укљ./ИÑкљ. режим целог екрана"
@@ -2856,14 +2908,15 @@ msgstr "ПоÑтавке уредника"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Управљај извозним шаблонима"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Управљај извозним шаблонима"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Помоћ"
@@ -2871,12 +2924,13 @@ msgstr "Помоћ"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Тражи"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлајн документација"
@@ -3160,6 +3214,11 @@ msgstr "Време:"
msgid "Calls"
msgstr "Позиви цртања"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Измени тему..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3328,7 +3387,8 @@ msgid "Import From Node:"
msgstr "Увоз преко чвора:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Поновно преузимање"
#: editor/export_template_manager.cpp
@@ -3345,6 +3405,10 @@ msgid "Download"
msgstr "Преучми"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(ÐедоÑтаје)"
@@ -3410,13 +3474,11 @@ msgid "No response."
msgstr "Ðема одговора."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "Захтев није уÑпешан."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Петља преуÑмерења."
@@ -3430,13 +3492,19 @@ msgid "Download Complete."
msgstr "Преузимање уÑпешно."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "ÐеуÑпех при чувању теме:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Грешка при захтеву url: "
#: editor/export_template_manager.cpp
@@ -3525,22 +3593,12 @@ msgstr "Преузми шаблоне"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Одабери одредиште Ñа лиÑте: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Ðе могу отворити „file_type_cache.cch“ за пиÑање! Ðе чувам датотеке "
-"кеш(cache) типа!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Омиљене:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "ÐеуÑпех навигације у „%s“ пошто није пронађен у датотечном ÑиÑтему!"
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3582,14 +3640,14 @@ msgid "Provided name contains invalid characters."
msgstr "Дато име Ñадржи неважећа Ñлова"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Дато име Ñадржи неважећа Ñлова."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Датотека или директоријум Ñа овим именом већ поÑтоји."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Дато име Ñадржи неважећа Ñлова."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Преименовање датотеке:"
@@ -3652,6 +3710,11 @@ msgstr "Дуплирај"
msgid "Move To..."
msgstr "Помери у..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ðова Ñцена"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3726,6 +3789,11 @@ msgstr "Датотека или директоријум Ñа овим именÐ
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Ðаправи од Ñцене"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Ðаправи Ñкриптицу"
@@ -3795,6 +3863,14 @@ msgid "Search complete"
msgstr "Потражи текÑÑ‚"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Додај у групу"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Обриши из групе"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "Грешка: име анимације већ поÑтоји!"
@@ -3804,13 +3880,23 @@ msgstr "Грешка: име анимације већ поÑтоји!"
msgid "Invalid group name."
msgstr "Ðеважеће име."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Групе"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Обирши раÑпоред"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Групе"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Додај у групу"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3824,12 +3910,13 @@ msgid "Nodes in Group"
msgstr "Додај у групу"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Додај у групу"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Обриши из групе"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Отвори уредник Ñкриптица"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4042,7 +4129,8 @@ msgid "MultiNode Set"
msgstr "ПоÑтави MultiNode"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Одабери чвор за мењање Ñигнала и група."
#: editor/plugin_config_dialog.cpp
@@ -4843,10 +4931,6 @@ msgid "View Files"
msgstr "Погледај датотеке"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Ðе могу решити име хоÑта:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Повезивање неуÑпешно, молимо Ð²Ð°Ñ Ð´Ð° покушате поново."
@@ -4859,14 +4943,47 @@ msgid "No response from host:"
msgstr "Ðема одговора од хоÑта:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Ðе могу решити име хоÑта:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Захтев неуÑпешан, повратни код:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Захтев није уÑпешан."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "ÐеуÑпех при чувању теме:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Захтев неуÑпео, превише преуÑмерења"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Петља преуÑмерења."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Захтев неуÑпешан, повратни код:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Време:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Лоша хеш Ñума, претпоÑтавља Ñе да је датотека измењена."
@@ -4909,6 +5026,11 @@ msgid "Idle"
msgstr "Ðеактиван"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "ИнÑталирај"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Покушај поново"
@@ -4939,13 +5061,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Ñви"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Увоз"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Прикључци"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4953,8 +5079,9 @@ msgid "Sort:"
msgstr "Сортирање:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Обрнут"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Захтевање..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4966,7 +5093,8 @@ msgid "Site:"
msgstr "Веб Ñтраница:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Подршка..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4978,6 +5106,11 @@ msgid "Testing"
msgstr "ТеÑтирање"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Учитај"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "РеÑурÑи ЗИП датотека"
@@ -5028,31 +5161,38 @@ msgid "Rotation Step:"
msgstr "Ротације корака:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Помери вертикални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Ðаправи нови вертикални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Обриши вертикални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Помери хоризонтални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Ðаправи нови хоризонтални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Обриши хоризонтални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Ðаправи нови хоризонтални и вертикални водич"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5143,6 +5283,11 @@ msgstr "Ðалепи позу"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Обриши позу"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Ðаправи тачке емиÑије од мреже"
@@ -5173,6 +5318,7 @@ msgid "Zoom Reset"
msgstr "Умањи"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Одабери режим"
@@ -5194,14 +5340,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+ДеÑни таÑтер миша: Ñелекција лиÑте дубине"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Режим померања"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Режим ротације"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Режим Ñкалирања (R)"
@@ -5229,6 +5378,7 @@ msgid "Toggle snapping."
msgstr "Укљ./ИÑкљ. лепљења"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "КориÑти лепљење"
@@ -5247,11 +5397,6 @@ msgid "Use Rotation Snap"
msgstr "КориÑти лепљење ротације"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "ПоÑтавке лепљења..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Залепи релативно"
@@ -5265,6 +5410,11 @@ msgid "Smart Snapping"
msgstr "Паметно лепљење"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "ПоÑтавке лепљења..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Лепи за родитеља"
@@ -5489,16 +5639,6 @@ msgstr "ПоÑтави дршку"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Грешка при учитавању Ñлике:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "У Ñлици нема пикÑела Ñа транÑпарентношћу већом од 128..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Учитај маÑку емиÑије"
@@ -5823,14 +5963,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Извор површине није важећи (нема Ñтрана)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Родитељ нема Ñтрана за попуњавање."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "ÐеуÑпех при мапирању облаÑти."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Одабери изворну мрежу:"
@@ -5916,20 +6048,27 @@ msgid "Generation Time (sec):"
msgstr "Време генериÑања (Ñек.):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Стране не Ñадрже облаÑÑ‚!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Ðема Ñтрана!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Чвор не Ñадржи геометрију (Ñтране)."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Чвор не Ñадржи геометрију."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Чвор не Ñадржи геометрију (Ñтране)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Чвор не Ñадржи геометрију."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6271,7 +6410,6 @@ msgid "Grid Settings"
msgstr "ПоÑтавке"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Залепи"
@@ -6390,12 +6528,7 @@ msgstr "Грешка при чувању TileSet!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "ÐеуÑпех при тражењу плочице:"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "ÐеуÑпех при тражењу плочице:"
#: editor/plugins/script_editor_plugin.cpp
@@ -6425,7 +6558,7 @@ msgstr "Грешка при увозу"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Ðови директоријум..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6512,6 +6645,11 @@ msgid "Open..."
msgstr "Отвори"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Покрени Ñкриптицу"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Сачувај Ñве"
@@ -6553,13 +6691,13 @@ msgid "Save Theme"
msgstr "Сачувај тему"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Затвори документацију"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Затвори Ñве"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Затвори документацију"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Покрени"
@@ -6650,6 +6788,11 @@ msgstr "Дебагер"
msgid "Search Results"
msgstr "Потражи помоћ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ОчиÑти недавне Ñцене"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6725,6 +6868,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6761,26 +6905,6 @@ msgstr "Коментариши"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Укљ./ИÑкљ. режим Ñлободног гледања"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Иди на Ñледећу прекудну тачку"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Иди на претходну прекидну тачку"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Обриши Ñве Ñтавке"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "Откриј линију"
@@ -6801,6 +6925,11 @@ msgid "Complete Symbol"
msgstr "Потпун Ñимбол"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Увећај одабрано"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Обриши празнине Ñа крајева"
@@ -6819,32 +6948,37 @@ msgid "Auto Indent"
msgstr "ÐутоматÑко увлачење"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "ПоÑтави прекидну тачку"
+msgid "Find Previous"
+msgstr "Ðађи претходни"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Обриши Ñве прекидне тачке"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Филтрирај датотеке..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "КонтекÑтуална помоћ"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Иди на Ñледећу прекудну тачку"
+msgid "Toggle Bookmark"
+msgstr "Укљ./ИÑкљ. режим Ñлободног гледања"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Иди на претходну прекидну тачку"
+msgid "Go to Next Bookmark"
+msgstr "Иди на Ñледећу прекудну тачку"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Ðађи претходни"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Иди на претходну прекидну тачку"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Филтрирај датотеке..."
+msgid "Remove All Bookmarks"
+msgstr "Обриши Ñве Ñтавке"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6857,8 +6991,23 @@ msgid "Go to Line..."
msgstr "Иди на линију..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "КонтекÑтуална помоћ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "ПоÑтави прекидну тачку"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Обриши Ñве прекидне тачке"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Иди на Ñледећу прекудну тачку"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Иди на претходну прекидну тачку"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -7045,9 +7194,14 @@ msgstr "Бок"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "Поравнавање Ñа погледом"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Поравнај одабрано Ñа погледом"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "Ðема родитеља за прављење Ñина."
@@ -7102,8 +7256,9 @@ msgid "Audio Listener"
msgstr "Звучни Ñлушалац"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "„Doppler“ режим"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Измени дужину анимације"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7159,9 +7314,8 @@ msgid "Snap Nodes To Floor"
msgstr "Залепи за мрежу"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Режим Ñелекције (Q)\n"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7174,32 +7328,11 @@ msgstr ""
"Alt+деÑни таÑтер миша: Ñелекција лиÑте дубине"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Режим помераја (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Режим ротације (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Режим Ñкалирања (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Локалне координате"
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr "Режим Ñкалирања (R)"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "Режим лепљења:"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Поглед одоздо"
@@ -7241,26 +7374,6 @@ msgid "Focus Selection"
msgstr "Ð¤Ð¾ÐºÑƒÑ Ð½Ð° Ñелекцију"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Поравнај одабрано Ñа погледом"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Избор алатки"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Ðлат помераја"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Ðлат ротације"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Ðлат Ñкалирања"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Укљ./ИÑкљ. режим Ñлободног гледања"
@@ -7317,7 +7430,8 @@ msgstr "Прикажи мрежу"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "ПоÑтавке"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7637,10 +7751,6 @@ msgid "TextureRegion"
msgstr "Регион текÑтуре"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "ÐеуÑпех при чувању теме:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Додај Ñве Ñтавке"
@@ -7732,12 +7842,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Ставка"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Ставка"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7851,14 +7961,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Огледало X оÑе"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Огледало Y оÑе"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "ÐутоматÑки рез"
@@ -7874,8 +7976,8 @@ msgstr "Цртај полчице"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8199,6 +8301,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Додај улаз"
@@ -8291,6 +8397,11 @@ msgid "Duplicate Nodes"
msgstr "Дуплирај чвор/ове графа"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Ðаправи чвор"
@@ -8315,6 +8426,11 @@ msgstr "деÑно"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Ðаправи чвор"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Ðаправи чвор"
@@ -8393,6 +8509,22 @@ msgid "Color uniform."
msgstr "ТранÑформација"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8400,10 +8532,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "Промени векторÑку конÑтанту"
@@ -8496,7 +8662,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8504,7 +8670,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8516,7 +8682,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8533,7 +8699,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8602,11 +8768,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8622,7 +8788,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8633,7 +8799,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8642,7 +8808,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8650,11 +8816,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8697,12 +8863,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr "Промени текÑтурну униформу (uniform)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup."
msgstr "Промени текÑтурну униформу (uniform)"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr "Промени текÑтурну униформу (uniform)"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8712,7 +8883,7 @@ msgstr "Прозор транÑформације..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8730,15 +8901,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8791,7 +8962,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8806,6 +8977,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8819,19 +8994,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8840,7 +9015,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8849,14 +9024,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8903,47 +9078,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9127,6 +9309,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Извозни шаблони за ову платформу ниÑу пронађени:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Управљај извозним шаблонима"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9279,6 +9465,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Пројекат"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Ðе могу отворити '%s'."
@@ -9352,8 +9547,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9373,8 +9568,9 @@ msgid "Project Manager"
msgstr "Менаџер пројекта"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "Пројекат"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9398,10 +9594,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9741,6 +9933,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Прикључци"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9793,14 +9989,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10103,6 +10291,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Промени улазно име"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10150,6 +10343,11 @@ msgstr "Покрени Ñкриптицу"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Ðаправи нов"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Сачувај Ñцену"
@@ -10226,19 +10424,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10336,6 +10534,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10368,7 +10570,7 @@ msgid "Script is valid."
msgstr "Ðнимационо дрво је важеће."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10534,6 +10736,10 @@ msgid "Change Shortcut"
msgstr "Промени Ñидра"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "ПоÑтавке уредника"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10955,10 +11161,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Ðеважеће име. Име је резервиÑано за поÑтојећи уграђени тип."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Ðаправи нов"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Ðаправи нов"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Ðаправи нови полигон од почетка."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11146,10 +11372,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Чланови"
@@ -11898,22 +12120,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ðеважећа величина фонта."
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11929,6 +12135,11 @@ msgstr "Ðеважећа величина фонта."
msgid "Invalid source for shader."
msgstr "Ðеважећа величина фонта."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ðеважећа величина фонта."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11945,6 +12156,96 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Ðе могу отворити „file_type_cache.cch“ за пиÑање! Ðе чувам датотеке "
+#~ "кеш(cache) типа!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "ÐеуÑпех навигације у „%s“ пошто није пронађен у датотечном ÑиÑтему!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Грешка при учитавању Ñлике:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "У Ñлици нема пикÑела Ñа транÑпарентношћу већом од 128..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Родитељ нема Ñтрана за попуњавање."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "ÐеуÑпех при мапирању облаÑти."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Стране не Ñадрже облаÑÑ‚!"
+
+#~ msgid "No faces!"
+#~ msgstr "Ðема Ñтрана!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "ÐеуÑпех при тражењу плочице:"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "„Doppler“ режим"
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Режим Ñелекције (Q)\n"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Режим помераја (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Режим ротације (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Режим Ñкалирања (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Локалне координате"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Режим лепљења:"
+
+#~ msgid "Tool Select"
+#~ msgstr "Избор алатки"
+
+#~ msgid "Tool Move"
+#~ msgstr "Ðлат помераја"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Ðлат ротације"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Ðлат Ñкалирања"
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ðеважећа величина фонта."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Претодни Ñпрат"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Ðаправи директоријум"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Отвори Ñледећи уредник"
+
+#~ msgid "Reverse"
+#~ msgstr "Обрнут"
+
+#~ msgid "Mirror X"
+#~ msgstr "Огледало X оÑе"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Огледало Y оÑе"
+
#, fuzzy
#~ msgid "Generating solution..."
#~ msgstr "Прављење контура..."
@@ -11970,10 +12271,6 @@ msgstr ""
#~ msgstr "Ðаправи ивице"
#, fuzzy
-#~ msgid "Build Project"
-#~ msgstr "Пројекат"
-
-#, fuzzy
#~ msgid "View log"
#~ msgstr "Погледај датотеке"
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 8478d11a8f..49789c467a 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -5,12 +5,13 @@
# Milos Ponjavusic <brane@branegames.com>, 2018.
# BLu <blmasfon@gmail.com>, 2018.
# Vojislav Bajakic <ch3d4.ns@gmail.com>, 2018.
+# LT <lakizvezdas@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-12-13 14:42+0100\n"
-"Last-Translator: Vojislav Bajakic <ch3d4.ns@gmail.com>\n"
+"PO-Revision-Date: 2019-07-29 19:21+0000\n"
+"Last-Translator: LT <lakizvezdas@gmail.com>\n"
"Language-Team: Serbian (latin) <https://hosted.weblate.org/projects/godot-"
"engine/godot/sr_Latn/>\n"
"Language: sr_Latn\n"
@@ -19,7 +20,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: Poedit 2.2\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
@@ -61,35 +62,32 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
-msgstr ""
+msgstr "Slobodno"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Balansirano"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr ""
+msgstr "Ogledalo"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
-msgstr ""
+msgstr "Vreme:"
#: editor/animation_bezier_editor.cpp
msgid "Value:"
-msgstr ""
+msgstr "Vrednost:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Insert Key Here"
-msgstr "Animacija dodaj kljuÄ"
+msgstr "Dodaj kljuÄ ovde"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Duplicate Selected Key(s)"
-msgstr "Uduplaj Selekciju"
+msgstr "Dupliraj Selektovane KljuÄeve"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
@@ -97,11 +95,11 @@ msgstr "IzbriÅ¡i oznaÄeni kljuÄ(eve)"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr ""
+msgstr "Dodaj Bezier TaÄku"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr ""
+msgstr "Pomeri Bezier TaÄke"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -133,8 +131,32 @@ msgstr "Animacija Promjeni Poziv"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animacija Promjeni Vrijeme KljuÄnog Kadra"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Animacija Promjeni Tranziciju"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Animacija Promjeni Transformaciju"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animacija Promjeni Vrijednost KljuÄnog Kadra"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Animacija Promjeni Poziv"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr "Promijeni Dužinu Animacije"
+msgstr "Promeni Dužinu Animacije"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -159,26 +181,24 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr ""
+msgstr "Audio Plejbek Traka"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
-msgstr ""
+msgstr "Animacija Plejbek Traka"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
-msgstr "Optimizuj Animaciju"
+msgstr "Dužina Animacije (frames)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
-msgstr "Promijeni Dužinu Animacije"
+msgstr "Dužina Animacije (secunde)"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Add Track"
-msgstr "Animacija Dodaj Kanal"
+msgstr "Dodaj Traku"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
@@ -186,16 +206,18 @@ msgstr ""
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
msgid "Functions:"
-msgstr ""
+msgstr "Funkcije:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr ""
+msgstr "Audio Klipovi:"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Anim Clips:"
-msgstr ""
+msgstr "Anim Klipovi:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
@@ -224,7 +246,7 @@ msgstr "Odstrani Kanal Animacije"
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr ""
+msgstr "Vreme (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -247,8 +269,9 @@ msgid "Capture"
msgstr ""
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Nearest"
-msgstr ""
+msgstr "Najbliže"
#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
@@ -275,12 +298,12 @@ msgstr ""
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Duplicate Key(s)"
-msgstr "Animacija Uduplaj KljuÄeve"
+msgstr "Dupliraj KljuÄeve"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Delete Key(s)"
-msgstr "Animacija ObriÅ¡i KljuÄeve"
+msgstr "ObriÅ¡i KljuÄeve"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -376,7 +399,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Add Bezier Track"
-msgstr "Animacija Dodaj Kanal"
+msgstr "Dodaj Bezier Kanal"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
@@ -392,9 +415,8 @@ msgid "Add Transform Track Key"
msgstr "Animacija Dodaj kanal i kljuÄ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "Animacija Dodaj Kanal"
+msgstr "Dodaj Kljuc Kanal"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
@@ -636,15 +658,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -869,8 +891,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -964,7 +985,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -1000,7 +1021,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1089,14 +1110,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1113,7 +1134,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1130,7 +1151,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1598,12 +1618,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1664,7 +1683,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1715,7 +1734,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1740,23 +1759,29 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Otiđi Na Prethodni Korak"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Otiđi Na Sljedeći Korak"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1991,6 +2016,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2287,6 +2316,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2380,6 +2417,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2433,6 +2474,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Obriši Selekciju"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2460,20 +2506,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2506,24 +2548,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2603,13 +2653,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Tranzicije"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2624,14 +2675,6 @@ 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 ""
@@ -2652,14 +2695,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2667,12 +2710,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2945,6 +2989,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Izmjeni Selekciju Krivulje"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3106,7 +3155,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3123,6 +3172,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3184,12 +3237,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3203,13 +3254,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3294,19 +3349,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3339,11 +3386,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3402,6 +3449,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3465,6 +3516,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Napravi"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3525,6 +3581,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3532,12 +3596,21 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Animacija ObriÅ¡i KljuÄeve"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3550,11 +3623,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3761,7 +3834,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4516,10 +4589,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4532,14 +4601,43 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Vreme:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4580,6 +4678,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4608,13 +4710,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4622,7 +4726,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4635,7 +4739,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4647,6 +4751,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4697,31 +4805,34 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Napravi"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Obriši Selekciju"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Obriši Selekciju"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4803,6 +4914,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Animacija Promjeni Transformaciju"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4832,6 +4948,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4852,14 +4969,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4883,6 +5003,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4899,11 +5020,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4916,6 +5032,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5126,16 +5247,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5451,14 +5562,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5542,19 +5645,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5886,7 +5993,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5992,11 +6098,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6020,7 +6122,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6101,6 +6203,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6138,11 +6244,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6230,6 +6336,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6297,6 +6407,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6332,24 +6443,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Otiđi Na Sljedeći Korak"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Otiđi Na Prethodni Korak"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6370,6 +6463,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skaliraj Selekciju"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6386,44 +6484,62 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Go to Next Bookmark"
msgstr "Otiđi Na Sljedeći Korak"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr "Otiđi Na Prethodni Korak"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Remove All Breakpoints"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Otiđi Na Sljedeći Korak"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Otiđi Na Prethodni Korak"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6599,7 +6715,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6655,7 +6775,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6709,7 +6829,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6720,27 +6840,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6784,26 +6884,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6858,7 +6938,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7161,10 +7241,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7251,11 +7327,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7362,14 +7438,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7383,8 +7451,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7682,6 +7750,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7762,6 +7834,11 @@ msgid "Duplicate Nodes"
msgstr "Animacija Uduplaj KljuÄeve"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Animacija ObriÅ¡i KljuÄeve"
@@ -7783,6 +7860,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7857,6 +7938,22 @@ msgid "Color uniform."
msgstr "Animacija Promjeni Transformaciju"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7864,10 +7961,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7957,7 +8088,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7965,7 +8096,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7977,7 +8108,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7994,7 +8125,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8063,11 +8194,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8083,7 +8214,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8094,7 +8225,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8103,7 +8234,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8111,11 +8242,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8156,11 +8287,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8170,7 +8305,7 @@ msgstr "Napravi"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8188,15 +8323,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8247,7 +8382,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8262,6 +8397,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8275,19 +8414,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8296,7 +8435,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8305,14 +8444,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8357,47 +8496,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8564,6 +8710,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8710,6 +8860,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8779,8 +8937,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8800,7 +8958,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8825,10 +8983,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9164,6 +9318,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9216,14 +9374,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9511,6 +9661,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9553,6 +9707,11 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Napravi"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9625,19 +9784,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9728,6 +9887,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9756,7 +9919,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9917,6 +10080,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10330,10 +10497,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Napravi"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Napravi"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Napravi"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10518,10 +10704,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11251,22 +11433,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11279,6 +11445,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index 0b7ff433c9..ed6ea9abe6 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -65,7 +65,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Gratis"
@@ -135,6 +134,31 @@ msgid "Anim Change Call"
msgstr "Anim Ändra Anrop"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Anim Ändra Tid för Nyckebild"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Anim Ändra Övergång"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Anim Ändra Transformation"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Anim Ändra Värde På Nyckelbild"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Anim Ändra Anrop"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Ändra Animationslängd"
@@ -662,18 +686,18 @@ msgid "Line Number:"
msgstr "Radnummer:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "Ersatte %d förekomst(er)."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
#, fuzzy
-msgid "No Matches"
+msgid "%d matches."
msgstr "Inga matchningar"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Ersatte %d förekomst(er)."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
#, fuzzy
msgid "Match Case"
@@ -923,8 +947,7 @@ msgstr "Favoriter:"
msgid "Recent:"
msgstr "Senaste:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1038,7 +1061,7 @@ msgstr ""
"Filerna som tas bort krävs av andra resurser för att de ska fungera.\n"
"Ta bort dem ändå? (går inte ångra)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "Kan inte ta bort:\n"
@@ -1083,7 +1106,7 @@ msgstr "Ta bort %d sak(er) permanent? (Går inte ångra!)"
msgid "Show Dependencies"
msgstr "Beroenden"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Föräldralös Resursutforskare"
@@ -1189,14 +1212,15 @@ msgstr "Licens"
#: editor/editor_about.cpp
#, fuzzy
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr "Tredje parts Licens"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine förlitar sig på ett antal av tredje parts gratis och öppen "
@@ -1220,7 +1244,7 @@ msgstr "Licenser"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
#, fuzzy
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr "Fel vid öppning av paketetfil, inte i zip-format."
#: editor/editor_asset_installer.cpp
@@ -1240,7 +1264,6 @@ msgid "Success!"
msgstr "Klart!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Installera"
@@ -1783,12 +1806,11 @@ msgid "New"
msgstr "Ny"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Importera"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Exportera"
@@ -1861,7 +1883,7 @@ msgstr "Visa I Filhanteraren"
msgid "New Folder..."
msgstr "Ny Mapp..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Uppdatera"
@@ -1914,7 +1936,7 @@ msgstr "Gå Framåt"
msgid "Go Up"
msgstr "GÃ¥ Upp"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "Toggle Hidden Files"
msgstr "Växla Dolda Filer"
@@ -1943,27 +1965,32 @@ msgstr "Flytta Favorit Ner"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "Föregående flik"
+msgid "Go to previous folder."
+msgstr "Gå till överordnad mapp"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "Skapa Mapp"
+msgid "Go to next folder."
+msgstr "Gå till överordnad mapp"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Gå till överordnad mapp"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Sök Klasser"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "Kunde inte skapa mapp."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Växla Dolda Filer"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2240,6 +2267,10 @@ msgstr "Rensa"
msgid "Clear Output"
msgstr "Output:"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Projekt exporten misslyckades med följande felmeddelande %d."
@@ -2600,6 +2631,15 @@ msgid "Pick a Main Scene"
msgstr "Välj en Huvudscen"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Stäng Scen"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Stäng Scen"
+
+#: editor/editor_node.cpp
#, fuzzy
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2729,6 +2769,11 @@ msgstr "Spela Scen"
msgid "Close Tab"
msgstr "Stänga Övriga Flikar"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Stänga Övriga Flikar"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "Close Other Tabs"
@@ -2788,6 +2833,11 @@ msgid "Go to previously opened scene."
msgstr "Gå till föregående öppna scen."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Kopiera Sökvägen"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Nästa flik"
@@ -2817,6 +2867,11 @@ msgstr "Ny Ärvd Scen..."
msgid "Open Scene..."
msgstr "Öppna Scen..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Open Recent"
+msgstr "Öppna Senaste"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Spara Scen"
@@ -2827,15 +2882,6 @@ msgid "Save All Scenes"
msgstr "Spara alla Scener"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Stäng Scen"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Open Recent"
-msgstr "Öppna Senaste"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Konvertera Till..."
@@ -2869,26 +2915,37 @@ msgstr "Återställ Scen"
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Projektinställningar"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Verktyg"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Exportera"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "Öppna Projekthanteraren?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Verktyg"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Föräldralös Resursutforskare"
#: editor/editor_node.cpp
#, fuzzy
@@ -2971,13 +3028,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "Övergångar"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2993,14 +3051,6 @@ 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 ""
@@ -3022,14 +3072,15 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr "Mallar"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Hjälp"
@@ -3037,12 +3088,13 @@ msgstr "Hjälp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Sök"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
msgstr "Dokumentation Online"
@@ -3331,6 +3383,11 @@ msgstr "Tid:"
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Redigera tema..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
#, fuzzy
msgid "On"
@@ -3504,8 +3561,9 @@ msgid "Import From Node:"
msgstr "Importera Från Node:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
-msgstr ""
+#, fuzzy
+msgid "Redownload"
+msgstr "Ladda ner"
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -3522,6 +3580,10 @@ msgid "Download"
msgstr "Ladda ner"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Saknas)"
@@ -3588,12 +3650,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3608,14 +3668,20 @@ msgid "Download Complete."
msgstr "Nedladdning Klar."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Kan inte spara tema till fil:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
-msgstr ""
+#, fuzzy
+msgid "Error requesting URL:"
+msgstr "Fel vid laddning:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
@@ -3712,20 +3778,12 @@ msgstr "Ladda Ner Mallar"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Favoriter:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3761,15 +3819,15 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr ""
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "A file or folder with this name already exists."
msgstr "En fil eller mapp med detta namn finns redan."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Renaming file:"
msgstr "Byter namn på filen:"
@@ -3838,6 +3896,11 @@ msgstr "Duplicera"
msgid "Move To..."
msgstr "Flytta Till..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ny Scen"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3910,6 +3973,11 @@ msgstr "En fil eller mapp med detta namn finns redan."
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Skapa från Scen"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Skapa Skript"
@@ -3982,6 +4050,14 @@ msgid "Search complete"
msgstr "Söktext"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Lägg till i Grupp"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Ta bort från Grupp"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "ERROR: Animationsnamn finns redan!"
@@ -3991,13 +4067,23 @@ msgstr "ERROR: Animationsnamn finns redan!"
msgid "Invalid group name."
msgstr "Ogiltigt namn."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Grupper"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Ta bort Layout"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Grupper"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "Lägg till i Grupp"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -4011,12 +4097,13 @@ msgid "Nodes in Group"
msgstr "Lägg till i Grupp"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Lägg till i Grupp"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Ta bort från Grupp"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Öppna Skript-Redigerare"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4240,7 +4327,7 @@ msgstr "MultiNode Ange"
#: editor/node_dock.cpp
#, fuzzy
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr "Välj en Node för att redigera Signaler och Grupper."
#: editor/plugin_config_dialog.cpp
@@ -5053,10 +5140,6 @@ msgid "View Files"
msgstr "Visa Filer"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -5069,14 +5152,44 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Kan inte spara tema till fil:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Tid:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -5120,6 +5233,11 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
+msgid "Install..."
+msgstr "Installera"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Retry"
msgstr "Försök igen"
@@ -5149,13 +5267,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Alla"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Importera"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -5163,7 +5284,7 @@ msgid "Sort:"
msgstr "Sortera:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5177,8 +5298,9 @@ msgid "Site:"
msgstr "Webbplats:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
-msgstr ""
+#, fuzzy
+msgid "Support"
+msgstr "Importera"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -5189,6 +5311,11 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Ladda"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -5240,31 +5367,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Skapa Mapp"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Ta bort Variabeln"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Skapa Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Ta bort ogiltiga nycklar"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5350,6 +5481,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "Rensa"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Skapa från Scen"
@@ -5380,6 +5516,7 @@ msgid "Zoom Reset"
msgstr "Zooma Ut"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -5400,14 +5537,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Växla Läge"
@@ -5432,6 +5572,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5449,11 +5590,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5466,6 +5602,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5686,16 +5827,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -6021,14 +6152,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -6118,19 +6241,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6468,7 +6595,6 @@ msgid "Grid Settings"
msgstr "Inställningar"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6582,12 +6708,7 @@ msgstr "Fel vid sparande av TileSet!"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Fel - Kunde inte skapa Skript i filsystemet."
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "Fel - Kunde inte skapa Skript i filsystemet."
#: editor/plugins/script_editor_plugin.cpp
@@ -6617,7 +6738,7 @@ msgstr "Fel vid laddning:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Ny Mapp..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6712,6 +6833,11 @@ msgid "Open..."
msgstr "Öppen"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Öppna Skript"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Spara Alla"
@@ -6755,13 +6881,13 @@ msgid "Save Theme"
msgstr "Spara Tema"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Stäng Alla"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Kör"
@@ -6852,6 +6978,11 @@ msgstr ""
msgid "Search Results"
msgstr "Sök Hjälp"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Rensa Senaste Scener"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6928,6 +7059,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6965,26 +7097,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Växla Läge"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Gå Till Nästa Steg"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Ge Till Föregående Steg"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Ta bort Alla"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -7005,6 +7117,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Skala urval"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -7024,32 +7141,37 @@ msgid "Auto Indent"
msgstr "Automatisk Indentering"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Filtrera Filer..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Gå Till Nästa Steg"
+msgid "Toggle Bookmark"
+msgstr "Växla Läge"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Ge Till Föregående Steg"
+msgid "Go to Next Bookmark"
+msgstr "Gå Till Nästa Steg"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Ge Till Föregående Steg"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Filtrera Filer..."
+msgid "Remove All Bookmarks"
+msgstr "Ta bort Alla"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7062,9 +7184,24 @@ msgid "Go to Line..."
msgstr "GÃ¥ till Rad"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Gå Till Nästa Steg"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Ge Till Föregående Steg"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -7264,7 +7401,12 @@ msgstr "Baksida"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr "Vy från höger"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr "Vy från höger"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7325,8 +7467,9 @@ msgid "Audio Listener"
msgstr "Ljud-Lyssnare"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Redigerbara Barn"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -7380,9 +7523,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "Välj Node"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7392,27 +7534,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7462,26 +7584,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -7537,7 +7639,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Inställningar"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7852,11 +7955,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
-msgid "Can't save theme to file:"
-msgstr "Kan inte spara tema till fil:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7948,11 +8046,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -8066,16 +8164,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
-msgid "Mirror X"
-msgstr "Spegla X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
-msgid "Mirror Y"
-msgstr "Spegla Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -8090,8 +8178,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8407,6 +8495,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Lägg till Signal"
@@ -8493,6 +8585,12 @@ msgid "Duplicate Nodes"
msgstr "Duplicera Nod(er)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Paste Nodes"
+msgstr "Klistra in Noder"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Ta bort Nod(er)"
@@ -8516,6 +8614,11 @@ msgstr "Höger"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Skapa Node"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Skapa Node"
@@ -8593,6 +8696,22 @@ msgid "Color uniform."
msgstr "Transformera"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8600,10 +8719,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8693,7 +8846,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8701,7 +8854,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8713,7 +8866,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8730,7 +8883,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8799,11 +8952,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8819,7 +8972,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8830,7 +8983,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8839,7 +8992,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8847,11 +9000,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8892,11 +9045,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8906,7 +9063,7 @@ msgstr "Transformera"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8924,15 +9081,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8984,7 +9141,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8999,6 +9156,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -9012,19 +9173,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -9033,7 +9194,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -9042,14 +9203,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9094,47 +9255,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9312,6 +9480,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9475,6 +9647,15 @@ msgstr "Namnlöst Projekt"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Importera Befintligt Projekt"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Kan inte öppna projekt"
@@ -9548,8 +9729,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9571,8 +9752,8 @@ msgstr "Projektledare"
#: editor/project_manager.cpp
#, fuzzy
-msgid "Project List"
-msgstr "Projektlista"
+msgid "Projects"
+msgstr "Projekt"
#: editor/project_manager.cpp
#, fuzzy
@@ -9601,11 +9782,6 @@ msgstr "Mallar"
#: editor/project_manager.cpp
#, fuzzy
-msgid "Exit"
-msgstr "Avsluta"
-
-#: editor/project_manager.cpp
-#, fuzzy
msgid "Restart Now"
msgstr "Starta om nu"
@@ -9958,6 +10134,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
#, fuzzy
msgid "Zero"
@@ -10014,14 +10194,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10338,6 +10510,11 @@ msgid "Remove Node(s)"
msgstr "Ta bort Nod(er)"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Ändra Typ"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10388,6 +10565,11 @@ msgstr "Öppna Skript"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Byt Förälder-Node"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Vettigt!"
@@ -10466,19 +10648,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10583,6 +10765,10 @@ msgid "Error loading script from %s"
msgstr "Fel vid laddning av Skript från %s"
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10615,7 +10801,8 @@ msgid "Script is valid."
msgstr "Skript giltigt"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Tillåtna: a-z, a-Z, 0-9 och _"
#: editor/script_create_dialog.cpp
@@ -10791,6 +10978,10 @@ msgid "Change Shortcut"
msgstr "Genvägar"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
#, fuzzy
msgid "Shortcuts"
msgstr "Genvägar"
@@ -11221,10 +11412,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt inbyggt typnamn."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Skapa Ny"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variabler:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Skapa Ny"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Skapa Prenumeration"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11428,11 +11639,6 @@ msgstr "Klipp ut Noder"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "Klistra in Noder"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "Medlemmar"
@@ -12219,26 +12425,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-#, fuzzy
-msgid "Error initializing FreeType."
-msgstr "Fel vid initiering av FreeType."
-
-#: scene/resources/dynamic_font.cpp
-#, fuzzy
-msgid "Unknown font format."
-msgstr "Okänt fontformat."
-
-#: scene/resources/dynamic_font.cpp
-#, fuzzy
-msgid "Error loading font."
-msgstr "Fel vid laddning av font."
-
-#: scene/resources/dynamic_font.cpp
-#, fuzzy
-msgid "Invalid font size."
-msgstr "Ogiltig teckenstorlek."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -12253,6 +12439,11 @@ msgstr "Ogiltig teckenstorlek."
msgid "Invalid source for shader."
msgstr "Ogiltig teckenstorlek."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Ogiltig teckenstorlek."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -12270,6 +12461,54 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Fel - Kunde inte skapa Skript i filsystemet."
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Välj Node"
+
+#, fuzzy
+#~ msgid "Project List"
+#~ msgstr "Projektlista"
+
+#, fuzzy
+#~ msgid "Exit"
+#~ msgstr "Avsluta"
+
+#, fuzzy
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Fel vid initiering av FreeType."
+
+#, fuzzy
+#~ msgid "Unknown font format."
+#~ msgstr "Okänt fontformat."
+
+#, fuzzy
+#~ msgid "Error loading font."
+#~ msgstr "Fel vid laddning av font."
+
+#, fuzzy
+#~ msgid "Invalid font size."
+#~ msgstr "Ogiltig teckenstorlek."
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "Föregående flik"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "Skapa Mapp"
+
+#, fuzzy
+#~ msgid "Mirror X"
+#~ msgstr "Spegla X"
+
+#, fuzzy
+#~ msgid "Mirror Y"
+#~ msgstr "Spegla Y"
+
+#, fuzzy
#~ msgid "Generating solution..."
#~ msgstr "Skapar konturer..."
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index 2aad1e09d7..521b42b338 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -60,7 +60,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -132,6 +131,31 @@ msgid "Anim Change Call"
msgstr "மாறà¯à®± அழைபà¯à®ªà¯ அசைவூடà¯à®Ÿà¯"
#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "மாறà¯à®± மதிபà¯à®ªà¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "மாறà¯à®±à®®à¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "உரà¯à®®à®¾à®±à¯à®±à®®à¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "மாறà¯à®± மதிபà¯à®ªà¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "மாறà¯à®± அழைபà¯à®ªà¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -627,15 +651,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -860,8 +884,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -955,7 +978,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -991,7 +1014,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1080,14 +1103,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1104,7 +1127,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1121,7 +1144,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1589,12 +1611,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1655,7 +1676,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1706,7 +1727,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1731,23 +1752,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1981,6 +2006,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2277,6 +2306,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2370,6 +2407,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2423,6 +2464,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•à®³à¯"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2450,20 +2496,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2496,24 +2538,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2593,13 +2643,14 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
-msgstr ""
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
+msgstr "மாறà¯à®±à®™à¯à®•à®³à¯ˆ இதறà¯à®•à¯ அமை:"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2614,14 +2665,6 @@ 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 ""
@@ -2642,14 +2685,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2657,12 +2700,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2934,6 +2978,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "தேரà¯à®µà¯ வளைவை [Selection Curve] திரà¯à®¤à¯à®¤à¯"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3095,7 +3144,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3112,6 +3161,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3173,12 +3226,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3192,13 +3243,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3283,19 +3338,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3328,11 +3375,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3392,6 +3439,10 @@ msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•à®³à¯"
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3455,6 +3506,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3515,6 +3570,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3522,12 +3585,21 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•à®³à¯"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3540,11 +3612,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3751,7 +3823,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4502,10 +4574,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4518,14 +4586,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4566,6 +4662,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4594,13 +4694,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4608,7 +4710,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4621,7 +4723,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4633,6 +4735,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4683,31 +4789,32 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4789,6 +4896,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "உரà¯à®®à®¾à®±à¯à®±à®®à¯ அசைவூடà¯à®Ÿà¯"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4818,6 +4930,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4838,14 +4951,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4869,6 +4985,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4885,11 +5002,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4902,6 +5014,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5109,16 +5226,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5431,14 +5538,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5522,19 +5621,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5863,7 +5966,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5969,11 +6071,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5997,7 +6095,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6078,6 +6176,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6115,11 +6217,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6207,6 +6309,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6273,6 +6379,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6307,92 +6414,97 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•à®³à¯"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Go to Next Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6570,7 +6682,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6626,7 +6742,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6680,7 +6796,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6691,27 +6807,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6755,26 +6851,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6829,7 +6905,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7124,10 +7200,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7214,11 +7286,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7325,14 +7397,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7346,8 +7410,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7629,6 +7693,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7707,6 +7775,11 @@ msgid "Duplicate Nodes"
msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•à®³à¯"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•à®³à¯"
@@ -7728,6 +7801,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7801,6 +7878,22 @@ msgid "Color uniform."
msgstr "உரà¯à®®à®¾à®±à¯à®±à®®à¯ அசைவூடà¯à®Ÿà¯"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7808,10 +7901,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7900,7 +8027,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7908,7 +8035,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7920,7 +8047,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7937,7 +8064,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8006,11 +8133,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8026,7 +8153,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8037,7 +8164,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8046,7 +8173,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8054,11 +8181,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8099,11 +8226,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8112,7 +8243,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8130,15 +8261,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8187,7 +8318,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8202,6 +8333,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8215,19 +8350,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8236,7 +8371,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8245,14 +8380,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8297,47 +8432,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8504,6 +8646,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8650,6 +8796,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8719,8 +8873,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8740,7 +8894,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8764,10 +8918,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9102,6 +9252,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9154,14 +9308,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9449,6 +9595,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9491,6 +9641,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9563,19 +9717,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9666,6 +9820,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9694,7 +9852,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9854,6 +10012,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10267,10 +10429,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10455,10 +10633,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11188,22 +11362,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11216,6 +11374,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 8d9b4c87f2..24f581a5e6 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -58,7 +58,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -127,6 +126,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -611,15 +630,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -843,8 +862,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -938,7 +956,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -974,7 +992,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1063,14 +1081,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1087,7 +1105,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1104,7 +1122,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1571,12 +1588,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1637,7 +1653,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1688,7 +1704,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1713,23 +1729,27 @@ msgid "Move Favorite Down"
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
+msgid "Go to previous folder."
msgstr ""
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
+msgid "Go to next folder."
msgstr ""
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr ""
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -1962,6 +1982,10 @@ msgstr ""
msgid "Clear Output"
msgstr ""
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2258,6 +2282,14 @@ msgid "Pick a Main Scene"
msgstr ""
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2351,6 +2383,10 @@ msgstr ""
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2404,6 +2440,10 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2431,20 +2471,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2477,24 +2513,32 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2574,12 +2618,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2595,14 +2639,6 @@ 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 ""
@@ -2623,14 +2659,14 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr ""
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2638,12 +2674,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2915,6 +2952,10 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3076,7 +3117,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3093,6 +3134,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3154,12 +3199,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3173,13 +3216,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3264,19 +3311,11 @@ msgstr ""
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3309,11 +3348,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3372,6 +3411,10 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr ""
@@ -3435,6 +3478,10 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3495,6 +3542,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3502,12 +3557,20 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3520,11 +3583,11 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
+msgid "Group Editor"
msgstr ""
#: editor/groups_editor.cpp
@@ -3731,7 +3794,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4473,10 +4536,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4489,14 +4548,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4537,6 +4624,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4565,13 +4656,15 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4579,7 +4672,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4592,7 +4685,7 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+msgid "Support"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4604,6 +4697,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr ""
@@ -4654,31 +4751,31 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4758,6 +4855,10 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4786,6 +4887,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4806,14 +4908,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr ""
@@ -4837,6 +4942,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4853,11 +4959,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4870,6 +4971,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5077,16 +5183,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5397,14 +5493,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5488,19 +5576,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5827,7 +5919,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -5933,11 +6024,7 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -5961,7 +6048,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6042,6 +6129,10 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6079,11 +6170,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6171,6 +6262,10 @@ msgstr ""
msgid "Search Results"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6237,6 +6332,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6271,92 +6367,96 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
+msgid "Fold/Unfold Line"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
+msgid "Fold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
+msgid "Unfold All Lines"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
+msgid "Clone Down"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold/Unfold Line"
+msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Fold All Lines"
+msgid "Evaluate Selection"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Unfold All Lines"
+msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Clone Down"
+msgid "Convert Indent to Spaces"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Complete Symbol"
+msgid "Convert Indent to Tabs"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Trim Trailing Whitespace"
+msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Spaces"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Convert Indent to Tabs"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Auto Indent"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Function..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Function..."
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Line..."
+msgid "Remove All Breakpoints"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6534,7 +6634,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6590,7 +6694,7 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
+msgid "Enable Doppler"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6644,7 +6748,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6655,27 +6759,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6719,26 +6803,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6793,7 +6857,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7086,10 +7150,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7174,11 +7234,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7283,14 +7343,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7304,8 +7356,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7584,6 +7636,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7660,6 +7716,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr ""
@@ -7680,6 +7741,10 @@ msgid "Light"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr ""
@@ -7752,6 +7817,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7759,10 +7840,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -7851,7 +7966,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7859,7 +7974,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7871,7 +7986,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7888,7 +8003,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7957,11 +8072,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7977,7 +8092,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7988,7 +8103,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -7997,7 +8112,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8005,11 +8120,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8049,11 +8164,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8062,7 +8181,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8080,15 +8199,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8137,7 +8256,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8152,6 +8271,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8165,19 +8288,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8186,7 +8309,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8195,14 +8318,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8247,47 +8370,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8454,6 +8584,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8600,6 +8734,14 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8669,8 +8811,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8690,7 +8832,7 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
+msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
@@ -8714,10 +8856,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9051,6 +9189,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9103,14 +9245,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9396,6 +9530,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9438,6 +9576,10 @@ msgid "Extend Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9509,19 +9651,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9612,6 +9754,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9640,7 +9786,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -9800,6 +9946,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10210,10 +10360,26 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10398,10 +10564,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11131,22 +11293,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11159,6 +11305,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 2675f9b850..1b847414c4 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -64,7 +64,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "ฟรี"
@@ -141,6 +140,31 @@ msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸­à¸™
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "เคลื่อนย้ายà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "à¹à¸à¹‰à¹„ขค่าคีย์เฟรมà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
@@ -663,17 +687,18 @@ msgid "Line Number:"
msgstr "บรรทัดที่:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "à¹à¸—นที่à¹à¸¥à¹‰à¸§ %d ครั้ง"
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "ไม่พบ"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "à¹à¸—นที่à¹à¸¥à¹‰à¸§ %d ครั้ง"
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "ตรงตามอัà¸à¸©à¸£à¸žà¸´à¸¡à¸žà¹Œà¹€à¸¥à¹‡à¸-ใหà¸à¹ˆ"
@@ -911,8 +936,7 @@ msgstr "ที่ชื่นชอบ:"
msgid "Recent:"
msgstr "ล่าสุด:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1015,7 +1039,7 @@ msgstr ""
"มีรีซอร์สอื่นต้องà¸à¸²à¸£à¹„ฟล์ที่à¸à¸³à¸¥à¸±à¸‡à¸¥à¸š\n"
"ยืนยันจะลบหรือไม่? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่ได้)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "ไม่สามารถลบ:"
@@ -1053,7 +1077,7 @@ msgstr "ลบ %d ไฟล์ถาวร? (ย้อนà¸à¸¥à¸±à¸šà¹„ม่à¹
msgid "Show Dependencies"
msgstr "à¸à¸²à¸£à¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าของ"
@@ -1142,14 +1166,16 @@ msgid "License"
msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•à¹„ลบรารี"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine อาศัยไลบรารีต่าง ๆ ที่นำมาใช้ได้อย่างเสรีà¹à¸¥à¸°à¹€à¸›à¸´à¸”เผยโค้ดเป็นจำนวนมาภ"
@@ -1169,7 +1195,8 @@ msgid "Licenses"
msgstr "สัà¸à¸à¸²à¸­à¸™à¸¸à¸à¸²à¸•"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ, ไม่ใช่รูปà¹à¸šà¸š zip"
#: editor/editor_asset_installer.cpp
@@ -1187,7 +1214,6 @@ msgid "Success!"
msgstr "สำเร็จ!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "ติดตั้ง"
@@ -1684,12 +1710,11 @@ msgid "New"
msgstr "ไฟล์ใหม่"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "นำเข้า"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "ส่งออà¸"
@@ -1760,7 +1785,7 @@ msgstr "à¹à¸ªà¸”งในตัวจัดà¸à¸²à¸£à¹„ฟล์"
msgid "New Folder..."
msgstr "สร้างโฟลเดอร์..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "รีเฟรช"
@@ -1811,7 +1836,7 @@ msgstr "ไปหน้า"
msgid "Go Up"
msgstr "ขึ้นบน"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "เปิด/ปิดไฟล์ที่ซ่อน"
@@ -1837,27 +1862,32 @@ msgstr "เลื่อนโฟลเดอร์ที่ชอบลง"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "ไปชั้นล่าง"
+msgid "Go to previous folder."
+msgstr "ไปยังโฟลเดอร์หลัà¸"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "ไปชั้นบน"
+msgid "Go to next folder."
+msgstr "ไปยังโฟลเดอร์หลัà¸"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "ไปยังโฟลเดอร์หลัà¸"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "ค้นหาคลาส"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "ไม่สามารถสร้างโฟลเดอร์"
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "เปิด/ปิดไฟล์ที่ซ่อน"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2113,6 +2143,11 @@ msgstr "ลบ"
msgid "Clear Output"
msgstr "ลบข้อความ"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "หน้าต่าง"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2425,6 +2460,15 @@ msgid "Pick a Main Scene"
msgstr "เลือà¸à¸‰à¸²à¸à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "ปิดไฟล์ฉาà¸"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "ปิดไฟล์ฉาà¸"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "ไม่สามารถเปิดใช้งานปลั๊à¸à¸­à¸´à¸™: '%s'"
@@ -2532,6 +2576,11 @@ msgstr "เล่น"
msgid "Close Tab"
msgstr "ปิดà¹à¸—็บอื่น"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "ปิดà¹à¸—็บอื่น"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "ปิดà¹à¸—็บอื่น"
@@ -2586,6 +2635,11 @@ msgid "Go to previously opened scene."
msgstr "ไปยังฉาà¸à¸—ี่เพิ่งเปิด"
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "คัดลอà¸à¸•à¸³à¹à¸«à¸™à¹ˆà¸‡"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "à¹à¸—็บถัดไป"
@@ -2613,6 +2667,10 @@ msgstr "สืบทอดฉาà¸à¹ƒà¸«à¸¡à¹ˆ..."
msgid "Open Scene..."
msgstr "เปิดไฟล์ฉาà¸..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "เปิดไฟล์ล่าสุด"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "บันทึà¸à¸‰à¸²à¸"
@@ -2623,14 +2681,6 @@ msgid "Save All Scenes"
msgstr "บันทึà¸à¸—ุà¸à¸‰à¸²à¸"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "ปิดไฟล์ฉาà¸"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "เปิดไฟล์ล่าสุด"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™..."
@@ -2660,26 +2710,36 @@ msgstr "คืนà¸à¸¥à¸±à¸šà¸‰à¸²à¸"
msgid "Miscellaneous project or scene-wide tools."
msgstr "โปรเจà¸à¸•à¹Œà¹à¸¥à¸°à¹€à¸„รื่องมืออื่น ๆ"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "โปรเจà¸à¸•à¹Œ"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "ตัวเลือà¸à¹‚ปรเจà¸à¸•à¹Œ"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "เครื่องมือ"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "ส่งออà¸..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "เปิดตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•à¹Œ?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "เครื่องมือ"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าของ"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2765,12 +2825,13 @@ msgstr ""
"เมื่อเปิดตัวเลือà¸à¸™à¸µà¹‰ สคริปต์ที่บันทึà¸à¸ˆà¸°à¹‚หลดในเà¸à¸¡à¸—ันที\n"
"ถ้าใช้à¸à¸±à¸šà¸­à¸¸à¸›à¸à¸£à¸“์รีโมท จะดีà¸à¸§à¹ˆà¸²à¸–้าเปิดระบบไฟล์เครือข่ายด้วย"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "โปรà¹à¸à¸£à¸¡"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
#: editor/editor_node.cpp
@@ -2788,15 +2849,6 @@ 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 "สลับเต็มจอ"
@@ -2821,14 +2873,15 @@ msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "ช่วยเหลือ"
@@ -2836,12 +2889,13 @@ msgstr "ช่วยเหลือ"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "ค้นหา"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "คู่มือ"
@@ -3123,6 +3177,11 @@ msgstr "เวลา"
msgid "Calls"
msgstr "จำนวนครั้ง"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "à¹à¸à¹‰à¹„ขธีม..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "เปิด"
@@ -3293,7 +3352,8 @@ msgid "Import From Node:"
msgstr "นำเข้าจาà¸à¹‚หนด:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "ดาวน์โหลดอีà¸à¸„รั้ง"
#: editor/export_template_manager.cpp
@@ -3310,6 +3370,10 @@ msgid "Download"
msgstr "ดาวน์โหลด"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(ไม่พบ)"
@@ -3372,12 +3436,10 @@ msgid "No response."
msgstr "ไม่มีà¸à¸²à¸£à¸•à¸­à¸šà¸à¸¥à¸±à¸š"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "ร้องขอผิดพลาด"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "เปลี่ยนทางมาà¸à¹€à¸à¸´à¸™à¹„ป"
@@ -3391,13 +3453,19 @@ msgid "Download Complete."
msgstr "ดาวน์โหลดเสร็จสิ้น"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "ผิดพลาดขณะร้องขอที่อยู่: "
#: editor/export_template_manager.cpp
@@ -3485,20 +3553,12 @@ msgstr "ดาวน์โหลดà¹à¸¡à¹ˆà¹à¸šà¸š"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "เลือà¸à¸¥à¸´à¸‡à¸à¹Œà¸”าวน์โหลด: "
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr "เปิดไฟล์ file_type_cache.cch เพื่อเขียนไม่ได้ จะไม่บันทึà¸à¹à¸„ชของชนิดไฟล์!"
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "ที่ชื่นชอบ:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "ไม่สามารถไปยัง '%s' เนื่องจาà¸à¹„ม่พบในระบบ!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "สถานะ: นำเข้าไฟล์ล้มเหลว à¸à¸£à¸¸à¸“าà¹à¸à¹‰à¹„ขไฟล์à¹à¸¥à¸°à¸™à¸³à¹€à¸‚้าใหม่"
@@ -3532,14 +3592,14 @@ msgid "Provided name contains invalid characters."
msgstr "ไม่สามารถใช้อัà¸à¸©à¸£à¸šà¸²à¸‡à¸•à¸±à¸§à¹ƒà¸™à¸Šà¸·à¹ˆà¸­à¹„ด้"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "อัà¸à¸©à¸£à¸šà¸²à¸‡à¸•à¸±à¸§à¹ƒà¸Šà¹‰à¹„ม่ได้"
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "มีชื่อà¸à¸¥à¸¸à¹ˆà¸¡à¸™à¸µà¹‰à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§"
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "อัà¸à¸©à¸£à¸šà¸²à¸‡à¸•à¸±à¸§à¹ƒà¸Šà¹‰à¹„ม่ได้"
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "เปลี่ยนชื่อไฟล์:"
@@ -3599,6 +3659,11 @@ msgstr "ทำซ้ำ..."
msgid "Move To..."
msgstr "ย้ายไป..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "ฉาà¸à¹ƒà¸«à¸¡à¹ˆ"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3673,6 +3738,11 @@ msgstr "มีโฟลเดอร์ชื่อเดียวà¸à¸±à¸™à¸­à¸¢
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "สร้างจาà¸à¸‰à¸²à¸"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "สร้างสคริปต์"
@@ -3742,6 +3812,14 @@ msgid "Search complete"
msgstr "ค้นหาคำ"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "เพิ่มไปยังà¸à¸¥à¸¸à¹ˆà¸¡"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "ลบออà¸à¸ˆà¸²à¸à¸à¸¥à¸¸à¹ˆà¸¡"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "ผิดพลาด: มีชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!"
@@ -3751,13 +3829,23 @@ msgstr "ผิดพลาด: มีชื่อà¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à
msgid "Invalid group name."
msgstr "ชื่อผิดพลาด"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "à¸à¸¥à¸¸à¹ˆà¸¡"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "ลบเลย์เอาต์"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "à¸à¸¥à¸¸à¹ˆà¸¡"
#: editor/groups_editor.cpp
#, fuzzy
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr "เพิ่มไปยังà¸à¸¥à¸¸à¹ˆà¸¡"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3771,12 +3859,13 @@ msgid "Nodes in Group"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸¥à¸¸à¹ˆà¸¡"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "เพิ่มไปยังà¸à¸¥à¸¸à¹ˆà¸¡"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "ลบออà¸à¸ˆà¸²à¸à¸à¸¥à¸¸à¹ˆà¸¡"
+#, fuzzy
+msgid "Group Editor"
+msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์"
#: editor/groups_editor.cpp
#, fuzzy
@@ -3987,7 +4076,8 @@ msgid "MultiNode Set"
msgstr "à¸à¸³à¸«à¸™à¸” MultiNode"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "เลือà¸à¹‚หนดเพื่อà¹à¸à¹‰à¹„ขสัà¸à¸à¸²à¸“à¹à¸¥à¸°à¸à¸¥à¸¸à¹ˆà¸¡"
#: editor/plugin_config_dialog.cpp
@@ -4794,10 +4884,6 @@ msgid "View Files"
msgstr "ดูไฟล์"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "ไม่พบตำà¹à¸«à¸™à¹ˆà¸‡à¸™à¸µà¹‰:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "เชื่อมต่อไม่ได้ à¸à¸£à¸¸à¸“าลองใหม่"
@@ -4810,14 +4896,47 @@ msgid "No response from host:"
msgstr "ไม่มีà¸à¸²à¸£à¸•à¸­à¸šà¸à¸¥à¸±à¸šà¸ˆà¸²à¸à¹‚ฮสต์:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "ไม่พบตำà¹à¸«à¸™à¹ˆà¸‡à¸™à¸µà¹‰:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "à¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อผิดพลาด รหัส:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "ร้องขอผิดพลาด"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "à¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อผิดพลาด เปลี่ยนทางมาà¸à¹€à¸à¸´à¸™à¹„ป"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "เปลี่ยนทางมาà¸à¹€à¸à¸´à¸™à¹„ป"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "à¸à¸²à¸£à¸£à¹‰à¸­à¸‡à¸‚อผิดพลาด รหัส:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "เวลา"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "à¹à¸®à¸Šà¸œà¸´à¸”พลาด ไฟล์ดาวน์โหลดอาจเสียหาย"
@@ -4860,6 +4979,11 @@ msgid "Idle"
msgstr "พร้อมใช้งาน"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "ติดตั้ง"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "ลองใหม่"
@@ -4890,13 +5014,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "ทั้งหมด"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "นำเข้าอีà¸à¸„รั้ง..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "ปลั๊à¸à¸­à¸´à¸™"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4904,8 +5032,9 @@ msgid "Sort:"
msgstr "เรียงตาม:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "ย้อนà¸à¸¥à¸±à¸š"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸£à¹‰à¸­à¸‡à¸‚อ..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4917,7 +5046,8 @@ msgid "Site:"
msgstr "ไซต์:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "à¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4929,6 +5059,11 @@ msgid "Testing"
msgstr "ทดสอบ"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "โหลด"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ไฟล์ ZIP"
@@ -4982,31 +5117,38 @@ msgid "Rotation Step:"
msgstr "ช่วงองศา:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "เลื่อนเส้นนำà¹à¸™à¸§à¸•à¸±à¹‰à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "สร้างเส้นนำà¹à¸™à¸§à¸•à¸±à¹‰à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "ลบเส้นนำà¹à¸™à¸§à¸•à¸±à¹‰à¸‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "เลื่อนเส้นนำà¹à¸™à¸§à¸™à¸­à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "สร้างเส้นนำà¹à¸™à¸§à¸™à¸­à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "ลบเส้นนำà¹à¸™à¸§à¸™à¸­à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "สร้างเส้นนำà¹à¸™à¸§à¸•à¸±à¹‰à¸‡à¹à¸¥à¸°à¹à¸™à¸§à¸™à¸­à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5097,6 +5239,11 @@ msgstr "วางท่าทาง"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "ลบท่าทาง"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "สร้างจุดปะทุจาภMesh"
@@ -5127,6 +5274,7 @@ msgid "Zoom Reset"
msgstr "รีเซ็ตà¸à¸²à¸£à¸‹à¸¹à¸¡"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "โหมดเลือà¸"
@@ -5147,14 +5295,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+คลิà¸à¸‚วา: เลือà¸à¸—ี่ซ้อนà¸à¸±à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "โหมดเคลื่อนย้าย"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "โหมดหมุน"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "โหมดปรับขนาด (R)"
@@ -5182,6 +5333,7 @@ msgid "Toggle snapping."
msgstr "เปิด/ปิด à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
@@ -5200,11 +5352,6 @@ msgid "Use Rotation Snap"
msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¸«à¸¡à¸¸à¸™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "ตั้งค่าà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "จำà¸à¸±à¸”โดยใช้ตำà¹à¸«à¸™à¹ˆà¸‡à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™"
@@ -5218,6 +5365,11 @@ msgid "Smart Snapping"
msgstr "จำà¸à¸±à¸”อัตโนมัติ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "ตั้งค่าà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "จำà¸à¸±à¸”ด้วยโหนดà¹à¸¡à¹ˆ"
@@ -5443,16 +5595,6 @@ msgstr "ปรับขนาดรูปร่าง"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "ผิดพลาดขณะโหลดรูป:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "รูปไม่มีพิà¸à¹€à¸‹à¸¥à¹ƒà¸”ที่ความโปร่งà¹à¸ªà¸‡ > 128 ..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "โหลด Mask à¸à¸²à¸£à¸›à¸°à¸—ุ"
@@ -5775,14 +5917,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "พื้นผิวต้นฉบับไม่ถูà¸à¸•à¹‰à¸­à¸‡ (ไม่มีหน้า)"
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "โหนดà¹à¸¡à¹ˆà¹„ม่มีพื้นผิวเพื่อสร้าง"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "ไม่สามารถวางพื้นที่"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "เลือภMesh ต้นฉบับ:"
@@ -5868,20 +6002,27 @@ msgid "Generation Time (sec):"
msgstr "เวลาในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡ (วินาที):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "หน้าไม่มีพื้นที่!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "ไม่มีหน้า!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "โหนดไม่มี geometry (หน้า)"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "โหนดไม่มี geometry"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "โหนดไม่มี geometry (หน้า)"
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "โหนดไม่มี geometry"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6223,7 +6364,6 @@ msgid "Grid Settings"
msgstr "à¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่า GridMap"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸„ลื่อนย้าย"
@@ -6338,13 +6478,8 @@ msgstr "ผิดพลาดขณะย้ายไฟล์:\n"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "โหลดภาพไม่ได้"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
-msgstr "โหลดภาพไม่ได้"
+msgid "Could not load file at:"
+msgstr "ไม่พบ tile:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6373,7 +6508,7 @@ msgstr "ผิดพลาดขณะนำเข้า"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "สร้างโฟลเดอร์..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6460,6 +6595,11 @@ msgid "Open..."
msgstr "เปิด"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "เปิดสคริปต์"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "บันทึà¸à¸—ั้งหมด"
@@ -6499,13 +6639,13 @@ msgid "Save Theme"
msgstr "บันทึà¸à¸˜à¸µà¸¡"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "ปิดคู่มือ"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "ปิดทั้งหมด"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "ปิดคู่มือ"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "รัน"
@@ -6596,6 +6736,11 @@ msgstr "ตัวà¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸­à¸‡"
msgid "Search Results"
msgstr "ค้นหาในคู่มือ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ล้างรายà¸à¸²à¸£à¸‰à¸²à¸à¸¥à¹ˆà¸²à¸ªà¸¸à¸”"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6670,6 +6815,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6705,26 +6851,6 @@ msgid "Toggle Comment"
msgstr "เปิด/ปิด ความคิดเห็น"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "เปิด/ปิดมุมมองอิสระ"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "ไปจุดพัà¸à¸–ัดไป"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "ไปจุดพัà¸à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "ลบทั้งหมด"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "ซ่อน/à¹à¸ªà¸”งบรรทัด"
@@ -6745,6 +6871,11 @@ msgid "Complete Symbol"
msgstr "เสนอà¹à¸™à¸°à¸„ำเต็ม"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "ปรับอัตราส่วนเวลาคีย์ที่เลือà¸"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "ลบตัวอัà¸à¸©à¸£à¸—ี่มองไม่เห็น"
@@ -6763,32 +6894,37 @@ msgid "Auto Indent"
msgstr "ย่อหน้าอัตโนมัติ"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "เปิด/ปิด จุดพัà¸à¹‚ปรà¹à¸à¸£à¸¡"
+msgid "Find Previous"
+msgstr "ค้นหาà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "ลบจุดพัà¸à¸—ั้งหมด"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "คัดà¸à¸£à¸­à¸‡à¹„ฟล์..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "ค้นหาคำที่เลือà¸à¹ƒà¸™à¸„ู่มือ"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "ไปจุดพัà¸à¸–ัดไป"
+msgid "Toggle Bookmark"
+msgstr "เปิด/ปิดมุมมองอิสระ"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "ไปจุดพัà¸à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
+msgid "Go to Next Bookmark"
+msgstr "ไปจุดพัà¸à¸–ัดไป"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "ค้นหาà¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "ไปจุดพัà¸à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "คัดà¸à¸£à¸­à¸‡à¹„ฟล์..."
+msgid "Remove All Bookmarks"
+msgstr "ลบทั้งหมด"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6801,8 +6937,23 @@ msgid "Go to Line..."
msgstr "ไปยังบรรทัด..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "ค้นหาคำที่เลือà¸à¹ƒà¸™à¸„ู่มือ"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "เปิด/ปิด จุดพัà¸à¹‚ปรà¹à¸à¸£à¸¡"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "ลบจุดพัà¸à¸—ั้งหมด"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "ไปจุดพัà¸à¸–ัดไป"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "ไปจุดพัà¸à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6989,9 +7140,14 @@ msgstr "หลัง"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "ย้ายมาที่à¸à¸¥à¹‰à¸­à¸‡"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "ย้ายวัตถุที่เลือà¸à¸¡à¸²à¸—ี่à¸à¸¥à¹‰à¸­à¸‡"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "ไม่พบโหนดà¹à¸¡à¹ˆà¸—ี่จะรับอินสà¹à¸•à¸™à¸‹à¹Œà¹‚หนดลูà¸"
@@ -7046,8 +7202,9 @@ msgid "Audio Listener"
msgstr "ตัวรับเสียง"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "เปิดดอปเพลอร์"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸à¹„ด้"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7103,8 +7260,8 @@ msgid "Snap Nodes To Floor"
msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "โหมดเลือภ(Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7117,30 +7274,11 @@ msgstr ""
"Alt+คลิà¸à¸‚วา: เลือà¸à¸—ี่ซ้อนà¸à¸±à¸™"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "โหมดเคลื่อนย้าย (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "โหมดหมุน (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "โหมดปรับขนาด (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "พิà¸à¸±à¸”ภายใน"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "โหมดพิà¸à¸±à¸”ภายใน (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "โหมดà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸” (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "มุมล่าง"
@@ -7182,26 +7320,6 @@ msgid "Focus Selection"
msgstr "มองวัตถุที่เลือà¸"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "ย้ายวัตถุที่เลือà¸à¸¡à¸²à¸—ี่à¸à¸¥à¹‰à¸­à¸‡"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "เครื่องมือเลือà¸"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "เครื่องมือย้าย"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "เครื่องมือหมุน"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "เครื่องมือปรับขนาด"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "เปิด/ปิดมุมมองอิสระ"
@@ -7258,7 +7376,8 @@ msgstr "à¹à¸ªà¸”งเส้นตาราง"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "ตัวเลือà¸"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7577,10 +7696,6 @@ msgid "TextureRegion"
msgstr "ขอบเขต Texture"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "เพิ่มทุà¸à¹„อเทม"
@@ -7672,12 +7787,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "ไอเทม"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "ไอเทม"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7788,14 +7903,6 @@ msgid "Transpose"
msgstr "สลับà¹à¸à¸™"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "สะท้อนซ้ายขวา"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "สะท้อนบนล่าง"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "Autotiles"
@@ -7811,8 +7918,8 @@ msgstr "วาด Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8139,6 +8246,10 @@ msgid "TileSet"
msgstr "Tile Set"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "เพิ่มอินพุต"
@@ -8231,6 +8342,11 @@ msgid "Duplicate Nodes"
msgstr "ทำซ้ำโหนด"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "วางโหนด"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "ลบโหนด"
@@ -8256,6 +8372,11 @@ msgstr "ขวา"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "สร้างโหนด"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "สร้างโหนด"
@@ -8334,6 +8455,22 @@ msgid "Color uniform."
msgstr "เคลื่อนย้าย"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8341,10 +8478,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "à¹à¸à¹‰à¹„ขค่าคงที่เวà¸à¹€à¸•à¸­à¸£à¹Œ"
@@ -8437,7 +8608,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8445,7 +8616,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8457,7 +8628,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8474,7 +8645,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8543,11 +8714,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8563,7 +8734,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8574,7 +8745,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8583,7 +8754,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8591,11 +8762,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8638,12 +8809,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "à¹à¸à¹‰à¹„ข Texture Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "à¹à¸à¹‰à¹„ข Texture Uniform"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "à¹à¸à¹‰à¹„ข Texture Uniform"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8653,7 +8829,7 @@ msgstr "เครื่องมือเคลื่อนย้าย..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8671,15 +8847,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8732,7 +8908,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8747,6 +8923,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8760,19 +8940,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8781,7 +8961,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8790,14 +8970,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8844,47 +9024,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9061,6 +9248,10 @@ msgid "Export templates for this platform are missing:"
msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸žà¸¥à¸•à¸Ÿà¸­à¸£à¹Œà¸¡à¸™à¸µà¹‰:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸­à¸­à¸"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "ส่งออà¸à¸žà¸£à¹‰à¸­à¸¡à¸à¸²à¸£à¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸­à¸‡"
@@ -9213,6 +9404,15 @@ msgstr "โปรเจà¸à¸•à¹Œà¹„ม่มีชื่อ"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "นำเข้าโปรเจà¸à¸•à¹Œà¸—ี่มีอยู่เดิม"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "ไม่สามารถเปิดโปรเจà¸à¸•à¹Œ"
@@ -9291,8 +9491,8 @@ msgstr "ลบโปรเจà¸à¸•à¹Œà¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­? (
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "ลบโปรเจà¸à¸•à¹Œà¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­? (โฟลเดอร์จะไม่ถูà¸à¸¥à¸š)"
#: editor/project_manager.cpp
@@ -9316,8 +9516,9 @@ msgid "Project Manager"
msgstr "ตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•à¹Œ"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "รายชื่อโปรเจà¸à¸•à¹Œ"
+#, fuzzy
+msgid "Projects"
+msgstr "โปรเจà¸à¸•à¹Œ"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9341,10 +9542,6 @@ msgid "Templates"
msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "ออà¸"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "เริ่มใหม่ทันที"
@@ -9691,6 +9888,10 @@ msgstr "ภูมิภาค:"
msgid "AutoLoad"
msgstr "ออโต้โหลด"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "ปลั๊à¸à¸­à¸´à¸™"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "ศูนย์"
@@ -9743,14 +9944,6 @@ msgstr "เลือà¸à¹€à¸¡à¸—็อด"
msgid "Select Method"
msgstr "เลือà¸à¹€à¸¡à¸—็อด"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "ใช้เครื่องมือ PVRTC ไม่ได้:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "โหลดรูปที่à¹à¸›à¸¥à¸‡à¹à¸¥à¹‰à¸§à¸”้วยเครื่องมือ PVRTC ไม่ได้:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10056,6 +10249,11 @@ msgid "Remove Node(s)"
msgstr "ลบโหนด"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "เปลี่ยนชื่ออินพุต"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10102,6 +10300,11 @@ msgstr "เปิดสคริปต์"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "หาโหนดà¹à¸¡à¹ˆà¹ƒà¸«à¸¡à¹ˆ"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "เข้าใจ!"
@@ -10179,23 +10382,25 @@ msgstr "คำเตือนà¸à¸²à¸£à¸•à¸±à¹‰à¸‡à¸„่าโหนด:"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"โหนดมีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยงà¹à¸¥à¸°à¸à¸¥à¸¸à¹ˆà¸¡\n"
"คลิà¸à¹€à¸žà¸·à¹ˆà¸­à¹à¸ªà¸”งà¹à¸œà¸‡à¸ªà¸±à¸à¸à¸²à¸“"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"โหนดมีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚ยง\n"
"คลิà¸à¹€à¸žà¸·à¹ˆà¸­à¹à¸ªà¸”งà¹à¸œà¸‡à¸ªà¸±à¸à¸à¸²à¸“"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"โหนดอยู่ในà¸à¸¥à¸¸à¹ˆà¸¡\n"
@@ -10302,6 +10507,11 @@ msgid "Error loading script from %s"
msgstr "ผิดพลาดขณะโหลดสคริปต์จาภ%s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..."
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "ไม่มี"
@@ -10336,7 +10546,8 @@ msgid "Script is valid."
msgstr "สคริปต์ถูà¸à¸•à¹‰à¸­à¸‡"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "อัà¸à¸‚ระที่ใช้ได้: a-z, A-Z, 0-9 à¹à¸¥à¸° _"
#: editor/script_create_dialog.cpp
@@ -10503,6 +10714,10 @@ msgid "Change Shortcut"
msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸•à¸£à¸¶à¸‡"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "ตัวเลือà¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "ทางลัด"
@@ -10926,10 +11141,30 @@ msgid "Set Variable Type"
msgstr "à¹à¸à¹‰à¹„ขประเภทตัวà¹à¸›à¸£"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "ชื่อผิดพลาด ต้องไม่ใช้ชื่อเดียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "สร้าง %s ใหม่"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "ตัวà¹à¸›à¸£:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "สร้าง %s ใหม่"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "สร้างรูปหลายเหลี่ยมจาà¸à¸„วามว่างเปล่า"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "ไม่สามารถใช้ชื่อนี้ได้:"
@@ -11118,10 +11353,6 @@ msgid "Cut Nodes"
msgstr "ตัดโหนด"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "วางโหนด"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "ตัวà¹à¸›à¸£"
@@ -11924,22 +12155,6 @@ msgstr ""
"ให้à¹à¸à¹‰à¹„ขโหนดนี้ให้เป็นโหนดลูà¸à¸‚อง Control à¹à¸•à¹ˆà¸–้าไม่ ให้ปรับเป็น render target à¹à¸¥à¸°à¸™à¸³à¹„ปใช้เป็น "
"texture ของโหนดอื่น"
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "ผิดพลาดขณะเริ่มต้น FreeType"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "ไม่ทราบประเภทของฟอนต์"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "ผิดพลาดขณะโหลดฟอนต์"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "ขนาดฟอนต์ผิดพลาด"
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11955,6 +12170,11 @@ msgstr "ต้นฉบับไม่ถูà¸à¸•à¹‰à¸­à¸‡!"
msgid "Invalid source for shader."
msgstr "ต้นฉบับไม่ถูà¸à¸•à¹‰à¸­à¸‡!"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "ต้นฉบับไม่ถูà¸à¸•à¹‰à¸­à¸‡!"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11971,6 +12191,123 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr "เปิดไฟล์ file_type_cache.cch เพื่อเขียนไม่ได้ จะไม่บันทึà¸à¹à¸„ชของชนิดไฟล์!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "ไม่สามารถไปยัง '%s' เนื่องจาà¸à¹„ม่พบในระบบ!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "ผิดพลาดขณะโหลดรูป:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "รูปไม่มีพิà¸à¹€à¸‹à¸¥à¹ƒà¸”ที่ความโปร่งà¹à¸ªà¸‡ > 128 ..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "โหนดà¹à¸¡à¹ˆà¹„ม่มีพื้นผิวเพื่อสร้าง"
+
+#~ msgid "Couldn't map area."
+#~ msgstr "ไม่สามารถวางพื้นที่"
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "หน้าไม่มีพื้นที่!"
+
+#~ msgid "No faces!"
+#~ msgstr "ไม่มีหน้า!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "โหลดภาพไม่ได้"
+
+#, fuzzy
+#~ msgid "Error could not load file."
+#~ msgstr "โหลดภาพไม่ได้"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "เปิดดอปเพลอร์"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "โหมดเลือภ(Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "โหมดเคลื่อนย้าย (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "โหมดหมุน (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "โหมดปรับขนาด (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "พิà¸à¸±à¸”ภายใน"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "โหมดà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸” (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "เครื่องมือเลือà¸"
+
+#~ msgid "Tool Move"
+#~ msgstr "เครื่องมือย้าย"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "เครื่องมือหมุน"
+
+#~ msgid "Tool Scale"
+#~ msgstr "เครื่องมือปรับขนาด"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "ลบโปรเจà¸à¸•à¹Œà¸­à¸­à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­? (โฟลเดอร์จะไม่ถูà¸à¸¥à¸š)"
+
+#~ msgid "Project List"
+#~ msgstr "รายชื่อโปรเจà¸à¸•à¹Œ"
+
+#~ msgid "Exit"
+#~ msgstr "ออà¸"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "ใช้เครื่องมือ PVRTC ไม่ได้:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "โหลดรูปที่à¹à¸›à¸¥à¸‡à¹à¸¥à¹‰à¸§à¸”้วยเครื่องมือ PVRTC ไม่ได้:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "ผิดพลาดขณะเริ่มต้น FreeType"
+
+#~ msgid "Unknown font format."
+#~ msgstr "ไม่ทราบประเภทของฟอนต์"
+
+#~ msgid "Error loading font."
+#~ msgstr "ผิดพลาดขณะโหลดฟอนต์"
+
+#~ msgid "Invalid font size."
+#~ msgstr "ขนาดฟอนต์ผิดพลาด"
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "ไปชั้นล่าง"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "ไปชั้นบน"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป"
+
+#~ msgid "Reverse"
+#~ msgstr "ย้อนà¸à¸¥à¸±à¸š"
+
+#~ msgid "Mirror X"
+#~ msgstr "สะท้อนซ้ายขวา"
+
+#~ msgid "Mirror Y"
+#~ msgstr "สะท้อนบนล่าง"
+
#~ msgid "Generating solution..."
#~ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ solution..."
@@ -12549,9 +12886,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "ลบที่เลือà¸"
-#~ msgid "Could not find tile:"
-#~ msgstr "ไม่พบ tile:"
-
#~ msgid "Item name or ID:"
#~ msgstr "ชื่อหรือ ID ไอเทม:"
@@ -12802,9 +13136,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "ข้อมูล"
-#~ msgid "Re-Import..."
-#~ msgstr "นำเข้าอีà¸à¸„รั้ง..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "ไม่มีบิตà¹à¸¡à¸ªà¸à¹Œà¹ƒà¸«à¹‰à¸™à¸³à¹€à¸‚้า!"
@@ -13180,9 +13511,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "สเตอริโอ"
-#~ msgid "Window"
-#~ msgstr "หน้าต่าง"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "ปรับขนาดเป็น %s%%"
@@ -13459,8 +13787,5 @@ msgstr ""
#~ msgid "Export Project PCK"
#~ msgstr "ส่งออภPCK โปรเจà¸à¸•à¹Œ"
-#~ msgid "Export..."
-#~ msgstr "ส่งออà¸..."
-
#~ msgid "Project Export"
#~ msgstr "ส่งออà¸à¹‚ปรเจà¸à¸•à¹Œ"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 406b84b591..afbea77509 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -28,12 +28,13 @@
# Anton Semchenko <semchenkoanton@protonmail.com>, 2019.
# Enes Can Yerlikaya <enescanyerlikaya@gmail.com>, 2019.
# Ömer Akgöz <omerakgoz34@gmail.com>, 2019.
+# Mehmet Dursun <mehmet.dursun@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:47+0000\n"
-"Last-Translator: Ömer Akgöz <omerakgoz34@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:34+0000\n"
+"Last-Translator: Mehmet Dursun <mehmet.dursun@gmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -41,12 +42,14 @@ 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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "convert() için geçersiz argüman tipi, TYPE_* sabitlerini kullanın."
+msgstr ""
+"\"convert ()\" için geçersiz tür bağımsız değişkeni, \"TYPE_ *\" sabitlerini "
+"kullanın."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -56,15 +59,15 @@ msgstr "Byte kodu çözmek için yetersiz byte, ya da geçersiz format."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "İfade de geçersiz girdi %i (geçmedi)."
+msgstr "İfade de geçersiz giriş %i (geçersiz)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "\"self\" ifadesi kullanılamaz, çünkü nesne \"null\" (tanımlandı)."
+msgstr "\"self\" kullanılamaz çünkü \"null\" değerini almış(geçersiz)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
-msgstr "%s, %s ve %s operatörleri için geçersiz işlem."
+msgstr "\"%s\" düğümünde geçersiz işlem '%s' ve '%s'."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
@@ -83,7 +86,6 @@ msgid "On call to '%s':"
msgstr "'%s' çağrıldığında:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Ãœcretsiz"
@@ -152,6 +154,26 @@ msgid "Anim Change Call"
msgstr "Animasyon Değişikliği Çağrısı"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Animasyon Anahtar-Çerçeve Zamanını Değiştir"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Animasyon geçişinin çoklu değişimi"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Animasyon Çoklu Değişikliği Dönüşümü"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Animasyon Çoklu Anahtar-Çerçeve Değerini Değiştir"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Animasyon Çoklu Değişiklik Çağrısı"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Animasyon UzunluÄŸunu DeÄŸiÅŸtir"
@@ -186,11 +208,11 @@ msgstr "Animasyon Oynatıcı İzi"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "Animasyon uzunluÄŸu (kare)"
+msgstr "Animasyon uzunluğu (çerçeve)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr "Animasyon uzunluÄŸu (kare)"
+msgstr "Animasyon uzunluÄŸu (saniye)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
@@ -207,19 +229,19 @@ msgstr "Ä°ÅŸlevler:"
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr "Ses Klipsi:"
+msgstr "Ses Parçası:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr "Animasyon Klipsleri:"
+msgstr "Animasyon Klipleri:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr "Ä°z Yolunu DeÄŸiÅŸtir"
+msgstr "Parça Yolunu Değiştir"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "Bu izi Aç/Kapat."
+msgstr "Bu parçayı Aç/Kapat."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
@@ -227,11 +249,11 @@ msgstr "Güncelleme Kipi (Bu özellik nasıl belirlenir)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
-msgstr "AradeÄŸerleme Kipi"
+msgstr "Ara DeÄŸerleme Kipi"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr "Döngü Örtü Kipi (Döngünün başlangıcını sonu ile aradeğerle)"
+msgstr "Döngü Sarma Kipi (Döngünün başlangıcı ile bitiş arası)"
#: editor/animation_track_editor.cpp
msgid "Remove this track."
@@ -239,7 +261,7 @@ msgstr "Bu izi sil."
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr "Süresi (sn): "
+msgstr "Süre (sn): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -247,11 +269,11 @@ msgstr "İz Dönüştürücü Etkin"
#: editor/animation_track_editor.cpp
msgid "Continuous"
-msgstr "Kesintisiz"
+msgstr "Sürekli"
#: editor/animation_track_editor.cpp
msgid "Discrete"
-msgstr "Kesikli"
+msgstr "Ayrık"
#: editor/animation_track_editor.cpp
msgid "Trigger"
@@ -285,15 +307,15 @@ msgstr "Döngü Aradeğerlemesin Sar"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Anahtar Gir"
+msgstr "Yeni Anahtar"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
-msgstr "Anahtar(lar)ı Çoğalt"
+msgstr "Yinelenen Anahtar(lar)"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
-msgstr "Tuşları Sil"
+msgstr "Anahtar(lar)ı Sil"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
@@ -332,7 +354,7 @@ msgstr "OluÅŸtur"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
-msgstr "Animasyon Gir"
+msgstr "Animasyon Ekle"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
@@ -341,15 +363,15 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
-msgstr "Animasyon OluÅŸtur & Gir"
+msgstr "Animasyon OluÅŸtur & Ekle"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr "Animasyon Ä°z & Anahtar Gir"
+msgstr "Animasyon Ä°z & Anahtar Ekle"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
-msgstr "Animasyon Anahtar Gir"
+msgstr "Animasyon Anahtar Ekle"
#: editor/animation_track_editor.cpp
msgid "Change Animation Step"
@@ -653,17 +675,18 @@ msgid "Line Number:"
msgstr "Satır Numarası:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
+msgstr "DeÄŸiÅŸtirildi %d oluÅŸ(sn)."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+#, fuzzy
+msgid "%d matches."
msgstr "EÅŸleÅŸme Yok"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "DeÄŸiÅŸtirildi %d oluÅŸ(sn)."
-
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
msgstr "Büyük/Küçük Harf Eşleştir"
@@ -892,8 +915,7 @@ msgstr "BeÄŸeniler:"
msgid "Recent:"
msgstr "Yakın zamanda:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -996,7 +1018,7 @@ msgstr ""
"Kaldırılmakta olan dosyalar başka kaynakların çalışması için gerekli.\n"
"Yine de kaldırmak istiyor musunuz? (geri alınamaz)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Kaldırılamadı:"
@@ -1033,7 +1055,7 @@ msgstr "%d Öğeleri kalıcı olarak silsin mi? (Geri alınamaz!)"
msgid "Show Dependencies"
msgstr "Bağımlılıklar"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "Orphan Kaynak Araştırıcı"
@@ -1122,14 +1144,16 @@ msgid "License"
msgstr "Lisans"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Üçüncü Parti Lisans"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Oyun Motoru, bazı ücretsiz ve açık kaynaklı üçüncü parti "
@@ -1150,7 +1174,8 @@ msgid "Licenses"
msgstr "Lisanslar"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Paket dosyası açılamıyor, zip formatında değil."
#: editor/editor_asset_installer.cpp
@@ -1167,7 +1192,6 @@ msgid "Success!"
msgstr "Başarılı!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Kur"
@@ -1666,12 +1690,11 @@ msgid "New"
msgstr "Yeni"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "İçe Aktar"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Dışa Aktar"
@@ -1740,7 +1763,7 @@ msgstr "Dosya Yöneticisinde Göster"
msgid "New Folder..."
msgstr "Yeni Klasör..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Yenile"
@@ -1791,7 +1814,7 @@ msgstr "Ä°leri Git"
msgid "Go Up"
msgstr "Yukarı Git"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Gizli Dosyalari Aç / Kapat"
@@ -1816,25 +1839,32 @@ msgid "Move Favorite Down"
msgstr "Beğenileni Aşağı Taşı"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Önceki Klasör"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Üst klasöre git"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Sonraki Klasör"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Üst klasöre git"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "Üst klasöre git"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Dosyaları ara"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Bu klasörü favorilerden çıkar/favorilere ekle."
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "Gizli Dosyalari Aç / Kapat"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2076,6 +2106,11 @@ msgstr "Temizle"
msgid "Clear Output"
msgstr "Çıktıyı Temizle"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "Pencere"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Proje dışa aktarımı %d hata koduyla başarısız."
@@ -2403,6 +2438,15 @@ msgid "Pick a Main Scene"
msgstr "Bir Ana Sahne Seç"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Sahneyi Kapat"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Sahneyi Kapat"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Şu eklenti etkinleştirilemedi: '%s' yapılandırma ayarlarının ayrıştırılması "
@@ -2515,6 +2559,11 @@ msgstr "Bu Sahneyi Oynat"
msgid "Close Tab"
msgstr "Sekmeyi Kapat"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Sekmeyi Kapat"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "DiÄŸer Sekmeleri Kapat"
@@ -2569,6 +2618,11 @@ msgid "Go to previously opened scene."
msgstr "Daha önce açılan sahneye git."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Dosya Yolunu Tıpkıla"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Sonraki sekme"
@@ -2596,6 +2650,10 @@ msgstr "Yeni Miras Alınmış Sahne ..."
msgid "Open Scene..."
msgstr "Sahne Aç..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "En Sonuncuyu Aç"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Sahne Kaydet"
@@ -2605,14 +2663,6 @@ msgid "Save All Scenes"
msgstr "Tüm Sahneleri Kaydet"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Sahneyi Kapat"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "En Sonuncuyu Aç"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Şuna Dönüştür..."
@@ -2642,25 +2692,35 @@ msgstr "Sahneyi Eski Durumuna Çevir"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Çeşitli proje ya da sahne-çapında araçlar."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Proje"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Proje Ayarları"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Araçlar"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Dışa Aktar..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Proje Verileri Klasörünü Aç"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Araçlar"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Orphan Kaynak Araştırıcı"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2758,12 +2818,13 @@ msgstr ""
"Bir cihazda uzaktan kullanıldığında, ağ dosya sistemi ile bu işlem daha "
"verimli olur."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Düzenleyici"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Düzenleyici Ayarları"
#: editor/editor_node.cpp
@@ -2781,15 +2842,6 @@ 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"
@@ -2812,14 +2864,15 @@ msgstr "Düzenleyici Ayarları Klasörünü Aç"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "Dışa Aktarım Şablonlarını Yönet"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Dışa Aktarım Şablonlarını Yönet"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Yardım"
@@ -2827,12 +2880,13 @@ msgstr "Yardım"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Ara"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Çevrimiçi Belgeler"
@@ -3109,6 +3163,11 @@ msgstr "Zaman"
msgid "Calls"
msgstr "Çağrılar"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "Tema düzenle..."
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Açık"
@@ -3284,7 +3343,8 @@ msgid "Import From Node:"
msgstr "Düğümden İçe Aktar:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Yeniden Yükle"
#: editor/export_template_manager.cpp
@@ -3301,6 +3361,10 @@ msgid "Download"
msgstr "Ä°ndir"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Mevcut DeÄŸil)"
@@ -3364,12 +3428,10 @@ msgid "No response."
msgstr "Cevap yok."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "İstek Başarısız Oldu."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Yönlendirme Döngüsü."
@@ -3383,15 +3445,22 @@ msgid "Download Complete."
msgstr "İndirme Tamamlandı."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Tema dosyaya kaydedilemiyor:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Şablon yüklemesi başarısız oldu. Sorunlu şablon arşivi şurada bulunabilir: "
"'%s'."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Url isteği hatası: "
#: editor/export_template_manager.cpp
@@ -3478,21 +3547,11 @@ msgstr "Şablonları İndir"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Listeden ayna seç: (Shift+Tıkla: Tarayıcıda Aç)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"file_type_cache.cch yazma için açılamıyor! dosya türü önbelleğe "
-"kaydedilmiyor!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Favoriler"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "Gidilemiyor. '%s' bu dosya sisteminde bulunamadı!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"Durum: Dosya içe aktarma başarısız oldu. Lütfen dosyayı onarın ve tekrar içe "
@@ -3528,14 +3587,14 @@ msgid "Provided name contains invalid characters."
msgstr "Sağlanan isim geçersiz karakterler içeriyor"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "İsim geçersiz karkterler içeriyor."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Bu isimde zaten bir dosya ve ya klasör mevcut."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "İsim geçersiz karkterler içeriyor."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Dosya yeniden-adlandırma:"
@@ -3595,6 +3654,11 @@ msgstr "Çoğalt..."
msgid "Move To..."
msgstr "Şuraya Taşı..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Yeni Sahne"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Yeni Betik..."
@@ -3663,6 +3727,11 @@ msgstr "Bu konumda zaten aynı ada sahip bir dosya veya klasör var."
msgid "Overwrite"
msgstr "Ãœzerine Yaz"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Sahneden OluÅŸtur"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Betik OluÅŸtur"
@@ -3723,6 +3792,14 @@ msgid "Search complete"
msgstr "Arama tamamlandı"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Öbeğe Ekle"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Öbekten Kaldır"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Grup adı zaten var."
@@ -3730,12 +3807,23 @@ msgstr "Grup adı zaten var."
msgid "Invalid group name."
msgstr "Geçersiz grup adı."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Grupları Düzenle"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Bediz Öbeğini Sil"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Gruplar"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Düğümler Grupta Değil"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3748,12 +3836,13 @@ msgid "Nodes in Group"
msgstr "Gruptaki Düğümler"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Öbeğe Ekle"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Öbekten Kaldır"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Betik Düzenleyiciyi Aç"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3965,7 +4054,8 @@ msgid "MultiNode Set"
msgstr "MultiNode Kur"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Sinyalleri ve Grupları düzenlemek için bir Düğüm seçin."
#: editor/plugin_config_dialog.cpp
@@ -4756,10 +4846,6 @@ msgid "View Files"
msgstr "Dosyaları Görüntüle"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Ana makine adı çözümlenemedi:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Bağlantı hatası, lütfen tekrar deneyiniz."
@@ -4772,14 +4858,47 @@ msgid "No response from host:"
msgstr "Ana makineden cevap yok:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Ana makine adı çözümlenemedi:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "İstem başarısız, dönen kod:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "İstek Başarısız Oldu."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Tema dosyaya kaydedilemiyor:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "İstem Başarısız, çok fazla yönlendirme"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Yönlendirme Döngüsü."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "İstem başarısız, dönen kod:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Zaman"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "Kötü indirme sağlaması, dosya üzerinde oynama yapılmış."
@@ -4822,6 +4941,11 @@ msgid "Idle"
msgstr "BoÅŸta"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Kur"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Tekrarla"
@@ -4852,13 +4976,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Hepsi"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Yeniden İçe Aktar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Eklentiler"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4866,8 +4994,9 @@ msgid "Sort:"
msgstr "Sırala:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Tersi"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Ä°steniyor..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4879,7 +5008,8 @@ msgid "Site:"
msgstr "Yer:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Destek..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4891,6 +5021,11 @@ msgid "Testing"
msgstr "Deneme"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Yükle..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Varlıkların ZIP Dosyası"
@@ -4948,31 +5083,38 @@ msgid "Rotation Step:"
msgstr "Dönme Adımı:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "Dikey kılavuzu taşı"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "Yeni dikey kılavuz oluştur"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "Dikey kılavuzu kaldır"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "Yatay kılavuzu taşı"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "Yeni yatay kılavuz oluştur"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "Yatay kılavuzu kaldır"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "Yeni yatay ve dikey kılavuzlar oluştur"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5063,6 +5205,11 @@ msgstr "Duruşu Yapıştır"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "DuruÅŸu Temizle"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Örüntüden Emisyon Noktaları Oluştur"
@@ -5093,6 +5240,7 @@ msgid "Zoom Reset"
msgstr "Yakınlaşmayı Sıfırla"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Kip Seç"
@@ -5115,14 +5263,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt + RMB: Derin liste seçimi"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Biçimi Taşı"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Döndürme Biçimi"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "Ölçek Biçimi (R)"
@@ -5150,6 +5301,7 @@ msgid "Toggle snapping."
msgstr "Yapılmayı aç/kapat"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Yapışma Kullan"
@@ -5168,11 +5320,6 @@ msgid "Use Rotation Snap"
msgstr "Döndürme Yapışması Kullan"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "Yapışmayı Yapılandır..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "Göreceli Yapış"
@@ -5186,6 +5333,11 @@ msgid "Smart Snapping"
msgstr "Akıllı yapışma"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Yapışmayı Yapılandır..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "Ebeveyne yapıştır"
@@ -5409,16 +5561,6 @@ msgstr "Tutamacı Ayarla"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Resim yüklenirken hata:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Saydamlığı olan nokta yok > 128 bedizde..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Yayma Maskesini Yükle"
@@ -5741,14 +5883,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Yüzey kaynağı geçersiz (yüzler yok)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Atanın doldurmak için eksiksiz yüzleri yok."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Alan eÅŸleÅŸtirilemedi."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Bir Kaynak Örüntü Seçin:"
@@ -5834,20 +5968,27 @@ msgid "Generation Time (sec):"
msgstr "Nesil Süresi (sn):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Yüzler alan içermez!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Düğüm uzambilgisi (yüzler) içermiyor."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Yüzler yok!"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Düğüm uzambilgisi içermiyor."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Düğüm uzambilgisi (yüzler) içermiyor."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Düğüm uzambilgisi içermiyor."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6189,7 +6330,6 @@ msgid "Grid Settings"
msgstr "IzgaraHaritası Ayarları"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "Yapış"
@@ -6304,13 +6444,8 @@ msgstr "Bediz yüklenirken sorun oluştu:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "Bediz yüklenemedi"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
-msgstr "Bediz yüklenemedi"
+msgid "Could not load file at:"
+msgstr "Karo Bulunamadı:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6339,7 +6474,7 @@ msgstr "İçe aktarılırken hata"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "Yeni Klasör..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6426,6 +6561,11 @@ msgid "Open..."
msgstr "Aç"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Betik Aç"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Tümünü kaydet"
@@ -6465,13 +6605,13 @@ msgid "Save Theme"
msgstr "Kalıbı Kaydet"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Belgeleri Kapat"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Tümünü Kapat"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Belgeleri Kapat"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Çalıştır"
@@ -6562,6 +6702,11 @@ msgstr "Hata Ayıklayıcı"
msgid "Search Results"
msgstr "Yardım Ara"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "En Son Sahneleri Temizle"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6635,6 +6780,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6670,26 +6816,6 @@ msgid "Toggle Comment"
msgstr "Yorumu Aç / Kapat"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Serbestbakış Aç / Kapat"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Sonraki Kesme Noktasına Git"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Önceki Kesme Noktasına Git"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "Bütün Öğeleri Kaldır"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Satırı Katla/Aç"
@@ -6710,6 +6836,11 @@ msgid "Complete Symbol"
msgstr "Simgeyi Tamamla"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Seçimi Ölçekle"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "İzleyenin Boşluklarını Kırp"
@@ -6728,32 +6859,37 @@ msgid "Auto Indent"
msgstr "Kendinden Girintili"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Kesme Noktası Aç/Kapat"
+msgid "Find Previous"
+msgstr "Öncekini Bul"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Tüm Kesme Noktalarını Kaldır"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Dosyaları Süz..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "Bağlamsal Yardım"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "Sonraki Kesme Noktasına Git"
+msgid "Toggle Bookmark"
+msgstr "Serbestbakış Aç / Kapat"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "Önceki Kesme Noktasına Git"
+msgid "Go to Next Bookmark"
+msgstr "Sonraki Kesme Noktasına Git"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Öncekini Bul"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "Önceki Kesme Noktasına Git"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Dosyaları Süz..."
+msgid "Remove All Bookmarks"
+msgstr "Bütün Öğeleri Kaldır"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6766,8 +6902,23 @@ msgid "Go to Line..."
msgstr "Dizeye Git..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "Bağlamsal Yardım"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Kesme Noktası Aç/Kapat"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Tüm Kesme Noktalarını Kaldır"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Sonraki Kesme Noktasına Git"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Önceki Kesme Noktasına Git"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6954,9 +7105,14 @@ msgstr "Arka"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
msgstr "Görünüme Ayarla"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "Seçimi Görünüme Ayarla"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "Çocuğun örnek alacağı bir ebeveyn yok."
@@ -7011,8 +7167,9 @@ msgid "Audio Listener"
msgstr "Ses Dinleyici"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Çoğaltıcı Aktif"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Düzenlenebilir Çocuklar"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7068,8 +7225,8 @@ msgid "Snap Nodes To Floor"
msgstr "Izgaraya yapış"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Seçim Kipi (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7082,30 +7239,11 @@ msgstr ""
"Alt+RMB: Derin liste seçimi"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Taşıma Biçimi (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Döndürme Biçimi (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Ölçek Biçimi (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Yerel Kordinatlar"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Yerel Uzay Kipi (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Yapışma Kipi (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "Alttan Görünüm"
@@ -7147,26 +7285,6 @@ msgid "Focus Selection"
msgstr "Seçime Odaklan"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "Seçimi Görünüme Ayarla"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "Seçim Aracı"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "Taşıma Aracı"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "Döndürme Aracı"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "Ölçek Aracı"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "Serbestbakış Aç / Kapat"
@@ -7223,7 +7341,8 @@ msgstr "Izgara Görünümü"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Ayarlar"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7542,10 +7661,6 @@ msgid "TextureRegion"
msgstr "Doku Bölgesi"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Tema dosyaya kaydedilemiyor:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Tüm Öğeleri Ekle"
@@ -7635,12 +7750,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "Öğe"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "Öğe"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7750,14 +7865,6 @@ msgid "Transpose"
msgstr "Tersine Çevir"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "X'e Aynala"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Y'ye Aynala"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
msgid "Disable Autotile"
msgstr "Oto-döşemeler"
@@ -7773,8 +7880,8 @@ msgstr "Karo Boya"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8103,6 +8210,10 @@ msgid "TileSet"
msgstr "Karo Takımı"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "GiriÅŸ Ekle"
@@ -8195,6 +8306,11 @@ msgid "Duplicate Nodes"
msgstr "Düğüm(leri) Çoğalt"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Düğümleri Yapıştır"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Düğümleri Sil"
@@ -8219,6 +8335,11 @@ msgstr "SaÄŸ"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Düğüm Oluştur"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Düğüm Oluştur"
@@ -8297,6 +8418,22 @@ msgid "Color uniform."
msgstr "Dönüşüm"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8304,10 +8441,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Boolean constant."
msgstr "Vec Sabitini DeÄŸiÅŸtir"
@@ -8400,7 +8571,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8408,7 +8579,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8420,7 +8591,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8437,7 +8608,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8506,11 +8677,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8526,7 +8697,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8537,7 +8708,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8546,7 +8717,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8554,11 +8725,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8601,12 +8772,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr "Doku Tekdüzenini Değiştir"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr "Doku Tekdüzenini Değiştir"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "2D texture uniform lookup with triplanar."
msgstr "Doku Tekdüzenini Değiştir"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8616,7 +8792,7 @@ msgstr "Dönüştürme İletişim Kutusu..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8634,15 +8810,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8695,7 +8871,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8710,6 +8886,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8723,19 +8903,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8744,7 +8924,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8753,14 +8933,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8807,47 +8987,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9028,6 +9215,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Bu platform için dışa aktarma şablonu eksik:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Dışa Aktarım Şablonlarını Yönet"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "Hata Ayıklama İle Dışa Aktar"
@@ -9179,6 +9370,15 @@ msgstr "Adsız Proje"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Var Olan Projeyi İçe Aktar"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Proje Açılamadı"
@@ -9258,8 +9458,8 @@ msgstr "Proje listeden kaldırılsın mı? (Klasör içerikleri değiştirilmeye
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "Proje listeden kaldırılsın mı? (Klasör içerikleri değiştirilmeyecek)"
#: editor/project_manager.cpp
@@ -9286,8 +9486,9 @@ msgid "Project Manager"
msgstr "Proje Yöneticisi"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "Proje Listesi"
+#, fuzzy
+msgid "Projects"
+msgstr "Proje"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9311,10 +9512,6 @@ msgid "Templates"
msgstr "Åžablonlar"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Çık"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Åžimdi Yeniden BaÅŸlat"
@@ -9663,6 +9860,10 @@ msgstr "Yereller:"
msgid "AutoLoad"
msgstr "Otomatik Yükle"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Eklentiler"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Sıfır"
@@ -9715,14 +9916,6 @@ msgstr "Sanal Metot Seç"
msgid "Select Method"
msgstr "Metot Seç"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "PVRTC aracı çalıştırılamadı:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "PVRTC aracını kullanarak dönüştürülen bedizi geri yükleyemiyor:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10029,6 +10222,11 @@ msgid "Remove Node(s)"
msgstr "Düğümleri Kaldır"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Giriş Adını Değiştir"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10076,6 +10274,11 @@ msgstr "Betik Aç"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Düğümün Ebeveynliğini Değiştir"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "Anlamlı!"
@@ -10155,23 +10358,25 @@ msgstr "Düğüm yapılandırma uyarısı:"
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Düğüm bağlantı(lar) ve grup(lar)a sahip\n"
"Sinyaller dokunu göstermek için tıkla."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Düğüm bağlantılara sahip.\n"
"Sinyaller dokunu göstermek için tıkla."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Düğüm grup(lar)ın içinde.\n"
@@ -10278,6 +10483,11 @@ msgid "Error loading script from %s"
msgstr "Şuradan: %s betik yüklenirken hata"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Ãœzerine Yaz"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Uygulanamaz"
@@ -10312,7 +10522,8 @@ msgid "Script is valid."
msgstr "Betik geçerli"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "Ä°zin verilenler: a-z, A-Z, 0-9 ve _"
#: editor/script_create_dialog.cpp
@@ -10479,6 +10690,10 @@ msgid "Change Shortcut"
msgstr "Çapaları Değiştir"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Düzenleyici Ayarları"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Kısayollar"
@@ -10908,10 +11123,30 @@ msgid "Set Variable Type"
msgstr "DeÄŸiÅŸken Tipini Ayarla"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Geçersiz ad. Var olan gömülü türdeki ad ile çakışmamalı."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Yeni %s oluÅŸtur"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "DeÄŸiÅŸkenler:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Yeni %s oluÅŸtur"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Sıfırdan yeni bir çokgen oluşturun."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Ad doÄŸru bir belirleyici deÄŸil:"
@@ -11104,10 +11339,6 @@ msgid "Cut Nodes"
msgstr "Düğümleri Kes"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Düğümleri Yapıştır"
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "Ãœyeler"
@@ -11963,22 +12194,6 @@ msgstr ""
"yapın böylece bir boyut elde edebilir. Aksi takdirde, Görüntüleme için bunu "
"bir RenderTarget yap ve dahili dokusunu herhangi bir düğüme ata."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "FreeType başlatılırken hata."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Bilinmeyen yazıtipi formatı."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Yazıtipi yükleme hatası."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Geçersiz yazıtipi boyutu."
-
#: scene/resources/visual_shader.cpp
#, fuzzy
msgid "Input"
@@ -11994,6 +12209,11 @@ msgstr "Geçersiz kaynak!"
msgid "Invalid source for shader."
msgstr "Geçersiz kaynak!"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "Geçersiz kaynak!"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -12008,7 +12228,125 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "file_type_cache.cch yazma için açılamıyor! dosya türü önbelleğe "
+#~ "kaydedilmiyor!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "Gidilemiyor. '%s' bu dosya sisteminde bulunamadı!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Resim yüklenirken hata:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Saydamlığı olan nokta yok > 128 bedizde..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Atanın doldurmak için eksiksiz yüzleri yok."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Alan eÅŸleÅŸtirilemedi."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Yüzler alan içermez!"
+
+#~ msgid "No faces!"
+#~ msgstr "Yüzler yok!"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "Bediz yüklenemedi"
+
+#, fuzzy
+#~ msgid "Error could not load file."
+#~ msgstr "Bediz yüklenemedi"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Çoğaltıcı Aktif"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Seçim Kipi (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Taşıma Biçimi (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Döndürme Biçimi (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Ölçek Biçimi (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Yerel Kordinatlar"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Yapışma Kipi (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "Seçim Aracı"
+
+#~ msgid "Tool Move"
+#~ msgstr "Taşıma Aracı"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "Döndürme Aracı"
+
+#~ msgid "Tool Scale"
+#~ msgstr "Ölçek Aracı"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Proje listeden kaldırılsın mı? (Klasör içerikleri değiştirilmeyecek)"
+
+#~ msgid "Project List"
+#~ msgstr "Proje Listesi"
+
+#~ msgid "Exit"
+#~ msgstr "Çık"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "PVRTC aracı çalıştırılamadı:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "PVRTC aracını kullanarak dönüştürülen bedizi geri yükleyemiyor:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "FreeType başlatılırken hata."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Bilinmeyen yazıtipi formatı."
+
+#~ msgid "Error loading font."
+#~ msgstr "Yazıtipi yükleme hatası."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Geçersiz yazıtipi boyutu."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Önceki Klasör"
+
+#~ msgid "Next Folder"
+#~ msgstr "Sonraki Klasör"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "Sonraki Düzenleyiciyi aç"
+
+#~ msgid "Reverse"
+#~ msgstr "Tersi"
+
+#~ msgid "Mirror X"
+#~ msgstr "X'e Aynala"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Y'ye Aynala"
#~ msgid "Generating solution..."
#~ msgstr "Çözüm oluşturuluyor..."
@@ -12596,9 +12934,6 @@ msgstr ""
#~ msgid "Erase selection"
#~ msgstr "Seçimi Sil"
-#~ msgid "Could not find tile:"
-#~ msgstr "Karo Bulunamadı:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Öğe adı yada kimliği:"
@@ -12844,9 +13179,6 @@ msgstr ""
#~ msgid "Info"
#~ msgstr "Bilgi"
-#~ msgid "Re-Import..."
-#~ msgstr "Yeniden İçe Aktar..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "Alınacak hiç bit örteci yok!"
@@ -13241,9 +13573,6 @@ msgstr ""
#~ msgid "Stereo"
#~ msgstr "Çiftli"
-#~ msgid "Window"
-#~ msgstr "Pencere"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "Şuna %s%% Ölçeklendiriliyor."
@@ -13474,9 +13803,6 @@ msgstr ""
#~ msgid "Add Image Group"
#~ msgstr "Bediz Öbeği Ekle"
-#~ msgid "Delete Image Group"
-#~ msgstr "Bediz Öbeğini Sil"
-
#~ msgid "Project Export Settings"
#~ msgstr "Tasarıyı Dışa Aktarma Ayarları"
@@ -13561,9 +13887,6 @@ msgstr ""
#~ msgid "Export Project PCK"
#~ msgstr "Tasarı PCK Dışa Aktar"
-#~ msgid "Export..."
-#~ msgstr "Dışa Aktar..."
-
#~ msgid "Project Export"
#~ msgstr "Tasarı Dışa Aktar"
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index db7f358773..bee04e31b7 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-07-09 10:46+0000\n"
+"PO-Revision-Date: 2019-08-04 14:22+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -69,7 +69,6 @@ msgid "On call to '%s':"
msgstr "При виклику «%s»:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Вивільнити"
@@ -138,6 +137,26 @@ msgid "Anim Change Call"
msgstr "Змінити виклик анімації"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Змінити Ñ‡Ð°Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¾Ð³Ð¾ кадру анімації"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Змінити перехід анімації"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Змінити Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð°Ð½Ñ–Ð¼Ð°Ñ†Ñ–Ñ—"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Змінити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¾Ð³Ð¾ кадру анімації"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Змінити виклик анімації"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "Змінити триваліÑÑ‚ÑŒ анімації"
@@ -641,16 +660,18 @@ msgid "Line Number:"
msgstr "Ðомер Ñ€Ñдка:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Замінено %d випадок(-ів)."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Ðемає збігів"
+#, fuzzy
+msgid "%d match."
+msgstr "ВиÑвлено %d відповідників."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "Замінено %d випадок(-ів)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "ВиÑвлено %d відповідників."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -800,9 +821,8 @@ msgid "Connect"
msgstr "З'єднати"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Сигнали:"
+msgstr "Сигнал:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -878,8 +898,7 @@ msgstr "Вибране:"
msgid "Recent:"
msgstr "Ðещодавні:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -967,9 +986,9 @@ msgid "Owners Of:"
msgstr "ВлаÑники:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "Видалити вибрані файли з проєкту? (ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ)"
+msgstr ""
+"Вилучити позначені файли з проєкту? (Вилучені файли не вдаÑÑ‚ÑŒÑÑ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð¸Ñ‚Ð¸)"
#: editor/dependency_editor.cpp
msgid ""
@@ -981,7 +1000,7 @@ msgstr ""
"працювати.\n"
"Видалити Ñ—Ñ… у будь-Ñкому разі? (ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Ðеможливо вилучити:"
@@ -1017,7 +1036,7 @@ msgstr "ОÑтаточно вилучити %d об'єкт(и)? (ÐеможлиÐ
msgid "Show Dependencies"
msgstr "Показати залежноÑÑ‚Ñ–"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "ОглÑд підключених реÑурÑів"
@@ -1106,14 +1125,16 @@ msgid "License"
msgstr "ЛіцензіÑ"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Ð›Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ Ñ‚Ñ€ÐµÑ‚ÑŒÐ¾Ñ— Ñторони"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Рушій Godot ÑпираєтьÑÑ Ð½Ð° Ñ€Ñд Ñторонніх безкоштовних Ñ– відкритих бібліотек, "
@@ -1134,7 +1155,8 @@ msgid "Licenses"
msgstr "Ліцензії"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "Помилка Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ„Ð°Ð¹Ð»Ð° пакунка, не у форматі zip."
#: editor/editor_asset_installer.cpp
@@ -1151,7 +1173,6 @@ msgid "Success!"
msgstr "УÑпіх!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Ð’Ñтановити"
@@ -1520,6 +1541,8 @@ msgstr "Файл шаблону не знайдено:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
+"При екÑпортуванні у 32-бітовому режимі вбудовані PCK не можуть перевищувати "
+"за розміром 4 ГіБ."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1627,12 +1650,11 @@ msgid "New"
msgstr "Ðовий"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Імпортувати"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "ЕкÑпортуваннÑ"
@@ -1693,7 +1715,7 @@ msgstr "Показати у менеджері файлів"
msgid "New Folder..."
msgstr "Створити теку..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Оновити"
@@ -1744,7 +1766,7 @@ msgstr "Йти вперед"
msgid "Go Up"
msgstr "Вгору"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Перемкнути приховані файли"
@@ -1769,23 +1791,27 @@ msgid "Move Favorite Down"
msgstr "ПереміÑтити вибране вниз"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñ‚ÐµÐºÐ°"
+msgid "Go to previous folder."
+msgstr "Перейти до попередньої теки."
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "ÐаÑтупна тека"
+msgid "Go to next folder."
+msgstr "Перейти до наÑтупної теки."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Перейти до батьківÑької теки."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "ОÑвіжити файли."
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "Перемкнути Ñтан вибраноÑÑ‚Ñ– Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ñ— теки."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr "Увімкнути або вимкнути видиміÑÑ‚ÑŒ прихованих файлів."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2027,6 +2053,10 @@ msgstr "ОчиÑтити"
msgid "Clear Output"
msgstr "ОчиÑтити вивід"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Ðе вдалоÑÑ ÐµÐºÑпортувати проєкт, код помилки — %d."
@@ -2348,6 +2378,15 @@ msgid "Pick a Main Scene"
msgstr "Виберіть головну Ñцену"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Закрити Ñцену"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Закрити Ñцену"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
"Ðе вдаєтьÑÑ Ð²Ð²Ñ–Ð¼ÐºÐ½ÑƒÑ‚Ð¸ плагін addon: '%s' не вдалоÑÑ Ð¿Ñ€Ð¾Ð°Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ "
@@ -2464,6 +2503,11 @@ msgstr "Відтворити цю Ñцену"
msgid "Close Tab"
msgstr "Закрити вкладку"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Закрити вкладку"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Закрити інші вкладки"
@@ -2517,6 +2561,10 @@ msgid "Go to previously opened scene."
msgstr "Перейти до раніше відкритої Ñцени."
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Копіювати текÑÑ‚"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "ÐаÑтупна вкладка"
@@ -2544,6 +2592,10 @@ msgstr "Ðова уÑпадкована Ñцена..."
msgid "Open Scene..."
msgstr "Відкрити Ñцену..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Відкрити оÑтанні"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Зберегти Ñцену"
@@ -2553,14 +2605,6 @@ msgid "Save All Scenes"
msgstr "Зберегти вÑÑ– Ñцени"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Закрити Ñцену"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Відкрити оÑтанні"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Перетворити на..."
@@ -2590,25 +2634,37 @@ msgstr "Повернути Ñцену"
msgid "Miscellaneous project or scene-wide tools."
msgstr "Різні проєктні або Ñценографічні інÑтрументи."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Проєкт"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "Параметри проєкту"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "ІнÑтрументи"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "ЕкÑпортуваннÑ"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Ð’Ñтановити шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних проєкту"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "ІнÑтрументи"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Ð’Ñтановити шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "ОглÑд підключених реÑурÑів"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2706,12 +2762,13 @@ msgstr ""
"При віддаленому викориÑтанні на приÑтрої, це більш ефективно з мережевою "
"файловою ÑиÑтемою."
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Редактор"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Параметри редактора"
#: editor/editor_node.cpp
@@ -2727,14 +2784,6 @@ 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 "Перемикач повноекранного режиму"
@@ -2755,14 +2804,16 @@ msgid "Open Editor Settings Folder"
msgstr "Відкрити теку параметрів редактора"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑ‚Ñми редактора"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ екÑпорту"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Довідка"
@@ -2770,12 +2821,13 @@ msgstr "Довідка"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Пошук"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлайн документаціÑ"
@@ -3055,6 +3107,10 @@ msgstr "ЧаÑ"
msgid "Calls"
msgstr "Виклики"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Редагувати текÑÑ‚:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "Увімкнено"
@@ -3227,7 +3283,8 @@ msgid "Import From Node:"
msgstr "Імпортувати з вузла:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Перезавантажити"
#: editor/export_template_manager.cpp
@@ -3244,6 +3301,10 @@ msgid "Download"
msgstr "Завантажити"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(ВідÑутній)"
@@ -3307,12 +3368,10 @@ msgid "No response."
msgstr "Ðемає відповіді."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "Запит не вдавÑÑ."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "Циклічне переÑпрÑмуваннÑ."
@@ -3326,15 +3385,22 @@ msgid "Download Complete."
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð¾."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ тему до файла:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
"Ðе вдалоÑÑ Ð²Ñтановити шаблони. Проблемні архіви із шаблонами можна знайти "
"тут: «%s»."
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Помилка запиту url: "
#: editor/export_template_manager.cpp
@@ -3419,22 +3485,11 @@ msgstr "Завантажити шаблони"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "Виберіть дзеркало зі ÑпиÑку: (Shift+клацаннÑ: відкрити у браузері)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-"Ðе вдаєтьÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ file_type_cache.cch Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу, не буде збережений файл "
-"тип кешу!"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "Вибране"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-"Ðеможливо перейти до '%s' , оÑкільки він не був знайдений в файловій ÑиÑтемі!"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
"СтатуÑ: не вдалоÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ файл. Будь лаÑка, виправте файл та повторно "
@@ -3469,14 +3524,14 @@ msgid "Provided name contains invalid characters."
msgstr "Ðадане ім'Ñ Ð¼Ñ–Ñтить некоректні Ñимволи."
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "Ðазва міÑтить некоректні Ñимволи."
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "Файл або тека з таким іменем вже Ñ–Ñнує."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Ðазва міÑтить некоректні Ñимволи."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ:"
@@ -3532,6 +3587,11 @@ msgstr "Дублювати..."
msgid "Move To..."
msgstr "ПереміÑтити до..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Ðова Ñцена"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Створити Ñкрипт…"
@@ -3597,6 +3657,11 @@ msgstr "У вказаному каталозі вже міÑтитьÑÑ Ñ‚ÐµÐºÐ
msgid "Overwrite"
msgstr "ПерезапиÑати"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Створити зі Ñцени"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Створити Ñкрипт"
@@ -3659,6 +3724,14 @@ msgid "Search complete"
msgstr "Пошук завершено"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Додати до групи"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Вилучити з групи"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Група із такою назвою вже Ñ–Ñнує."
@@ -3666,12 +3739,23 @@ msgstr "Група із такою назвою вже Ñ–Ñнує."
msgid "Invalid group name."
msgstr "ÐеприпуÑтима назва групи."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð°Ð¼Ð¸"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Видалити компонуваннÑ"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Групи"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Вузли поза групою"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3684,12 +3768,13 @@ msgid "Nodes in Group"
msgstr "Вузли у групі"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Додати до групи"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Вилучити з групи"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Редактор Ñкриптів"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3897,7 +3982,8 @@ msgid "MultiNode Set"
msgstr "Мультивузловий набір"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "Виберіть вузол Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñигналів та груп."
#: editor/plugin_config_dialog.cpp
@@ -4662,10 +4748,6 @@ msgid "View Files"
msgstr "ПереглÑд файлів"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "Ðеможливо розпізнати ім'Ñ Ñ…Ð¾Ñта:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Помилка з'єднаннÑ, будь лаÑка, повторіть Ñпробу."
@@ -4678,14 +4760,47 @@ msgid "No response from host:"
msgstr "Ðемає відповіді від хоÑта:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "Ðеможливо розпізнати ім'Ñ Ñ…Ð¾Ñта:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Помилка запиту, код поверненнÑ:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "Запит не вдавÑÑ."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ тему до файла:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "Запит не вдавÑÑ, забагато перенаправлень"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Циклічне переÑпрÑмуваннÑ."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Помилка запиту, код поверненнÑ:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "ЧаÑ"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "РозбіжніÑÑ‚ÑŒ хеша завантаженнÑ, можливо файл був змінений."
@@ -4726,6 +4841,10 @@ msgid "Idle"
msgstr "ПроÑтій"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Ð’Ñтановити…"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Повторити Ñпробу"
@@ -4754,13 +4873,17 @@ msgid "Last"
msgstr "ОÑтанній"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Ð’Ñе"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Імпортувати"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "Плаґіни (додатки)"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4768,8 +4891,8 @@ msgid "Sort:"
msgstr "Сортувати:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Зворотний"
+msgid "Reverse sorting."
+msgstr "Обернений порÑдок."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4781,7 +4904,8 @@ msgid "Site:"
msgstr "Сайт:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Підтримка..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4793,6 +4917,11 @@ msgid "Testing"
msgstr "ТеÑтуваннÑ"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Завантажити…"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP файл активів"
@@ -4850,32 +4979,32 @@ msgid "Rotation Step:"
msgstr "Крок повороту:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr "ПереміÑтити вертикальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr "Створити нову вертикальну напрÑмну"
+msgid "Create Vertical Guide"
+msgstr "Створити вертикальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+msgid "Remove Vertical Guide"
msgstr "Вилучити вертикальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr "ПереміÑтити горизонтальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr "Створити нову горизонтальну напрÑмну"
+msgid "Create Horizontal Guide"
+msgstr "Створити горизонтальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "Вилучити горизонтальну напрÑмну"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr "Створити нові горизонтальні та вертикальні напрÑмні"
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Створити горизонтальні та вертикальні напрÑмні"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move pivot"
@@ -4958,6 +5087,11 @@ msgid "Paste Pose"
msgstr "Ð’Ñтавити позу"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "ОчиÑтити кіÑтки"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Створити нетипові кіÑтки з вузлів"
@@ -4988,6 +5122,7 @@ msgid "Zoom Reset"
msgstr "Відновити початковий маÑштаб"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Режим виділеннÑ"
@@ -5010,14 +5145,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Ðльт+ПКМ: СпиÑок вибору глибини"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Режим переміщеннÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Режим повороту"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Режим маÑштабуваннÑ"
@@ -5043,6 +5181,7 @@ msgid "Toggle snapping."
msgstr "Увімкнути або вимкнути прив'ÑзуваннÑ."
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "За допомогою функції прив'Ñзки"
@@ -5059,11 +5198,6 @@ msgid "Use Rotation Snap"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð²'Ñзки"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð²'Ñзки..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "ВідноÑна прив'Ñзка"
@@ -5076,6 +5210,11 @@ msgid "Smart Snapping"
msgstr "Інтелектуальне прилипаннÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð²'Ñзки..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ предка"
@@ -5291,16 +5430,6 @@ msgstr "Ð’Ñтановити обробник"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "Ð’ зображенні немає пікÑелів з прозоріÑÑ‚ÑŽ > 128..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "Завантажити маÑку випромінюваннÑ"
@@ -5611,14 +5740,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "Ðеправильне джерело поверхні (немає граней)."
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "Предок не має Ñуцільних граней Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð·Ð¸Ñ‚Ð¸ ділÑнку."
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "Виберіть джерело Ñітки:"
@@ -5703,20 +5824,27 @@ msgid "Generation Time (sec):"
msgstr "Ð§Ð°Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ— (Ñек):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "Грані не міÑÑ‚ÑÑ‚ÑŒ ділÑнки!"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "Ðемає граней!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Вузол не міÑтить геометрії (граней)."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "Вузол не міÑтить геометрії."
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "Вузол не міÑтить геометрії (граней)."
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "Вузол не міÑтить геометрії."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6049,7 +6177,6 @@ msgid "Grid Settings"
msgstr "Параметри Ñітки"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "ПрилипаннÑ"
@@ -6155,12 +6282,9 @@ msgid "Error writing TextFile:"
msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби запиÑати TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "Помилка: не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ файл."
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "Помилка: не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ файл."
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Ðеможливо знайти плитку:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6183,7 +6307,8 @@ msgid "Error Importing"
msgstr "Помилка імпортуваннÑ"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "Створити текÑтовий файл…"
#: editor/plugins/script_editor_plugin.cpp
@@ -6264,6 +6389,11 @@ msgid "Open..."
msgstr "Відкрити..."
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Відкрити Ñкрипт"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "Зберегти вÑе"
@@ -6301,13 +6431,13 @@ msgid "Save Theme"
msgstr "Зберегти тему"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Закрити документацію"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Закрити вÑе"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Закрити документацію"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "ЗапуÑтити"
@@ -6395,6 +6525,11 @@ msgstr "Зневаджувач"
msgid "Search Results"
msgstr "Результати пошуку"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "ОчиÑтити недавні Ñцени"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· методом:"
@@ -6463,8 +6598,9 @@ msgid "Syntax Highlighter"
msgstr "ЗаÑіб підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ ÑинтакÑиÑу"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Перейти"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6472,9 +6608,8 @@ msgid "Bookmarks"
msgstr "Закладки"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Створити точки."
+msgstr "Точки зупину"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -6498,22 +6633,6 @@ msgid "Toggle Comment"
msgstr "Перемкнути коментар"
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr "Увімкнути або вимкнути закладку"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr "Перейти до наÑтупної закладки"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr "Перейти до попередньої закладки"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr "Вилучити вÑÑ– закладки"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "Згорнути/розгорнути Ñ€Ñдок"
@@ -6534,6 +6653,11 @@ msgid "Complete Symbol"
msgstr "Завершити Ñимвол"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Вибір маÑштабу"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "Обрізати кінцевий пробіл"
@@ -6550,29 +6674,32 @@ msgid "Auto Indent"
msgstr "ÐвтовідÑтуп"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "Перемкнути точку зупинки"
+msgid "Find Previous"
+msgstr "Знайти попереднє"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "Вилучити вÑÑ– точки зупинки"
+msgid "Find in Files..."
+msgstr "Знайти у файлах…"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "Перейти до наÑтупної точки зупинки"
+msgid "Contextual Help"
+msgstr "КонтекÑтна довідка"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "Перейти до попередньої точки зупинки"
+msgid "Toggle Bookmark"
+msgstr "Увімкнути або вимкнути закладку"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "Знайти попереднє"
+msgid "Go to Next Bookmark"
+msgstr "Перейти до наÑтупної закладки"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "Знайти у файлах…"
+msgid "Go to Previous Bookmark"
+msgstr "Перейти до попередньої закладки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Вилучити вÑÑ– закладки"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6583,8 +6710,21 @@ msgid "Go to Line..."
msgstr "Перейти до Ñ€Ñдка..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "КонтекÑтна довідка"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Перемкнути точку зупинки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Вилучити вÑÑ– точки зупинки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Перейти до наÑтупної точки зупинки"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Перейти до попередньої точки зупинки"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6763,8 +6903,12 @@ msgid "Rear"
msgstr "Ззаду"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
-msgstr "ВирівнÑти з переглÑдом"
+msgid "Align Transform with View"
+msgstr "ВирівнÑти Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· переглÑдом"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "ВирівнÑти Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ñ–Ð· переглÑдом"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -6819,8 +6963,9 @@ msgid "Audio Listener"
msgstr "ПроÑÐ»ÑƒÑ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð²ÑƒÐºÑƒ"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "Ефект Доплера"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Увімкнути фільтруваннÑ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6876,8 +7021,8 @@ msgid "Snap Nodes To Floor"
msgstr "Приліпити вузли до підлоги"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "Режим Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6890,30 +7035,11 @@ msgstr ""
"Alt+Права кнопка: Вибір у ÑпиÑку за глибиною"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "Режим переÑÑƒÐ²Ð°Ð½Ð½Ñ (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "Режим Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "Режим маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "Локальні координати"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "Режим локального проÑтору (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "Режим Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "ВиглÑд знизу"
@@ -6954,26 +7080,6 @@ msgid "Focus Selection"
msgstr "ФокуÑувати позначене"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "ВирівнÑти позначене із переглÑдом"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "ІнÑтрумент позначеннÑ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "ІнÑтрумент переÑуваннÑ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "ІнÑтрумент обертаннÑ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "ІнÑтрумент маÑштабуваннÑ"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð¾Ð³Ð»Ñду"
@@ -7028,7 +7134,8 @@ msgstr "ПереглÑд ґратки"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "Параметри"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7323,10 +7430,6 @@ msgid "TextureRegion"
msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ тему до файла:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "Додати уÑÑ– елементи"
@@ -7411,11 +7514,13 @@ msgid "Submenu"
msgstr "Підменю"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+#, fuzzy
+msgid "Subitem 1"
msgstr "Елемент 1"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+#, fuzzy
+msgid "Subitem 2"
msgstr "Елемент 2"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7520,14 +7625,6 @@ msgid "Transpose"
msgstr "ТранÑпонувати"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "Віддзеркалити за X"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "Віддзеркалити за Y"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "Вимкнути автоплитки"
@@ -7540,9 +7637,10 @@ msgid "Paint Tile"
msgstr "Ðамалювати плитку"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
"Shift+права кнопка: малювати лінію\n"
"Shift+Ctrl+права кнопка: малювати прÑмокутник"
@@ -7843,6 +7941,10 @@ msgid "TileSet"
msgstr "Ðабір плиток"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "(лише GLES3)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr "Додати вхід +"
@@ -7919,6 +8021,11 @@ msgid "Duplicate Nodes"
msgstr "Дублювати вузли"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Ð’Ñтавити вузли"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "Вилучити вузли"
@@ -7939,6 +8046,11 @@ msgid "Light"
msgstr "Світло"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Створити вузол шейдера"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Create Shader Node"
msgstr "Створити вузол шейдера"
@@ -8011,6 +8123,22 @@ msgid "Color uniform."
msgstr "Однорідний колір."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "Повертає булевий результат порівнÑÐ½Ð½Ñ %s між двома параметрами."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "РівніÑÑ‚ÑŒ (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "Більше (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "Більше або дорівнює (>=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8020,11 +8148,47 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "Повертає булевий результат порівнÑÐ½Ð½Ñ Ð¼Ñ–Ð¶ INF та ÑкалÑрним параметром."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr "Повертає булевий результат порівнÑÐ½Ð½Ñ Ð¼Ñ–Ð¶ NaN Ñ– ÑкалÑрним параметром."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "Менше (<)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Менше або дорівнює (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Ðе дорівнює (!=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
"Повертає пов'Ñзаний вектор за заданим булевим значеннÑм «true» або «false»."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "Повертає булевий результат порівнÑÐ½Ð½Ñ Ð¼Ñ–Ð¶ двома параметрами."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+"Повертає булевий результат порівнÑÐ½Ð½Ñ Ð¼Ñ–Ð¶ INF (або NaN) та ÑкалÑрним "
+"параметром."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr "Булева Ñтала."
@@ -8113,16 +8277,16 @@ msgid "Returns the arc-cosine of the parameter."
msgstr "Повертає арккоÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
-msgstr "(Лише GLES3) Повертає обернений гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "Повертає обернений гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
msgstr "Повертає аркÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr "(Лише GLES3) Повертає обернений гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "Повертає обернений гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
@@ -8133,8 +8297,8 @@ msgid "Returns the arc-tangent of the parameters."
msgstr "Повертає Ð°Ñ€ÐºÑ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð²."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
-msgstr "(Лише GLES3) Повертає обернений гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "Повертає обернений гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8152,8 +8316,8 @@ msgid "Returns the cosine of the parameter."
msgstr "Повертає коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
-msgstr "(Лише GLES3) Повертає гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "Повертає гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
@@ -8225,12 +8389,12 @@ msgid "1.0 / scalar"
msgstr "1.0 / ÑкалÑÑ€"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
-msgstr "(Лише GLES3) Знаходить найближче ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра."
+msgid "Finds the nearest integer to the parameter."
+msgstr "Знаходить найближче ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr "(Лише GLES3) Знаходить найближче парне ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра."
+msgid "Finds the nearest even integer to the parameter."
+msgstr "Знаходить найближче парне ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -8245,18 +8409,19 @@ msgid "Returns the sine of the parameter."
msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
-msgstr "(Лише GLES3) Повертає гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "Повертає гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
msgstr "Повертає квадратний корінь з параметра."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8267,10 +8432,11 @@ msgstr ""
"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"ФункціÑ-Ñходинка ( ÑкалÑÑ€(межа), ÑкалÑÑ€(x) ).\n"
"\n"
@@ -8281,12 +8447,12 @@ msgid "Returns the tangent of the parameter."
msgstr "Повертає Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
-msgstr "(Лише GLES3) Повертає гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "Повертає гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr "(Лише GLES3) Визначає обрізане до цілого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+msgid "Finds the truncated value of the parameter."
+msgstr "Визначає обрізане до цілого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
@@ -8325,12 +8491,16 @@ msgid "Perform the texture lookup."
msgstr "Виконує пошук текÑтури."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
-msgstr "Однорідна кубічна текÑтура."
+msgid "Cubic texture uniform lookup."
+msgstr "Пошук однорідної кубічної текÑтури."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr "Пошук однорідної плаÑкої текÑтури."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
-msgstr "Однорідна плаÑка текÑтура."
+msgid "2D texture uniform lookup with triplanar."
+msgstr "Однорідний пошук плаÑкої текÑтури за допомогою трьох площин."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform function."
@@ -8338,7 +8508,7 @@ msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8346,7 +8516,7 @@ 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"
"\n"
"OuterProduct вважає перший параметр, «c», Ñ” вектором-Ñтовпчиком (матрицею із "
"одного Ñтовпчика) а другий параметр, «r», Ñ” вектором-Ñ€Ñдком (матрицею із "
@@ -8363,16 +8533,16 @@ msgid "Decomposes transform to four vectors."
msgstr "Розкладає Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð° чотири вектори."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
-msgstr "(Лише GLES3) ОбчиÑлює визначник перетвореннÑ."
+msgid "Calculates the determinant of a transform."
+msgstr "ОбчиÑлює визначник перетвореннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr "(Лише GLES3) ОбчиÑлює обернену матрицю перетвореннÑ."
+msgid "Calculates the inverse of a transform."
+msgstr "ОбчиÑлює обернену матрицю перетвореннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr "(Лише GLES3) ОбчиÑлює транÑпозицію перетвореннÑ."
+msgid "Calculates the transpose of a transform."
+msgstr "ОбчиÑлює транÑпозицію перетвореннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
@@ -8420,7 +8590,7 @@ msgstr "ОбчиÑлює ÑкалÑрний добуток двох вектор
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8439,6 +8609,11 @@ msgid "Linear interpolation between two vectors."
msgstr "Лінійна інтерполÑÑ†Ñ–Ñ Ð²Ñ–Ð´ двох векторних значень."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+msgstr "Лінійна інтерполÑÑ†Ñ–Ñ Ð²Ñ–Ð´ двох векторних значень."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr "Повертає нормалізований векторний добуток векторів."
@@ -8452,21 +8627,22 @@ msgstr "1.0 / вектор"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the 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."
+msgid "Returns the vector that points in the direction of refraction."
msgstr "Повертає вектор, Ñкий вказує напрÑмок рефракції."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8477,10 +8653,11 @@ msgstr ""
"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8491,20 +8668,22 @@ msgstr ""
"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"ФункціÑ-Ñходинка ( вектор(межа), вектор(x) ).\n"
"\n"
"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа». Якщо це не так, повертає 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
"ФункціÑ-Ñходинка ( ÑкалÑÑ€(межа), вектор(x) ).\n"
"\n"
@@ -8558,64 +8737,66 @@ msgstr ""
"напрÑмку поглÑду камери (функції Ñлід передати відповіді вхідні дані)."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ ÑкалÑрної "
-"похідної."
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
-msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— "
-"похідної."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr "(лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ ÑкалÑрної похідної."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr "(лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— похідної."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «x» на "
-"оÑнові локального диференціюваннÑ."
+"(лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «x» на оÑнові "
+"локального диференціюваннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «x» на "
-"оÑнові локального диференціюваннÑ."
+"(лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «x» на оÑнові "
+"локального диференціюваннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «y» на "
-"оÑнові локального диференціюваннÑ."
+"(лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «y» на оÑнові "
+"локального диференціюваннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «y» на "
-"оÑнові локального диференціюваннÑ."
+"(лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «y» на оÑнові "
+"локального диференціюваннÑ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Сума похідних за "
-"модулем у «x» та «y»."
+"(лише у режимі фрагментів або Ñвітла) (вектор) Сума похідних за модулем у "
+"«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'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
-"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Сума похідних за модулем "
-"у «x» та «y»."
+"(лише у режимі фрагментів або Ñвітла) Сума похідних за модулем у «x» та «y»."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
@@ -8791,6 +8972,10 @@ msgid "Export templates for this platform are missing:"
msgstr "Ðемає шаблонів екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— платформи:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ екÑпорту"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "ЕкÑпортувати із діагноÑтикою"
@@ -8949,6 +9134,15 @@ msgid "Unnamed Project"
msgstr "Проєкт без назви"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "Імпортувати наÑвний проєкт"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ проєкт у «%s»."
@@ -9045,11 +9239,13 @@ msgstr ""
"ВміÑÑ‚ теки не буде змінено."
#: editor/project_manager.cpp
+#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
-"Вилучити уÑÑ– проєкти, Ñкі не знайдено, зі ÑпиÑку? (ВміÑÑ‚ тек не буде змінено)"
+"Вилучити %d проєктів зі ÑпиÑку?\n"
+"ВміÑÑ‚ тек проєктів змінено не буде."
#: editor/project_manager.cpp
msgid ""
@@ -9073,8 +9269,9 @@ msgid "Project Manager"
msgstr "Керівник проекту"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "СпиÑок проєктів"
+#, fuzzy
+msgid "Projects"
+msgstr "Проєкт"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9097,10 +9294,6 @@ msgid "Templates"
msgstr "Шаблони"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Вихід"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Перезавантажити зараз"
@@ -9440,6 +9633,10 @@ msgstr "Мови:"
msgid "AutoLoad"
msgstr "ÐвтозавантаженнÑ"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Плаґіни (додатки)"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "Ðуль"
@@ -9492,15 +9689,6 @@ msgstr "Вибір віртуального методу"
msgid "Select Method"
msgstr "Вибір методу"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ інÑтрумент PVRTC:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-"Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ перетворене Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð° допомогою заÑобу PVRTC:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "Пакетне перейменуваннÑ"
@@ -9798,6 +9986,11 @@ msgid "Remove Node(s)"
msgstr "Вилучити вузли"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "Змінити назву вихідного порту"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9842,6 +10035,10 @@ msgid "Extend Script"
msgstr "Розширити Ñкрипт"
#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr "Змінити батьківÑький вузол на новий"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "Зробити кореневим Ð´Ð»Ñ Ñцени"
@@ -9914,24 +10111,27 @@ msgid "Node configuration warning:"
msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ Ð½Ð°Ð»Ð°ÑˆÑ‚Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÑƒÐ·Ð»Ð°:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"Вузол міÑтить з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ– групи.\n"
"Клацніть, щоб переглÑнути панель Ñигналів."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"Вузол міÑтить з'єднаннÑ\n"
"Клацніть, щоб переглÑнути панель Ñигналів."
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"Вузол належить групам.\n"
@@ -10030,6 +10230,11 @@ msgid "Error loading script from %s"
msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби завантажити Ñкрипт з %s"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "ПерезапиÑати"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "Ð/З"
@@ -10058,8 +10263,8 @@ msgid "Script is valid."
msgstr "Скрипт є коректним."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
-msgstr "Можна викориÑтовувати: a-z, A-Z, 0-9 Ñ– _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Можна викориÑтовувати: a-z, A-Z, 0-9, _ Ñ– ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
@@ -10218,6 +10423,10 @@ msgid "Change Shortcut"
msgstr "Змінити ÑкороченнÑ"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Параметри редактора"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "Клавіатурні ÑкороченнÑ"
@@ -10636,10 +10845,30 @@ msgid "Set Variable Type"
msgstr "Ð’Ñтановити тип змінної"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "Ðазва не повинна збігатиÑÑ Ñ–Ð· наÑвною назвою вбудованого типу."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Створити прÑмокутник."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Змінні:"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Створити прÑмокутник."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Створити новий полігон."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "Ðазва не Ñ” коректним ідентифікатором:"
@@ -10828,10 +11057,6 @@ msgid "Cut Nodes"
msgstr "Вирізати вузли"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "Ð’Ñтавити вузли"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "Редагувати член"
@@ -11138,7 +11363,6 @@ 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 "
"order for AnimatedSprite to display frames."
@@ -11206,11 +11430,10 @@ msgstr ""
"увімкненим параметром «ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ñ‡Ð°Ñток»."
#: scene/2d/light_2d.cpp
-#, fuzzy
msgid ""
"A texture with the shape of the light must be supplied to the \"Texture\" "
"property."
-msgstr "Ð”Ð»Ñ Ð²Ð»Ð°ÑтивоÑÑ‚Ñ– «texture» Ñлід надати текÑтуру із формою оÑвітленнÑ."
+msgstr "Ð”Ð»Ñ Ð²Ð»Ð°ÑтивоÑÑ‚Ñ– «Texture» Ñлід надати текÑтуру із формою оÑвітленнÑ."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -11220,11 +11443,10 @@ msgstr ""
"багатокутник затулÑннÑ."
#: scene/2d/light_occluder_2d.cpp
-#, fuzzy
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
msgstr ""
"Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ затулÑÐ½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾ÐºÑƒÑ‚Ð½Ð¸Ðº Ñ” порожнім. Будь лаÑка, намалюйте "
-"багатокутник!"
+"багатокутник."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -11324,7 +11546,6 @@ msgstr ""
"форми."
#: scene/2d/visibility_notifier_2d.cpp
-#, fuzzy
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
@@ -11333,9 +11554,8 @@ msgstr ""
"безпоÑереднім батьківÑьким елементом — редагованим коренем Ñцени."
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera повинен мати батьківÑьким вузлом вузол ARVROrigin"
+msgstr "ARVRCamera повинен мати батьківÑьким вузлом вузол ARVROrigin."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
@@ -11425,13 +11645,12 @@ 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."
msgstr ""
"Ð”Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ñ†ÐµÐ·Ð´Ð°Ñ‚Ð½Ð¾ÑÑ‚Ñ– CollisionShape Ñлід надати форму. Будь "
-"лаÑка, Ñтворіть реÑÑƒÑ€Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ елемента!"
+"лаÑка, Ñтворіть реÑÑƒÑ€Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ елемента."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -11467,7 +11686,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "SpotLight з кутом, Ñкий Ñ” більшим за 90 градуÑів, не може давати тіні."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11513,12 +11732,11 @@ msgid "PathFollow only works when set as a child of a Path node."
msgstr "PathFollow працюватиме лише Ñк дочірній елемент вузла Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
msgstr ""
-"PathFollow ROTATION_ORIENTED потребує Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Â«Up Vector» у його "
+"ROTATION_ORIENTED у PathFollow потребує Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Â«Up Vector» у його "
"батьківÑькому реÑурÑÑ– Curve у Path."
#: scene/3d/physics_body.cpp
@@ -11532,13 +11750,12 @@ msgstr ""
"ЗаміÑÑ‚ÑŒ цієї зміни, вам варто змінити розміри дочірніх форм зіткненнÑ."
#: scene/3d/remote_transform.cpp
-#, fuzzy
msgid ""
"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
"derived node to work."
msgstr ""
-"Щоб уÑе працювало Ñк Ñлід, влаÑтивіÑÑ‚ÑŒ шлÑху (path) має вказувати на "
-"коректний вузол Spatial."
+"Щоб уÑе працювало Ñк Ñлід, влаÑтивіÑÑ‚ÑŒ «Remote Path» має вказувати на "
+"коректний вузол Spatial або похідний від Spatial."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
@@ -11554,13 +11771,12 @@ msgstr ""
"ЗаміÑÑ‚ÑŒ цієї зміни, вам варто змінити розміри дочірніх форм зіткненнÑ."
#: scene/3d/sprite_3d.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"Щоб AnimatedSprite могла показувати кадри, має бути Ñтворено або вÑтановлено "
-"у влаÑтивоÑÑ‚Ñ– «Frames» реÑÑƒÑ€Ñ SpriteFrames."
+"Щоб AnimatedSprite3D могла показувати кадри, має бути Ñтворено або "
+"вÑтановлено у влаÑтивоÑÑ‚Ñ– «Frames» реÑÑƒÑ€Ñ SpriteFrames."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -11575,6 +11791,8 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"Щоб WorldEnvironment мала видимий ефект, Ñ—Ñ— влаÑтивіÑÑ‚ÑŒ «Environment» має "
+"міÑтити Ñередовище."
#: scene/3d/world_environment.cpp
msgid ""
@@ -11613,7 +11831,6 @@ msgid "Nothing connected to input '%s' of node '%s'."
msgstr "Ðічого не з'єднано із входом «%s» вузла «%s»."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "No root AnimationNode for the graph is set."
msgstr "Кореневий елемент AnimationNode Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„Ñƒ не вÑтановлено."
@@ -11627,7 +11844,6 @@ msgstr ""
"ШлÑÑ…, вÑтановлений Ð´Ð»Ñ AnimationPlayer, не веде до вузла AnimationPlayer."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
msgstr "Кореневий елемент AnimationPlayer не є коректним вузлом."
@@ -11657,7 +11873,6 @@ msgid "Add current color as a preset."
msgstr "Додати поточний колір Ñк шаблон."
#: scene/gui/container.cpp
-#, fuzzy
msgid ""
"Container by itself serves no purpose unless a script configures its "
"children placement behavior.\n"
@@ -11686,7 +11901,6 @@ 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, but they will hide upon "
@@ -11697,12 +11911,10 @@ msgstr ""
"практика. Втім, Ñлід пам'Ñтати, що під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку Ñ—Ñ… буде приховано."
#: scene/gui/range.cpp
-#, fuzzy
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr "Якщо exp_edit має Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ true, min_value має бути > 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 "
@@ -11737,35 +11949,22 @@ msgstr ""
"Control, щоб у неї був розмір. Крім того, можна зробити її RenderTarget і "
"пов'Ñзати Ñ—Ñ— внутрішню текÑтуру з одним із вузлів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ."
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Помилка ініціалізації FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Ðевідомий формат шрифту."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ñƒ."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Ðекоректний розмір шрифту."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Вхідні дані"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "Ðекоректне джерело програми побудови тіней."
+msgstr "Ðекоректне джерело Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "Ðекоректне джерело програми побудови тіней."
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr "Ðекоректна Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½ÑÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ типу."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¹Ð½Ð¾Ð³Ð¾."
@@ -11782,6 +11981,130 @@ msgstr "Змінні величини можна пов'Ñзувати лише
msgid "Constants cannot be modified."
msgstr "Сталі не можна змінювати."
+#~ msgid "No Matches"
+#~ msgstr "Ðемає збігів"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr ""
+#~ "Ðе вдаєтьÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ file_type_cache.cch Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу, не буде збережений "
+#~ "файл тип кешу!"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr ""
+#~ "Ðеможливо перейти до '%s' , оÑкільки він не був знайдений в файловій "
+#~ "ÑиÑтемі!"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "Ð’ зображенні немає пікÑелів з прозоріÑÑ‚ÑŽ > 128..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "Предок не має Ñуцільних граней Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ."
+
+#~ msgid "Couldn't map area."
+#~ msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð·Ð¸Ñ‚Ð¸ ділÑнку."
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "Грані не міÑÑ‚ÑÑ‚ÑŒ ділÑнки!"
+
+#~ msgid "No faces!"
+#~ msgstr "Ðемає граней!"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "Помилка: не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ файл."
+
+#~ msgid "Error could not load file."
+#~ msgstr "Помилка: не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ файл."
+
+#~ msgid "Doppler Enable"
+#~ msgstr "Ефект Доплера"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "Режим Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "Режим переÑÑƒÐ²Ð°Ð½Ð½Ñ (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "Режим Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "Режим маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "Локальні координати"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "Режим Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "ІнÑтрумент позначеннÑ"
+
+#~ msgid "Tool Move"
+#~ msgstr "ІнÑтрумент переÑуваннÑ"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "ІнÑтрумент обертаннÑ"
+
+#~ msgid "Tool Scale"
+#~ msgstr "ІнÑтрумент маÑштабуваннÑ"
+
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr ""
+#~ "Вилучити уÑÑ– проєкти, Ñкі не знайдено, зі ÑпиÑку? (ВміÑÑ‚ тек не буде "
+#~ "змінено)"
+
+#~ msgid "Project List"
+#~ msgstr "СпиÑок проєктів"
+
+#~ msgid "Exit"
+#~ msgstr "Вихід"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ інÑтрумент PVRTC:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr ""
+#~ "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ перетворене Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð° допомогою заÑобу PVRTC:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Помилка ініціалізації FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Ðевідомий формат шрифту."
+
+#~ msgid "Error loading font."
+#~ msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ñƒ."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Ðекоректний розмір шрифту."
+
+#~ msgid "Previous Folder"
+#~ msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñ‚ÐµÐºÐ°"
+
+#~ msgid "Next Folder"
+#~ msgstr "ÐаÑтупна тека"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "Ðвтоматично відкривати знімки вікон"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "Відкрити у зовнішньому редакторі зображень."
+
+#~ msgid "Reverse"
+#~ msgstr "Зворотний"
+
+#~ msgid "Mirror X"
+#~ msgstr "Віддзеркалити за X"
+
+#~ msgid "Mirror Y"
+#~ msgstr "Віддзеркалити за Y"
+
#~ msgid "Generating solution..."
#~ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð²'Ñзку..."
@@ -12521,9 +12844,6 @@ msgstr "Сталі не можна змінювати."
#~ msgid "Erase selection"
#~ msgstr "Витерти позначене"
-#~ msgid "Could not find tile:"
-#~ msgstr "Ðеможливо знайти плитку:"
-
#~ msgid "Item name or ID:"
#~ msgstr "Ðазва або ідентифікатор елемента:"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index cccbdbf067..d02d8f8c2c 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -63,7 +63,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -133,6 +132,26 @@ msgid "Anim Change Call"
msgstr ""
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr ""
@@ -621,15 +640,15 @@ msgid "Line Number:"
msgstr ""
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
+msgid "Replaced %d occurrence(s)."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
+msgid "%d match."
msgstr ""
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
msgstr ""
#: editor/code_editor.cpp editor/find_in_files.cpp
@@ -861,8 +880,7 @@ msgstr ""
msgid "Recent:"
msgstr ""
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -956,7 +974,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr ""
@@ -992,7 +1010,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1081,14 +1099,14 @@ msgid "License"
msgstr ""
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr ""
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1105,7 +1123,7 @@ msgid "Licenses"
msgstr ""
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1122,7 +1140,6 @@ msgid "Success!"
msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr ""
@@ -1600,12 +1617,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr ""
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr ""
@@ -1670,7 +1686,7 @@ msgstr ""
msgid "New Folder..."
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr ""
@@ -1721,7 +1737,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr ""
@@ -1748,24 +1764,30 @@ msgid "Move Favorite Down"
msgstr "Ù¾Ø³Ù†Ø¯ÛŒØ¯Û Ù†ÛŒÚ†Û’ منتقل کریں"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "سب سکریپشن بنائیں"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr ""
+#, fuzzy
+msgid "Go to next folder."
+msgstr "سب سکریپشن بنائیں"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "سب سکریپشن بنائیں"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr ""
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
msgstr ""
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2007,6 +2029,10 @@ msgstr ""
msgid "Clear Output"
msgstr "سب سکریپشن بنائیں"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2304,6 +2330,15 @@ msgid "Pick a Main Scene"
msgstr "ایک مینو منظر چنیں"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2398,6 +2433,10 @@ msgstr "ایک مینو منظر چنیں"
msgid "Close Tab"
msgstr ""
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2451,6 +2490,11 @@ msgid "Go to previously opened scene."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr ".تمام کا انتخاب"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr ""
@@ -2478,20 +2522,16 @@ msgstr ""
msgid "Open Scene..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "Save Scene"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
msgstr ""
#: editor/editor_node.cpp
-msgid "Save All Scenes"
+msgid "Save Scene"
msgstr ""
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
+msgid "Save All Scenes"
msgstr ""
#: editor/editor_node.cpp
@@ -2524,24 +2564,33 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr ""
#: editor/editor_node.cpp
-msgid "Project Settings"
+msgid "Project Settings..."
msgstr ""
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr ".سپورٹ"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr ""
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
+msgid "Orphan Resource Explorer..."
msgstr ""
#: editor/editor_node.cpp
@@ -2621,12 +2670,12 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr ""
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
msgstr ""
#: editor/editor_node.cpp
@@ -2642,14 +2691,6 @@ 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 ""
@@ -2670,14 +2711,15 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
-msgstr ""
-
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
+msgstr ".تمام کا انتخاب"
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr ""
@@ -2685,12 +2727,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2964,6 +3007,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr ".تمام کا انتخاب"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3127,7 +3175,7 @@ msgid "Import From Node:"
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+msgid "Redownload"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3144,6 +3192,10 @@ msgid "Download"
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3205,12 +3257,10 @@ msgid "No response."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr ""
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3224,13 +3274,17 @@ msgid "Download Complete."
msgstr ""
#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr ""
#: editor/export_template_manager.cpp
@@ -3318,20 +3372,12 @@ msgstr ".تمام کا انتخاب"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Ù¾Ø³Ù†Ø¯ÛŒØ¯Û Ø§ÙˆÙ¾Ø± منتقل کریں"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3364,11 +3410,11 @@ msgid "Provided name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
+msgid "A file or folder with this name already exists."
msgstr ""
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
+msgid "Name contains invalid characters."
msgstr ""
#: editor/filesystem_dock.cpp
@@ -3431,6 +3477,11 @@ msgstr ""
msgid "Move To..."
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "سب سکریپشن بنائیں"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3495,6 +3546,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "سب سکریپشن بنائیں"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3555,6 +3611,14 @@ msgid "Search complete"
msgstr ""
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr ""
@@ -3562,12 +3626,22 @@ msgstr ""
msgid "Invalid group name."
msgstr ""
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr ".تمام کا انتخاب"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3580,12 +3654,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "سب سکریپشن بنائیں"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3791,7 +3866,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4553,10 +4628,6 @@ msgid "View Files"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4569,14 +4640,42 @@ msgid "No response from host:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4617,6 +4716,10 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr ""
@@ -4645,13 +4748,16 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr ".سپورٹ"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4659,7 +4765,7 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
+msgid "Reverse sorting."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4672,7 +4778,8 @@ msgid "Site:"
msgstr "سائٹ:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr ".سپورٹ"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4684,6 +4791,10 @@ msgid "Testing"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Ø§Ø«Ø§Ø«Û Ú©ÛŒ زپ Ùائل"
@@ -4734,35 +4845,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "سب سکریپشن بنائیں"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "سب سکریپشن بنائیں"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr ".تمام کا انتخاب"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr ".تمام کا انتخاب"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "سب سکریپشن بنائیں"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr ".تمام کا انتخاب"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "سب سکریپشن بنائیں"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -4847,6 +4962,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr ""
@@ -4876,6 +4996,7 @@ msgid "Zoom Reset"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr ""
@@ -4896,15 +5017,18 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Move Mode"
msgstr "ایکشن منتقل کریں"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "ایکشن منتقل کریں"
@@ -4929,6 +5053,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -4945,11 +5070,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4962,6 +5082,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5172,16 +5297,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5497,14 +5612,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5588,19 +5695,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5939,7 +6050,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6045,12 +6155,9 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr ""
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "سب سکریپشن بنائیں"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6073,7 +6180,7 @@ msgid "Error Importing"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
@@ -6157,6 +6264,11 @@ msgid "Open..."
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6194,11 +6306,11 @@ msgid "Save Theme"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
+msgid "Close All"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close All"
+msgid "Close Docs"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
@@ -6287,6 +6399,11 @@ msgstr ""
msgid "Search Results"
msgstr "سب سکریپشن بنائیں"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "سب سکریپشن بنائیں"
+
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
msgstr ""
@@ -6355,6 +6472,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6390,23 +6508,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Toggle Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Bookmark"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr ".تمام کا انتخاب"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6427,6 +6528,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6443,32 +6549,36 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+msgid "Find in Files..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
+msgid "Toggle Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Go to Next Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
+msgid "Go to Previous Bookmark"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
msgid "Go to Function..."
msgstr ".تمام کا انتخاب"
@@ -6477,7 +6587,20 @@ msgid "Go to Line..."
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
msgstr ""
#: editor/plugins/shader_editor_plugin.cpp
@@ -6657,7 +6780,12 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
msgstr ".تمام کا انتخاب"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6713,8 +6841,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr ".نوٹÙئر Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6767,7 +6896,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6778,27 +6907,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6843,28 +6952,6 @@ msgid "Focus Selection"
msgstr ".تمام کا انتخاب"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Align Selection With View"
-msgstr ".تمام کا انتخاب"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr ".تمام کا انتخاب"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6919,7 +7006,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+msgid "Settings..."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7222,10 +7309,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7312,11 +7395,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7423,14 +7506,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7444,8 +7519,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7749,6 +7824,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add input +"
msgstr ""
@@ -7827,6 +7906,11 @@ msgid "Duplicate Nodes"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
@@ -7849,6 +7933,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "سب سکریپشن بنائیں"
@@ -7923,6 +8012,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7930,10 +8035,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8022,7 +8161,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8030,7 +8169,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8042,7 +8181,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8059,7 +8198,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8128,11 +8267,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8148,7 +8287,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8159,7 +8298,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8168,7 +8307,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8176,11 +8315,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8220,11 +8359,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8234,7 +8377,7 @@ msgstr "سب سکریپشن بنائیں"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8252,15 +8395,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8312,7 +8455,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8327,6 +8470,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8340,19 +8487,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8361,7 +8508,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8370,14 +8517,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8422,47 +8569,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8630,6 +8784,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8779,6 +8937,15 @@ msgid "Unnamed Project"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr ".تمام کا انتخاب"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr ""
@@ -8848,8 +9015,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8869,8 +9036,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr ".تمام کا انتخاب"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8895,10 +9063,6 @@ msgid "Templates"
msgstr ".تمام کا انتخاب"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9234,6 +9398,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9286,14 +9454,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr ""
@@ -9583,6 +9743,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9626,6 +9790,11 @@ msgid "Extend Script"
msgstr "سب سکریپشن بنائیں"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9701,19 +9870,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9805,6 +9974,10 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9834,7 +10007,7 @@ msgid "Script is valid."
msgstr ""
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10000,6 +10173,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10419,10 +10596,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10611,10 +10807,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11346,22 +11538,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr ""
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11374,6 +11550,10 @@ msgstr ""
msgid "Invalid source for shader."
msgstr ""
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11391,6 +11571,10 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr ".تمام کا انتخاب"
+
+#, fuzzy
#~ msgid "Create C# solution"
#~ msgstr "سب سکریپشن بنائیں"
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index e30b7b02b6..2cad1f6396 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-07-02 10:49+0000\n"
+"PO-Revision-Date: 2019-07-29 19:20+0000\n"
"Last-Translator: Steve Dang <itsnguu@outlook.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
@@ -28,7 +28,7 @@ msgstr ""
#: 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 ""
+msgstr "Hàm convert() có đối số không hợp lệ, sử dụng các hằng TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -65,13 +65,12 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "Miễn phí"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "Cân bằng"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
@@ -86,14 +85,12 @@ msgid "Value:"
msgstr "Giá trị:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Insert Key Here"
-msgstr "Chèn Key Anim"
+msgstr "Thêm Khoá Tại Äây"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Duplicate Selected Key(s)"
-msgstr "Nhân đôi lá»±a chá»n"
+msgstr "Nhân đôi các khoá đã chá»n"
#: editor/animation_bezier_editor.cpp
msgid "Delete Selected Key(s)"
@@ -101,12 +98,11 @@ msgstr "Xoá Key(s) được chá»n"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr ""
+msgstr "Thêm điểm Bezier"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Move Bezier Points"
-msgstr "Di chuyển đến..."
+msgstr "Di chuyển điểm Bezier"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -138,13 +134,37 @@ msgstr "Äổi Function Gá»i Animation"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Äổi thá»i gian khung hình"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "Äổi Transition Animation"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "Äổi Transform Animation"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Äổi giá trị khung hình"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "Äổi Function Gá»i Animation"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr "Äổi vòng lặp Anim"
+msgstr "Thay Äá»™ Dài Hoạt Ảnh"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "Chỉnh Vòng Lặp Hoạt Ảnh"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -172,14 +192,12 @@ msgid "Animation Playback Track"
msgstr "Ngưng chạy animation. (S)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
-msgstr "Äá»™ dài Animation (giây)."
+msgstr "Äá»™ dài hoạt ảnh (khung hình)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
-msgstr "Äá»™ dài Animation (giây)."
+msgstr "Äá»™ dài hoạt ảnh (giây)"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -187,9 +205,8 @@ msgid "Add Track"
msgstr "Thêm Track Animation"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Looping"
-msgstr "Phóng Animation."
+msgstr "Vòng Lặp Hoạt Ảnh"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -366,7 +383,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "Các bản hoạt ảnh chỉ có thể trỠtới các nút AnimationPlayer."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
@@ -454,12 +471,11 @@ 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 ""
+msgstr "Chá»n Toàn Bá»™"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select None"
-msgstr "Chế Ä‘á»™ chá»n"
+msgstr "Chá»n Không có"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -470,14 +486,12 @@ msgid "Group tracks by node or display them as plain list."
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "BÆ°á»›c (s):"
+msgstr "Chụp:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation step value."
-msgstr "Phóng Animation."
+msgstr "Giá trị bước hoạt ảnh."
#: editor/animation_track_editor.cpp
msgid "Seconds"
@@ -521,27 +535,24 @@ msgid "Duplicate Transposed"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "Nhân đôi lá»±a chá»n"
+msgstr "Xoá lá»±a chá»n"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Next Step"
-msgstr "Äến Step tiếp theo"
+msgstr "Äến BÆ°á»›c tiếp theo"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Previous Step"
-msgstr "Äến Step trÆ°á»›c đó"
+msgstr "Äến BÆ°á»›c trÆ°á»›c đó"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr "Tối ưu Animation"
+msgstr "Tối ưu Hoạt ảnh"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr "Dá»n dẹp Animation"
+msgstr "Dá»n dẹp Hoạt ảnh"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
@@ -573,12 +584,11 @@ msgstr "Tối ưu"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr "Hủy key không đúng chuẩn"
+msgstr "Gỡ bỠcác khoá không hợp lệ"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove unresolved and empty tracks"
-msgstr "Gỡ bỠtrack trống và không tìm thấy"
+msgstr "Gỡ bỠcác Tracks không thể xử lý và trống"
#: editor/animation_track_editor.cpp
msgid "Clean-up all animations"
@@ -586,7 +596,7 @@ msgstr "Dá»n dẹp tất cả animations"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "Dá»n dẹp tất cả Animation (KHÔNG THỂ Há»’I LẠI)"
+msgstr "Dá»n dẹp tất cả Hoạt ảnh (KHÔNG THỂ Há»’I LẠI)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
@@ -598,7 +608,7 @@ msgstr "Tỉ lệ Scale:"
#: editor/animation_track_editor.cpp
msgid "Select tracks to copy:"
-msgstr ""
+msgstr "Chá»n các Track để sao chép:"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -610,9 +620,8 @@ msgid "Copy"
msgstr "Sao chép"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Thêm Track Animation"
+msgstr "Thêm Track Âm thanh"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -643,21 +652,22 @@ msgid "Line Number:"
msgstr "Dòng số:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "Äã thay thế %d biến cố."
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "Không tìm thấy"
+#, fuzzy
+msgid "%d match."
+msgstr "Tìm thấy %d khớp."
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr ""
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "Tìm thấy %d khớp."
#: editor/code_editor.cpp editor/find_in_files.cpp
-#, fuzzy
msgid "Match Case"
-msgstr "Trùng khớp"
+msgstr "Khá»›p TrÆ°á»ng Hợp"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
@@ -705,37 +715,32 @@ msgid "Line and column numbers."
msgstr "Số dòng và cột."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "Cách thức trong Node được chá»n phải được ghi rõ!"
+msgstr "Phương thức trong nút đích phải được chỉ định."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid ""
"Target method not found. Specify a valid method or attach a script to the "
"target node."
msgstr ""
-"Cách thức của đối tượng không tìm thấy! ghi rõ một cách thức hợp lệ hoặc "
-"đính kèm một script cho đối tượng Node."
+"Phương thức không tìm thấy. Chỉ định phương thức hợp lệ hoặc đính kèm tệp "
+"lệnh vào nút."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Node:"
-msgstr "Kết nối đến Node:"
+msgstr "Kết nối đến Nút:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "Không thể kết nối tới host:"
+msgstr "Kết nối Tệp lệnh:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "Äang kết nối Signal:"
+msgstr "Từ tín hiệu:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr "Cảnh không chứa mã lệnh."
+msgstr "Cảnh không chứa tệp lệnh."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -755,27 +760,26 @@ msgid "Remove"
msgstr "Xóa"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Add Extra Call Argument:"
-msgstr "Thêm đối số:"
+msgstr "Thêm đối số mở rộng:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr ""
+msgstr "Mở rá»™ng Äối số được gá»i:"
#: editor/connections_dialog.cpp
msgid "Advanced"
msgstr "Nâng cao"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Deferred"
-msgstr "Hoãn lại"
+msgstr "Trì hoãn"
#: editor/connections_dialog.cpp
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
msgstr ""
+"Trì hoãn tín hiệu, lÆ°u vào má»™t hàng chá» và chỉ kích nó vào thá»i gian rãnh."
#: editor/connections_dialog.cpp
msgid "Oneshot"
@@ -808,7 +812,6 @@ msgid "Connect"
msgstr "Kết nối"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "Tín hiệu:"
@@ -821,9 +824,8 @@ msgid "Disconnect '%s' from '%s'"
msgstr "Hủy kết nối '%s' từ '%s'"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect all from signal: '%s'"
-msgstr "Hủy kết nối '%s' từ '%s'"
+msgstr "Dừng kết nối tất cả từ tín hiệu: '%s'"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -868,7 +870,7 @@ msgstr "Äến Method"
#: editor/create_dialog.cpp
msgid "Change %s Type"
-msgstr "Äổi %s Type"
+msgstr "Äổi %s Loại"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
@@ -887,8 +889,7 @@ msgstr "Ưa thích:"
msgid "Recent:"
msgstr "Gần đây:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -921,38 +922,42 @@ msgid ""
"Scene '%s' is currently being edited.\n"
"Changes will only take effect when reloaded."
msgstr ""
+"Cảnh '%s' hiện đang được chỉnh sửa.\n"
+"Các thay đổi chỉ có hiệu lực khi tải lại."
#: editor/dependency_editor.cpp
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
msgstr ""
+"Tài nguyên '%s' đang sử dụng.\n"
+"Thay đổi sẽ chỉ hiệu lực khi tải lại."
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Dependencies"
-msgstr ""
+msgstr "Các phụ thuộc"
#: editor/dependency_editor.cpp
msgid "Resource"
-msgstr ""
+msgstr "Tài nguyên"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_settings_editor.cpp editor/script_create_dialog.cpp
msgid "Path"
-msgstr ""
+msgstr "ÄÆ°á»ng dẫn"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
-msgstr ""
+msgstr "Các phụ thuộc:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
-msgstr ""
+msgstr "Sửa chữa"
#: editor/dependency_editor.cpp
msgid "Dependency Editor"
-msgstr ""
+msgstr "Trình chỉnh sửa Phụ thuộc"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
@@ -970,11 +975,11 @@ msgstr "Mở"
#: editor/dependency_editor.cpp
msgid "Owners Of:"
-msgstr ""
+msgstr "Sở hữu của:"
#: editor/dependency_editor.cpp
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr ""
+msgstr "Gỡ bá» các tệp đã chá»n trong dá»± án? (Không thể khôi phục)"
#: editor/dependency_editor.cpp
msgid ""
@@ -983,7 +988,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "Không thể gỡ bá»:"
@@ -997,15 +1002,15 @@ msgstr ""
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
-msgstr ""
+msgstr "Luôn mở"
#: editor/dependency_editor.cpp
msgid "Which action should be taken?"
-msgstr ""
+msgstr "Chá»n hành Ä‘á»™ng nên thá»±c hiện?"
#: editor/dependency_editor.cpp
msgid "Fix Dependencies"
-msgstr ""
+msgstr "Sửa các phần phụ thuộc"
#: editor/dependency_editor.cpp
msgid "Errors loading!"
@@ -1020,7 +1025,7 @@ msgstr "Xoá vĩnh viễn các đối tượng %d? (Không thể hoàn lại!)"
msgid "Show Dependencies"
msgstr "Phần phụ thuộc cho:"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1034,7 +1039,7 @@ msgstr "Xóa"
#: editor/dependency_editor.cpp
msgid "Owns"
-msgstr ""
+msgstr "Sở hữu"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
@@ -1109,16 +1114,22 @@ msgid "License"
msgstr "Cấp phép"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "Cấp phép nhóm thứ ba"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
+"Godot Engine dựa trên một số thư viện mã nguồn mở và miễn phí của bên thứ "
+"ba, tất cả Ä‘á»u phù hợp vá»›i các Ä‘iá»u khoản trong giấy phép MIT. Sau đây là "
+"danh sách tất cả các thành phần của bên thứ ba vá»›i các Ä‘iá»u khoản bản quyá»n "
+"và Ä‘iá»u khoản cấp phép tÆ°Æ¡ng ứng."
#: editor/editor_about.cpp
msgid "All Components"
@@ -1133,12 +1144,13 @@ msgid "Licenses"
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."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
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"
-msgstr ""
+msgstr "Giải nén Assets"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1150,7 +1162,6 @@ msgid "Success!"
msgstr "Thành công!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "Cài đặt"
@@ -1160,7 +1171,7 @@ msgstr "Gói cài đặt"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
-msgstr ""
+msgstr "Máy phát thanh"
#: editor/editor_audio_buses.cpp
msgid "Add Effect"
@@ -1269,7 +1280,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
-msgstr ""
+msgstr "Vị trí cho Bố cục mới..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
@@ -1621,12 +1632,11 @@ msgid "New"
msgstr "Má»›i"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "Nhập vào"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Xuất ra"
@@ -1688,7 +1698,7 @@ msgstr "Xem trong trình quản lý tệp"
msgid "New Folder..."
msgstr "Thư mục mới ..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "Làm mới"
@@ -1739,7 +1749,7 @@ msgstr "Tiến tới"
msgid "Go Up"
msgstr "Äi Lên"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "Bật tắt File ẩn"
@@ -1764,23 +1774,31 @@ msgid "Move Favorite Down"
msgstr "Di chuyển Ưa thích xuống"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "Thư mục trước"
+#, fuzzy
+msgid "Go to previous folder."
+msgstr "Äến thÆ° mục cha"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "Thư mục sau"
+#, fuzzy
+msgid "Go to next folder."
+msgstr "Äến thÆ° mục cha"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Äến thÆ° mục cha"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "Tìm kiếm tệp tin"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "BỠyêu thích thư mục hiện tại."
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Toggle the visibility of hidden files."
msgstr "Bật tắt hiện các tệp tin ẩn."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2016,6 +2034,10 @@ msgstr "Xoá"
msgid "Clear Output"
msgstr "Xoá đầu ra"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "Xuất dự án thất bại với mã lỗi %d."
@@ -2333,6 +2355,15 @@ msgid "Pick a Main Scene"
msgstr "Chá»n má»™t Scene chính"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Äóng Cảnh"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "Äóng Cảnh"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2436,6 +2467,11 @@ msgstr "Chạy cảnh này"
msgid "Close Tab"
msgstr "Äóng Tab"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "Äóng Tab"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "Äóng tất cả Tab khác"
@@ -2489,6 +2525,11 @@ msgid "Go to previously opened scene."
msgstr "Trở vỠcảnh đã mở trước đó."
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "Sao chép Ä‘Æ°á»ng dẫn"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "Tab tiếp theo"
@@ -2516,6 +2557,10 @@ msgstr "Tạo Cảnh Kế thừa..."
msgid "Open Scene..."
msgstr "Mở Cảnh ..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Mở gần đây"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "Lưu Cảnh"
@@ -2525,14 +2570,6 @@ msgid "Save All Scenes"
msgstr "Lưu tất cả Cảnh"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "Äóng Cảnh"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "Mở gần đây"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "Chuyển đổi ..."
@@ -2562,25 +2599,37 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "Dự án"
#: editor/editor_node.cpp
-msgid "Project Settings"
-msgstr ""
+#, fuzzy
+msgid "Project Settings..."
+msgstr "List Project"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "Công cụ"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "Xuất ra"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "Cài đặt mẫu xây dựng Android"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "Mở thư mục dữ liệu dự án"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Công cụ"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "Cài đặt mẫu xây dựng Android"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "Lưu tài nguyên thành ..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2661,12 +2710,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Trình biên tập"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "Cài đặt Trình biên tập"
#: editor/editor_node.cpp
@@ -2683,14 +2733,6 @@ 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 in an external image editor."
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
msgstr "Chế độ Toàn màn hình"
@@ -2712,14 +2754,16 @@ msgid "Open Editor Settings Folder"
msgstr ""
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
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"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "Quản lý mẫu Xuất ra"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "Trợ giúp"
@@ -2727,12 +2771,13 @@ msgstr "Trợ giúp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "Tìm kiếm"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Tài liệu trực tuyến"
@@ -3006,6 +3051,11 @@ msgstr ""
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "LÆ°u Theme"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3168,7 +3218,8 @@ msgid "Import From Node:"
msgstr "Nhập từ Nút:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "Tải lại"
#: editor/export_template_manager.cpp
@@ -3185,6 +3236,10 @@ msgid "Download"
msgstr "Tải"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(Thiếu)"
@@ -3246,12 +3301,10 @@ msgid "No response."
msgstr "Không phản hồi."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
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 "Chuyển hướng vòng lặp."
@@ -3265,13 +3318,19 @@ msgid "Download Complete."
msgstr "Tải xuống xong."
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "Không thể gỡ bá»:"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "Lá»—i khi yêu cầu Ä‘Æ°á»ng dẫn: "
#: editor/export_template_manager.cpp
@@ -3357,20 +3416,12 @@ msgstr "Tải các Mẫu"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "Ưa thích:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3403,14 +3454,14 @@ msgid "Provided name contains invalid characters."
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ó 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 têp tin hoặc thÆ° mục trùng tên."
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "Tên có chứa kí tự không hợp lệ."
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "Äổi tên tệp tin:"
@@ -3466,6 +3517,11 @@ msgstr "Nhân đôi..."
msgid "Move To..."
msgstr "Di chuyển đến..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "Tạo Cảnh Mới"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "Tạo Mã lệnh ..."
@@ -3531,6 +3587,11 @@ msgstr "Äã có tệp tin hoặc thÆ° mục cùng tên tại vị trí này."
msgid "Overwrite"
msgstr "Ghi đè"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "Tạo từ Scene"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "Tạo Mã lệnh"
@@ -3593,6 +3654,14 @@ msgid "Search complete"
msgstr "Tìm kiếm hoàn tất"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Thêm vào Nhóm"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Xóa khá»i Nhóm"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "Tên nhóm đã tồn tại."
@@ -3600,12 +3669,23 @@ msgstr "Tên nhóm đã tồn tại."
msgid "Invalid group name."
msgstr "Tên nhóm không hợp lệ."
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "Quản lý Nhóm"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "Xoá bố cục"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "Nhóm"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "Nút không trong Nhóm"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3618,12 +3698,13 @@ msgid "Nodes in Group"
msgstr "Các nút trong Nhóm"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "Thêm vào Nhóm"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "Xóa khá»i Nhóm"
+#, fuzzy
+msgid "Group Editor"
+msgstr "Trình viết mã lệnh"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3829,7 +3910,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -3909,7 +3990,7 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Animation"
-msgstr "Thêm Animation"
+msgstr "Thêm Hoạt ảnh"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4111,7 +4192,7 @@ msgstr "Äổi bá»™ lá»c"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
-msgstr ""
+msgstr "Không có trình phát hoạt ảnh, không thể truy xuất tên."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
@@ -4123,6 +4204,7 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
+"Trính phát hoạt ảnh không có Ä‘Æ°á»ng dẫn nút Gốc, không thể truy xuất tên."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
@@ -4227,7 +4309,7 @@ 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 hoạt ảnh. (S)"
+msgstr "Dừng chạy lại hoạt ảnh. (S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
@@ -4588,10 +4670,6 @@ msgid "View Files"
msgstr "Xem Files"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "Kết nỗi lỗi, thử lại."
@@ -4604,15 +4682,48 @@ msgid "No response from host:"
msgstr "Không có phản hồi từ host:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "Yêu cầu thất bại, trả lại code:"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
+msgid "Request failed."
+msgstr "Yêu cầu thất bại."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "Không thể gỡ bá»:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Request failed, too many redirects"
msgstr "Yêu cầu thất bại, gá»­i lại quá nhiá»u"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "Chuyển hướng vòng lặp."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "Yêu cầu thất bại, trả lại code:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "Thá»i gian:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4653,6 +4764,11 @@ msgid "Idle"
msgstr "Chạy không"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "Cài đặt"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "Thử lại"
@@ -4681,13 +4797,16 @@ msgid "Last"
msgstr "Cuối cùng"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "Tất cả"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "Nhập vào"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4695,8 +4814,9 @@ msgid "Sort:"
msgstr "Sắp xếp:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "Ngược lại"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "Äang yêu cầu..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4708,7 +4828,8 @@ msgid "Site:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "Hỗ trợ ..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4720,6 +4841,11 @@ msgid "Testing"
msgstr "Kiểm tra"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "Nạp ..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Tệp tin ZIP Nguyên liệu"
@@ -4770,31 +4896,35 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+msgid "Move Vertical Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Create Vertical Guide"
+msgstr "Tạo Folder"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "Xoá Variable"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+msgid "Move Horizontal Guide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal Guide"
+msgstr "Tạo Root Node:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Horizontal Guide"
+msgstr "Hủy key không đúng chuẩn"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+msgid "Create Horizontal and Vertical Guides"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4878,6 +5008,11 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Guides"
+msgstr "Xoá khung xương"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
msgstr "Tạo xương tuỳ chỉnh từ Nút"
@@ -4906,6 +5041,7 @@ msgid "Zoom Reset"
msgstr "Äặt lại Thu phóng"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "Chế Ä‘á»™ chá»n"
@@ -4926,14 +5062,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "Chế độ Di chuyển"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "Chế độ Xoay"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "Chế độ Tỉ lệ"
@@ -4959,6 +5098,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "Sử dụng Snap"
@@ -4975,11 +5115,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -4992,6 +5127,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5201,16 +5341,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-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
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5526,14 +5656,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5617,19 +5739,24 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "Cảnh không chứa tệp lệnh."
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't contain geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -5964,7 +6091,6 @@ msgid "Grid Settings"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6070,12 +6196,9 @@ msgid "Error writing TextFile:"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr ""
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "Không viết được file:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6103,8 +6226,9 @@ msgid "Error Importing"
msgstr "Lỗi di chuyển:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
-msgstr ""
+#, fuzzy
+msgid "New Text File..."
+msgstr "Thư mục mới ..."
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6189,6 +6313,11 @@ msgid "Open..."
msgstr "Mở"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "Tạo Script"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6227,13 +6356,13 @@ msgid "Save Theme"
msgstr "LÆ°u Theme"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "Äóng Docs"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "Äóng tất cả"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Äóng Docs"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "Chạy"
@@ -6320,6 +6449,11 @@ msgstr ""
msgid "Search Results"
msgstr "Tìm sự giúp đỡ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "Dá»n các cảnh gần đây"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6391,6 +6525,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6426,25 +6561,6 @@ msgid "Toggle Comment"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "Bật tắt Chức năng"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "Äến Step tiếp theo"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "Äến Step trÆ°á»›c đó"
-
-#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Bookmarks"
-msgstr ""
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr ""
@@ -6465,6 +6581,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "Chá»n Scale"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6481,35 +6602,39 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "Tìm..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
+msgid "Toggle Bookmark"
+msgstr "Bật tắt Chức năng"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Bookmark"
msgstr "Äến Step tiếp theo"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
+msgid "Go to Previous Bookmark"
msgstr "Äến Step trÆ°á»›c đó"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
+msgid "Remove All Bookmarks"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "Tìm..."
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function..."
msgstr "Xoá Function"
@@ -6519,9 +6644,24 @@ msgid "Go to Line..."
msgstr "Äến Dòng"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "Äến Step tiếp theo"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "Äến Step trÆ°á»›c đó"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -6699,7 +6839,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -6755,8 +6899,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr ""
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "Kích hoạt lá»c"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6809,7 +6954,7 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6820,27 +6965,7 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6884,26 +7009,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr ""
@@ -6958,8 +7063,9 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
-msgstr ""
+#, fuzzy
+msgid "Settings..."
+msgstr "Äang kết nối..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -7264,10 +7370,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7356,11 +7458,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7469,14 +7571,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7490,8 +7584,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -7798,6 +7892,10 @@ msgid "TileSet"
msgstr "Xuất Tile Set"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "Thêm Input"
@@ -7884,6 +7982,11 @@ msgid "Duplicate Nodes"
msgstr "Nhân đôi Node(s)"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "Xóa Node(s)"
@@ -7906,6 +8009,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "Tạo Root Node:"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "Tạo Root Node:"
@@ -7984,6 +8092,22 @@ msgid "Color uniform."
msgstr "Äổi Transform Animation"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -7991,10 +8115,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8084,7 +8242,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8092,7 +8250,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8104,7 +8262,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8121,7 +8279,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8190,11 +8348,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8210,7 +8368,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8221,7 +8379,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8230,7 +8388,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8238,11 +8396,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8283,11 +8441,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8297,7 +8459,7 @@ msgstr "Tạo"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8315,15 +8477,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8375,7 +8537,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8390,6 +8552,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8403,19 +8569,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8424,7 +8590,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8433,14 +8599,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8485,47 +8651,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8697,6 +8870,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "Quản lý mẫu Xuất ra"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -8845,6 +9022,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "Dự án"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "Không thể chạy project"
@@ -8914,8 +9100,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -8935,8 +9121,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "List Project"
+#, fuzzy
+msgid "Projects"
+msgstr "Dự án"
#: editor/project_manager.cpp
msgid "Scan"
@@ -8960,10 +9147,6 @@ msgid "Templates"
msgstr "Khung project"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "Thoát"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "Restart ngay"
@@ -9304,6 +9487,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9356,14 +9543,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9656,6 +9835,10 @@ msgid "Remove Node(s)"
msgstr "Xóa Node(s)"
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9700,6 +9883,11 @@ msgid "Extend Script"
msgstr "Tạo Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "Tạo các nút mới."
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr ""
@@ -9775,19 +9963,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -9883,6 +10071,11 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "Ghi đè"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -9914,7 +10107,7 @@ msgid "Script is valid."
msgstr "Animation tree khả dụng."
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10075,6 +10268,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "Cài đặt Trình biên tập"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10491,10 +10688,29 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "Tạo nodes mới."
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "Tạo nodes mới."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "Tạo"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -10681,10 +10897,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr ""
@@ -11426,22 +11638,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "Lỗi khởi tạo FreeType."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "Äịnh dạng font không hợp lệ."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "Lỗi tải font."
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "Kích thước font không hợp lệ."
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "Nhập"
@@ -11455,6 +11651,11 @@ msgstr "nguồn vô hiệu cho shader."
msgid "Invalid source for shader."
msgstr "nguồn vô hiệu cho shader."
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "nguồn vô hiệu cho shader."
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11471,6 +11672,36 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No Matches"
+#~ msgstr "Không khớp"
+
+#~ msgid "Error loading image:"
+#~ msgstr "Lỗi tải nạp hình ảnh:"
+
+#~ msgid "Exit"
+#~ msgstr "Thoát"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "Lỗi khởi tạo FreeType."
+
+#~ msgid "Unknown font format."
+#~ msgstr "Äịnh dạng font không hợp lệ."
+
+#~ msgid "Error loading font."
+#~ msgstr "Lỗi tải font."
+
+#~ msgid "Invalid font size."
+#~ msgstr "Kích thước font không hợp lệ."
+
+#~ msgid "Previous Folder"
+#~ msgstr "Thư mục trước"
+
+#~ msgid "Next Folder"
+#~ msgstr "Thư mục sau"
+
+#~ msgid "Reverse"
+#~ msgstr "Ngược lại"
+
#~ msgid "Enabled Classes"
#~ msgstr "Các lớp đã bật"
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index a789fbbaaa..b79ebd625f 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -33,7 +33,7 @@
# å°è è粑粑 <2062152083@qq.com>, 2018.
# 刘庆文 <liuqingwen@163.com>, 2018.
# Haowen Liu <liu.haowen.andy@gmail.com>, 2018.
-# tangdou1 <1093505442@qq.com>, 2018.
+# tangdou1 <1093505442@qq.com>, 2018, 2019.
# yzt <834950797@qq.com>, 2018, 2019.
# DKLost <514dklost@gmail.com>, 2018.
# thanksshu <hezihanshangyuan@gmail.com>, 2018.
@@ -48,12 +48,18 @@
# DS <dseqrasd@126.com>, 2019.
# ZeroAurora <zeroaurora@qq.com>, 2019.
# Gary Wang <wzc782970009@gmail.com>, 2019.
+# ASC_8384 <ASC8384ST@gmail.com>, 2019.
+# Lyu Shiqing <shiqing-thu18@yandex.com>, 2019.
+# ColdThunder11 <lslyj27761@gmail.com>, 2019.
+# liu lizhi <kz-xy@163.com>, 2019.
+# çŽ‹å¾ <jackey20000331@gmail.com>, 2019.
+# 巴哈姆特 <ttwings@126.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-07-09 10:47+0000\n"
-"Last-Translator: Gary Wang <wzc782970009@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: yzt <834950797@qq.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
"Language: zh_CN\n"
@@ -61,7 +67,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.8-dev\n"
+"X-Generator: Weblate 3.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -103,7 +109,6 @@ msgid "On call to '%s':"
msgstr "对'%s'调用 :"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "释放"
@@ -172,6 +177,26 @@ msgid "Anim Change Call"
msgstr "修改回调"
#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "修改多个动画关键帧的时长"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "修改多个动画过渡方å¼"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "动画多次修改å˜æ¢é‡"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "修改多个动画关键帧的值"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "修改多个回调"
+
+#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
msgstr "修改动画长度"
@@ -471,6 +496,11 @@ 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"
@@ -660,16 +690,18 @@ msgid "Line Number:"
msgstr "è¡Œå·:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "替æ¢äº†%d项。"
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "无匹é…项"
+#, fuzzy
+msgid "%d match."
+msgstr "找到%d个匹é…项。"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "替æ¢äº†%d项。"
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "找到%d个匹é…项。"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -721,16 +753,14 @@ 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 "找ä¸åˆ°ç›®æ ‡æ–¹æ³•ï¼ 请指定一个有效的方法或把脚本附加到目标节点。"
+msgstr "找ä¸åˆ°ç›®æ ‡æ–¹æ³•ï¼ 请指定一个有效的方法或者把脚本附加到目标节点。"
#: editor/connections_dialog.cpp
msgid "Connect to Node:"
@@ -741,7 +771,6 @@ msgid "Connect to Script:"
msgstr "连接到脚本:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
msgstr "ä¿¡å·æº:"
@@ -775,7 +804,6 @@ msgid "Extra Call Arguments:"
msgstr "é¢å¤–调用å‚æ•°:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
msgstr "高级选项"
@@ -819,7 +847,6 @@ msgid "Connect"
msgstr "连接"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "ä¿¡å·:"
@@ -897,8 +924,7 @@ msgstr "收è—:"
msgid "Recent:"
msgstr "最近文件:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -932,11 +958,12 @@ msgid ""
msgstr "场景 '%s' 已被修改,é‡æ–°åŠ è½½åŽç”Ÿæ•ˆã€‚"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Resource '%s' is in use.\n"
"Changes will only take effect when reloaded."
-msgstr "资æº'%s'正在使用中,修改将在é‡æ–°åŠ è½½åŽç”Ÿæ•ˆã€‚"
+msgstr ""
+"资æº'%s'正在使用中。\n"
+"修改将åªåœ¨é‡æ–°åŠ è½½åŽç”Ÿæ•ˆã€‚"
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -983,9 +1010,8 @@ msgid "Owners Of:"
msgstr "拥有者:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Remove selected files from the project? (Can't be restored)"
-msgstr "确定从项目中删除文件?(此æ“作无法撤销)"
+msgstr "确定从项目中删除选定文件?(此æ“作无法撤销)"
#: editor/dependency_editor.cpp
msgid ""
@@ -994,7 +1020,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr "è¦åˆ é™¤çš„文件被其他资æºæ‰€ä¾èµ–,ä»ç„¶è¦åˆ é™¤å—?(无法撤销)"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "无法移除:"
@@ -1030,7 +1056,7 @@ msgstr "永久删除选中的%dæ¡é¡¹ç›®å—?(此æ“作无法撤销ï¼ï¼‰"
msgid "Show Dependencies"
msgstr "显示ä¾èµ–"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "查看孤立资æº"
@@ -1119,14 +1145,16 @@ msgid "License"
msgstr "许å¯è¯"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "第三方许å¯è¯"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot引擎ä¾èµ–第三方开æºä»£ç åº“,全部符åˆMIT 许å¯è¯çš„æ¡æ¬¾ã€‚下é¢åˆ—出所有第三方组"
@@ -1145,7 +1173,8 @@ msgid "Licenses"
msgstr "许å¯è¯"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "打开压缩包出错,éžzipæ ¼å¼ã€‚"
#: editor/editor_asset_installer.cpp
@@ -1162,7 +1191,6 @@ msgid "Success!"
msgstr "æˆåŠŸï¼"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "安装"
@@ -1390,7 +1418,6 @@ msgid "Rearrange Autoloads"
msgstr "é‡æŽ’åºAutoload"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid path."
msgstr "路径éžæ³•ã€‚"
@@ -1526,7 +1553,7 @@ msgstr "找ä¸åˆ°æ¨¡æ¿æ–‡ä»¶:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "以32ä½å¹³å°å¯¼å‡ºæ—¶ï¼Œå†…嵌的PCKä¸èƒ½å¤§äºŽ4GB。"
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1605,11 +1632,10 @@ msgid "File '%s' format is invalid, import aborted."
msgstr "文件 '%s' æ ¼å¼æ— æ•ˆï¼Œå¯¼å…¥ä¸­æ­¢ã€‚"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
-msgstr "é…置文件 '%s' 已存在。在导入之å‰é¦–先远程处ç†ï¼Œå¯¼å…¥å·²ä¸­æ­¢ã€‚"
+msgstr "é…置文件 '%s' 已存在。在导入之å‰å…ˆåˆ é™¤å®ƒï¼Œå¯¼å…¥å·²ä¸­æ­¢ã€‚"
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
@@ -1620,9 +1646,8 @@ msgid "Unset"
msgstr "未设置"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "当å‰é…置文件"
+msgstr "当å‰é…置文件:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1634,19 +1659,17 @@ msgid "New"
msgstr "新建"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "导入"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "导出"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "å¯ç”¨é…置文件"
+msgstr "å¯ç”¨é…置文件:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1701,7 +1724,7 @@ msgstr "在文件管ç†å™¨ä¸­æ˜¾ç¤º"
msgid "New Folder..."
msgstr "新建文件夹 ..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "刷新"
@@ -1752,7 +1775,7 @@ msgstr "å‰è¿›"
msgid "Go Up"
msgstr "上一级"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "切æ¢æ˜¾ç¤ºéšè—文件"
@@ -1777,24 +1800,28 @@ msgid "Move Favorite Down"
msgstr "å‘下移动收è—"
#: editor/editor_file_dialog.cpp
-msgid "Previous Folder"
-msgstr "上一个文件夹"
+msgid "Go to previous folder."
+msgstr "转到上个文件夹。"
#: editor/editor_file_dialog.cpp
-msgid "Next Folder"
-msgstr "下一个文件夹"
+msgid "Go to next folder."
+msgstr "转到下个文件夹。"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "转到父文件夹。"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "刷新文件。"
+
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "(å–消)收è—当å‰æ–‡ä»¶å¤¹ã€‚"
-#: editor/editor_file_dialog.cpp
-msgid "Toggle visibility of hidden files."
-msgstr "切æ¢æ˜¾ç¤ºéšè—文件。"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "切æ¢éšè—文件的å¯è§æ€§ã€‚"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1827,11 +1854,10 @@ msgid "ScanSources"
msgstr "扫ææºæ–‡ä»¶"
#: editor/editor_file_system.cpp
-#, fuzzy
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
-msgstr "%s 文件存在多ç§å¯¼å…¥æ–¹å¼ã€è‡ªåŠ¨å¯¼å…¥å¤±è´¥ã€‚"
+msgstr "ä¸åŒç±»åž‹çš„%s 文件存在多ç§å¯¼å…¥æ–¹å¼ï¼Œè‡ªåŠ¨å¯¼å…¥å¤±è´¥"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -2033,6 +2059,11 @@ msgstr "清除"
msgid "Clear Output"
msgstr "清空输出"
+#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
+msgid "New Window"
+msgstr "窗å£"
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "é¡¹ç›®å¯¼å‡ºå¤±è´¥ï¼Œé”™è¯¯ä»£ç  %d。"
@@ -2168,12 +2199,11 @@ 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
@@ -2344,6 +2374,15 @@ msgid "Pick a Main Scene"
msgstr "选择主场景"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "关闭场景"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "关闭场景"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "无法在: \"%s\" 上å¯ç”¨åŠ è½½é¡¹æ’件, é…置解æžå¤±è´¥ã€‚"
@@ -2446,6 +2485,11 @@ msgstr "è¿è¡Œæ­¤åœºæ™¯"
msgid "Close Tab"
msgstr "关闭标签页"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "关闭标签页"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "关闭其他标签页"
@@ -2455,9 +2499,8 @@ msgid "Close Tabs to the Right"
msgstr "关闭å³ä¾§"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "关闭全部"
+msgstr "关闭全部标签"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2500,6 +2543,10 @@ msgid "Go to previously opened scene."
msgstr "å‰å¾€ä¸Šä¸€ä¸ªæ‰“开的场景。"
#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "å¤åˆ¶æ–‡æœ¬"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "下一项"
@@ -2527,6 +2574,10 @@ msgstr "新建继承的场景…"
msgid "Open Scene..."
msgstr "打开场景..."
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "最近打开"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "ä¿å­˜åœºæ™¯"
@@ -2536,14 +2587,6 @@ msgid "Save All Scenes"
msgstr "ä¿å­˜æ‰€æœ‰åœºæ™¯"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "关闭场景"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "最近打开"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "转æ¢ä¸º..."
@@ -2573,25 +2616,36 @@ msgstr "æ¢å¤åœºæ™¯"
msgid "Miscellaneous project or scene-wide tools."
msgstr "其他工程或全场景工具。"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "项目"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "项目设置"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "工具"
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "导出..."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Install Android Build Template..."
+msgstr "安装 Android 构建模æ¿"
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "打开项目数æ®æ–‡ä»¶å¤¹"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "工具"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr "安装 Android 构建模æ¿"
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "查看孤立资æº"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2679,12 +2733,13 @@ msgstr ""
"å¼€å¯æ­¤é¡¹åŽï¼Œæ‰€æœ‰è„šæœ¬åœ¨ä¿å­˜æ—¶éƒ½ä¼šè¢«æ­£åœ¨è¿è¡Œçš„游æˆé‡æ–°åŠ è½½ã€‚\n"
"当使用远程设备调试时,使用网络文件系统能有效æ高编辑效率。"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "编辑器"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "编辑器设置"
#: editor/editor_node.cpp
@@ -2700,20 +2755,12 @@ 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 ""
+msgstr "系统命令行模å¼"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2728,14 +2775,16 @@ msgid "Open Editor Settings Folder"
msgstr "打开“编辑器设置â€æ–‡ä»¶å¤¹"
#: editor/editor_node.cpp
-msgid "Manage Editor Features"
+#, fuzzy
+msgid "Manage Editor Features..."
msgstr "管ç†ç¼–辑器功能"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "管ç†å¯¼å‡ºæ¨¡æ¿"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "帮助"
@@ -2743,12 +2792,13 @@ msgstr "帮助"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "æœç´¢"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "在线文档"
@@ -2822,14 +2872,12 @@ msgid "Spins when the editor window redraws."
msgstr "编辑器窗å£é‡ç»˜æ—¶æ—‹è½¬ã€‚"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "è¿žç»­"
+msgstr "æŒç»­æ›´æ–°"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "有更改时更新UI"
+msgstr "当有更改时更新"
#: editor/editor_node.cpp
#, fuzzy
@@ -2865,15 +2913,16 @@ 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 ""
@@ -2881,6 +2930,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"
@@ -3024,6 +3075,10 @@ msgstr "时间"
msgid "Calls"
msgstr "调用次数"
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "编辑文本:"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "å¯ç”¨"
@@ -3191,7 +3246,8 @@ msgid "Import From Node:"
msgstr "从节点中导入:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "é‡æ–°ä¸‹è½½"
#: editor/export_template_manager.cpp
@@ -3208,6 +3264,10 @@ msgid "Download"
msgstr "下载"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(丢失)"
@@ -3269,12 +3329,10 @@ msgid "No response."
msgstr "æ— å“应。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "请求失败。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "循环é‡å®šå‘。"
@@ -3288,13 +3346,20 @@ msgid "Download Complete."
msgstr "下载完æˆã€‚"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "无法ä¿å­˜ä¸»é¢˜åˆ°æ–‡ä»¶:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr "模æ¿å®‰è£…失败。å¯ä»¥åœ¨ '%s' 中找到这些问题模æ¿æ–‡æ¡£ã€‚"
#: editor/export_template_manager.cpp
-msgid "Error requesting url: "
+#, fuzzy
+msgid "Error requesting URL:"
msgstr "请求链接错误: "
#: editor/export_template_manager.cpp
@@ -3344,9 +3409,8 @@ msgid "SSL Handshake Error"
msgstr "SSL æ¡æ‰‹é”™è¯¯"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "无压缩资æº"
+msgstr "无压缩的Android Build资æº"
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3365,9 +3429,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"
@@ -3381,19 +3444,11 @@ msgstr "下载模æ¿"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "从列表中选择镜åƒï¼šï¼ˆShift+å•å‡»ï¼šåœ¨æµè§ˆå™¨ä¸­æ‰“开)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr "无法以å¯å†™æ–¹å¼æ‰“å¼€file_type_cache.cchï¼"
-
#: editor/filesystem_dock.cpp
msgid "Favorites"
msgstr "收è—夹"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr "因为文件系统没找到文件,ä¸èƒ½å®šä½åˆ°'%s'ï¼"
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "状æ€: 导入文件失败。请手动修å¤æ–‡ä»¶åŽé‡æ–°å¯¼å…¥ã€‚"
@@ -3427,14 +3482,14 @@ msgid "Provided name contains invalid characters."
msgstr "æ供的å称包å«æ— æ•ˆå­—符"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "å称包å«æ— æ•ˆå­—符。"
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "åŒå的文件夹已ç»å­˜åœ¨ã€‚"
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "å称包å«æ— æ•ˆå­—符。"
+
+#: editor/filesystem_dock.cpp
msgid "Renaming file:"
msgstr "é‡å‘½å文件:"
@@ -3451,9 +3506,8 @@ msgid "Duplicating folder:"
msgstr "å¤åˆ¶æ–‡ä»¶å¤¹:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
-msgstr "新建继承的场景…"
+msgstr "新继承的场景"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3494,6 +3548,11 @@ msgstr "æ‹·è´..."
msgid "Move To..."
msgstr "移动..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "新建场景"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
msgstr "新建脚本…"
@@ -3562,6 +3621,11 @@ msgstr "当å‰ä½ç½®å·²å­˜åœ¨ç›¸åŒå字的文件或目录。"
msgid "Overwrite"
msgstr "覆盖"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "从场景中创建"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "创建脚本"
@@ -3586,7 +3650,7 @@ msgstr "筛选:"
msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
-msgstr ""
+msgstr "包å«ä¸‹åˆ—扩展å的文件。å¯åœ¨é¡¹ç›®è®¾ç½®ä¸­å¢žåŠ æˆ–移除。"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -3622,6 +3686,14 @@ msgid "Search complete"
msgstr "æœç´¢å®Œæ¯•"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "添加到分组"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "从分组中移除"
+
+#: editor/groups_editor.cpp
msgid "Group name already exists."
msgstr "分组å称已存在。"
@@ -3629,12 +3701,23 @@ msgstr "分组å称已存在。"
msgid "Invalid group name."
msgstr "组å无效。"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "管ç†åˆ†ç»„"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "删除图片分组"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "分组"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "ä¸åœ¨åˆ†ç»„中的节点"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3647,12 +3730,12 @@ msgid "Nodes in Group"
msgstr "分组中的节点"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "添加到分组"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "从分组中移除"
+msgid "Group Editor"
+msgstr "分组编辑"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3858,7 +3941,8 @@ msgid "MultiNode Set"
msgstr "多节点组"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "请选择一个节点æ¥è®¾ç½®ä¿¡å·æˆ–分组。"
#: editor/plugin_config_dialog.cpp
@@ -4611,10 +4695,6 @@ msgid "View Files"
msgstr "查看文件"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "无法解æžä¸»æœºå:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "连接错误,请é‡è¯•ã€‚"
@@ -4627,14 +4707,47 @@ msgid "No response from host:"
msgstr "æœåŠ¡å™¨æ— å“应:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "无法解æžä¸»æœºå:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "请求失败,错误代ç :"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "请求失败。"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "无法ä¿å­˜ä¸»é¢˜åˆ°æ–‡ä»¶:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "请求失败,é‡å®šå‘次数过多"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "循环é‡å®šå‘。"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "请求失败,错误代ç :"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "时间"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr "文件hash值错误,该文件å¯èƒ½è¢«ç¯¡æ”¹ã€‚"
@@ -4675,6 +4788,11 @@ msgid "Idle"
msgstr "空闲"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "安装"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "é‡è¯•"
@@ -4703,13 +4821,17 @@ msgid "Last"
msgstr "最åŽä¸€é¡¹"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "全部"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "é‡æ–°å¯¼å…¥..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "æ’件"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4717,8 +4839,9 @@ msgid "Sort:"
msgstr "排åº:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "å选"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "正在请求。。"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4730,7 +4853,8 @@ msgid "Site:"
msgstr "站点:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "支æŒ..."
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4742,6 +4866,11 @@ msgid "Testing"
msgstr "测试"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "加载..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP资æºåŒ…"
@@ -4795,31 +4924,38 @@ msgid "Rotation Step:"
msgstr "旋转步长:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "移动垂直标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "创建新的垂直标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "删除垂直标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "移动水平标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "创建水平标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "移除水平标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "创建垂直水平标尺"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -4860,7 +4996,7 @@ msgstr "控件节点的定ä½ç‚¹å’Œè¾¹è·å€¼çš„预设。"
msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
-msgstr ""
+msgstr "激活åŽï¼Œç§»åŠ¨æŽ§åˆ¶èŠ‚点会更改å˜é”šç‚¹ï¼Œè€Œéžè¾¹è·ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -4904,6 +5040,11 @@ msgstr "粘贴姿势"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "清除姿势"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "从节点制作自定义骨骼"
@@ -4933,6 +5074,7 @@ msgid "Zoom Reset"
msgstr "é‡ç½®ç¼©æ”¾"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "选择模å¼"
@@ -4953,14 +5095,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+é¼ æ ‡å³é”®:显示鼠标点击ä½ç½®ä¸‹çš„所有节点列表"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "移动模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "旋转模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
msgstr "缩放模å¼"
@@ -4984,6 +5129,7 @@ msgid "Toggle snapping."
msgstr "开关å¸é™„。"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "使用å¸é™„"
@@ -5001,11 +5147,6 @@ msgid "Use Rotation Snap"
msgstr "使用旋转å¸é™„"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr "设置å¸é™„..."
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr "相对å¸é™„"
@@ -5019,6 +5160,11 @@ msgid "Smart Snapping"
msgstr "智能å¸é™„"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "设置å¸é™„..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "å¸é™„到父节点"
@@ -5132,18 +5278,16 @@ msgid "Preview Canvas Scale"
msgstr "ç²¾çµé›†é¢„览"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Translation mask for inserting keys."
msgstr "用于æ’入键的转æ¢æŽ©ç ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotation mask for inserting keys."
msgstr "用于æ’入键的旋转掩ç ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale mask for inserting keys."
-msgstr ""
+msgstr "æ’入键的缩放é®ç½©ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert keys (based on mask)."
@@ -5156,6 +5300,9 @@ 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
msgid "Auto Insert Key"
@@ -5239,16 +5386,6 @@ msgstr "设置处ç†ç¨‹åº"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "加载图片出错:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "图片中没有é€æ˜Žåº¦> 128çš„åƒç´ ..."
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr "加载Emission Mask(å‘å°„å±è”½ï¼‰"
@@ -5423,7 +5560,7 @@ msgstr "创建Trimesh(三维网格)形状"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Failed creating shapes!"
-msgstr ""
+msgstr "创建形状失败ï¼"
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -5570,14 +5707,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "表é¢çš„æºæ— æ•ˆï¼ˆæ— é¢ï¼‰ã€‚"
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "父级没有实体é¢æ¥å¡«å……。"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "无法绘制区域。"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "选择æºMesh:"
@@ -5661,20 +5790,27 @@ msgid "Generation Time (sec):"
msgstr "生æˆæ—¶é—´ï¼ˆç§’):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "é¢ä¸å«æœ‰åŒºåŸŸï¼"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "节点ä¸åŒ…å«å‡ ä½•ï¼ˆé¢ï¼‰ã€‚"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
-msgstr "没有é¢ï¼"
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "节点ä¸åŒ…å«å‡ ä½•ã€‚"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "节点ä¸åŒ…å«å‡ ä½•ï¼ˆé¢ï¼‰ã€‚"
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "节点ä¸åŒ…å«å‡ ä½•ã€‚"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6001,7 +6137,6 @@ msgid "Grid Settings"
msgstr "网格设置"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr "å¸é™„"
@@ -6107,12 +6242,9 @@ msgid "Error writing TextFile:"
msgstr "写入文本文件时出错:"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Error: could not load file."
-msgstr "错误:无法加载文件。"
-
-#: editor/plugins/script_editor_plugin.cpp
-msgid "Error could not load file."
-msgstr "错误,无法加载文件。"
+#, fuzzy
+msgid "Could not load file at:"
+msgstr "找ä¸åˆ°ç –å—:"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving file!"
@@ -6135,7 +6267,8 @@ msgid "Error Importing"
msgstr "导入出错"
#: editor/plugins/script_editor_plugin.cpp
-msgid "New TextFile..."
+#, fuzzy
+msgid "New Text File..."
msgstr "新建文本文档..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6218,6 +6351,11 @@ msgid "Open..."
msgstr "打开…"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "打开脚本"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "全部ä¿å­˜"
@@ -6255,13 +6393,13 @@ msgid "Save Theme"
msgstr "ä¿å­˜ä¸»é¢˜"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "关闭文档"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "关闭全部"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "关闭文档"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "è¿è¡Œ"
@@ -6351,6 +6489,11 @@ msgstr "调试器"
msgid "Search Results"
msgstr "æœç´¢ç»“æžœ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "清除近期的场景"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6421,8 +6564,9 @@ msgid "Syntax Highlighter"
msgstr "语法高亮显示"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "跳转到"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
@@ -6456,26 +6600,6 @@ msgid "Toggle Comment"
msgstr "切æ¢æ³¨é‡Š"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "切æ¢è‡ªç”±è§‚察模å¼"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "å‰å¾€ä¸‹ä¸€ä¸ªæ–­ç‚¹"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "å‰å¾€ä¸Šä¸€ä¸ªæ–­ç‚¹"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "移除类项目"
-
-#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
msgstr "切æ¢å è¡Œ"
@@ -6496,6 +6620,11 @@ msgid "Complete Symbol"
msgstr "代ç è¡¥å…¨"
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "缩放选中项"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr "修剪行åŽç©ºç™½"
@@ -6512,29 +6641,36 @@ msgid "Auto Indent"
msgstr "自动缩进"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "设置断点"
+msgid "Find Previous"
+msgstr "查找上一项"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "移除所有断点"
+msgid "Find in Files..."
+msgstr "在文件中查找..."
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Next Breakpoint"
-msgstr "å‰å¾€ä¸‹ä¸€ä¸ªæ–­ç‚¹"
+msgid "Contextual Help"
+msgstr "æœç´¢å…‰æ ‡ä½ç½®"
#: editor/plugins/script_text_editor.cpp
-msgid "Go to Previous Breakpoint"
-msgstr "å‰å¾€ä¸Šä¸€ä¸ªæ–­ç‚¹"
+#, fuzzy
+msgid "Toggle Bookmark"
+msgstr "切æ¢è‡ªç”±è§‚察模å¼"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "查找上一项"
+#, fuzzy
+msgid "Go to Next Bookmark"
+msgstr "å‰å¾€ä¸‹ä¸€ä¸ªæ–­ç‚¹"
#: editor/plugins/script_text_editor.cpp
-msgid "Find in Files..."
-msgstr "在文件中查找..."
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "å‰å¾€ä¸Šä¸€ä¸ªæ–­ç‚¹"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Remove All Bookmarks"
+msgstr "移除类项目"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6545,8 +6681,21 @@ msgid "Go to Line..."
msgstr "转到行..."
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr "æœç´¢å…‰æ ‡ä½ç½®"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "设置断点"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "移除所有断点"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "å‰å¾€ä¸‹ä¸€ä¸ªæ–­ç‚¹"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "å‰å¾€ä¸Šä¸€ä¸ªæ–­ç‚¹"
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
@@ -6726,9 +6875,15 @@ msgid "Rear"
msgstr "åŽæ–¹"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+#, fuzzy
+msgid "Align Transform with View"
msgstr "对é½è§†å›¾"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "选中项与视图对é½"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr "没有选中节点æ¥æ·»åŠ å®žä¾‹ã€‚"
@@ -6782,8 +6937,9 @@ msgid "Audio Listener"
msgstr "音频监å¬å™¨"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "å¯ç”¨å¤šæ™®å‹’效应"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "å…许过滤"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -6838,8 +6994,8 @@ msgid "Snap Nodes To Floor"
msgstr "将节点å¸é™„至地é¢"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Select Mode (Q)"
-msgstr "é€‰æ‹©æ¨¡å¼ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -6852,30 +7008,11 @@ msgstr ""
"Alt+é¼ æ ‡å³é”®ï¼šæ˜¾ç¤ºåˆ—表"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "移动模å¼ï¼ˆW)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "旋转模å¼ï¼ˆE)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "缩放模å¼ï¼ˆR)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "本地åæ ‡"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "æœ¬åœ°ç©ºé—´æ¨¡å¼ (%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "å¸é™„æ¨¡å¼ (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "底部视图"
@@ -6917,26 +7054,6 @@ msgid "Focus Selection"
msgstr "选中选中项"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "选中项与视图对é½"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Select"
-msgstr "选择工具"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "移动工具"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "旋转工具"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "缩放工具"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "切æ¢è‡ªç”±è§‚察模å¼"
@@ -6992,7 +7109,8 @@ msgstr "显示网格"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "设置"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7194,13 +7312,12 @@ msgid "Animation Frames:"
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 "从精çµè¡¨æ ¼ä¸­æ·»åŠ å¸§"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -7219,9 +7336,8 @@ msgid "Move (After)"
msgstr "å¾€åŽç§»åŠ¨"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Select Frames"
-msgstr "堆栈帧(Stack Frames)"
+msgstr "选择帧"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7286,17 +7402,13 @@ msgstr "步长(秒):"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
-msgstr "ä¹æœˆï¼š"
+msgstr "间隔:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "TextureRegion"
msgstr "TextureRegion 纹ç†åŒºåŸŸ"
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "无法ä¿å­˜ä¸»é¢˜åˆ°æ–‡ä»¶:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "添加所有项目"
@@ -7377,8 +7489,9 @@ msgid "Checked Radio Item"
msgstr "已选å•é€‰é¡¹ç›®"
#: editor/plugins/theme_editor_plugin.cpp
+#, fuzzy
msgid "Named Sep."
-msgstr ""
+msgstr "称为 Sep。"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
@@ -7386,12 +7499,12 @@ msgstr "å­èœå•(Submenu)"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "项目(Item)"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "项目(Item)"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7426,7 +7539,7 @@ msgstr "å…许编辑å­å­™èŠ‚点"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "å­æ ‘"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
@@ -7498,14 +7611,6 @@ msgid "Transpose"
msgstr "转置"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr "沿X轴翻转"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr "沿Y轴翻转"
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr "ç¦ç”¨æ™ºèƒ½ç£è´´(Autotile)"
@@ -7519,10 +7624,13 @@ msgid "Paint Tile"
msgstr "绘制ç£è´´"
#: editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift+é¼ æ ‡å³é”®ï¼šç»˜åˆ¶ç›´çº¿\n"
+"Shift+Ctrl+é¼ æ ‡å³é”®ï¼šç»˜åˆ¶çŸ©å½¢"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
@@ -7826,7 +7934,11 @@ msgstr "ä¸èƒ½ä¿®æ”¹è¯¥å±žæ€§ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "TileSet"
-msgstr "瓦片集"
+msgstr "ç –å—集"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr "åªä½¿ç”¨GLES3"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -7849,7 +7961,7 @@ msgstr "å‘é‡"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "布尔值"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -7858,7 +7970,7 @@ msgstr "添加输入事件"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "增加输出端å£"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -7917,6 +8029,11 @@ msgid "Duplicate Nodes"
msgstr "å¤åˆ¶èŠ‚点"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "粘贴节点"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Delete Nodes"
msgstr "删除节点"
@@ -7938,6 +8055,11 @@ msgstr "ç¯å…‰"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "新节点"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "新节点"
@@ -7948,7 +8070,7 @@ msgstr "转到函数"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "颜色è¿ç®—符。"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -7957,11 +8079,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
@@ -7969,12 +8091,14 @@ msgid "Sepia function."
msgstr "é‡å‘½å函数"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Burn operator."
-msgstr ""
+msgstr "Burn æ“作。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Darken operator."
-msgstr ""
+msgstr "Darken è¿ç®—符。"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -7982,323 +8106,388 @@ msgid "Difference operator."
msgstr "ä»…ä¸åŒ"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Dodge operator."
-msgstr ""
+msgstr "Dodge è¿ç®—符。"
#: 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 "Lightenè¿ç®—."
#: 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
+#, fuzzy
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr "返回两个å‚数之间%s比较的布尔结果。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr "等于 (==)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr "大于 (>)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr "大于等于 (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
-msgstr ""
+msgstr "如果æ供的标é‡ç›¸ç­‰ï¼Œæ›´å¤§æˆ–æ›´å°ï¼Œåˆ™è¿”回关è”çš„å‘é‡ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
-"Returns an associated vector if the provided boolean value is true or false."
-msgstr ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr "返回 INF 和标é‡å‚数之间比较的布尔结果。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr "返回 NaN 和标é‡å‚数之间比较的布尔结果。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr "å°äºŽ (*)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "å°äºŽæˆ–等于 (+)"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Not Equal (!=)"
+msgstr "ä¸ç­‰äºŽï¼ˆ!=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr "如果æ供的布尔值为true或false,则返回关è”çš„å‘é‡ã€‚"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr "返回两个å‚数之间比较的布尔结果。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr "返回 INF(或 NaN)和标é‡å‚数之间比较的布尔结果。"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
-msgstr "修改Vec常é‡ç³»æ•°"
+msgstr "布尔常é‡ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "布尔统一。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "'%s'为所有ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "å¸é™„到父节点"
+msgstr "输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "'%s'为顶点和片段ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "'%s'为片段和ç¯å…‰ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "'%s' 为片段ç€è‰²å™¨æ¨¡å¼çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "'%s' 为ç¯å…‰ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "'%s' 为顶点ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "'%s'为顶点和片段ç€è‰²å™¨æ¨¡æ¿çš„输入å‚数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "修改Function Scalar"
+msgstr "Scalar 函数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
-msgstr "更改标é‡è¿ç®—符(Scalar Operator)"
+msgstr "æ ‡é‡è¿ç®—符(Scalar Operator)。"
#: 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 ""
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr "返回å‚æ•°çš„ååŒæ›²ä½™å¼¦å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "返回å‚æ•°çš„å正弦值。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr "返回å‚æ•°çš„ååŒæ›²æ­£å¼¦å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+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 ""
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr "返回å‚æ•°çš„ååŒæ›²æ­£åˆ‡å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr ""
+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 ""
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr "返回å‚æ•°çš„åŒæ›²ä½™å¼¦å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+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 ""
+msgid "Finds the nearest integer to the parameter."
+msgstr "查找å‚数最近的整数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
-msgstr ""
+msgid "Finds the nearest even integer to the parameter."
+msgstr "查找å‚数最近的å¶æ•°ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+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 ""
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr "返回å‚æ•°çš„åŒæ›²æ­£å¼¦å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "返回å‚数的平方根。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"如果'x'å°äºŽ'edge0'则返回0.0,如果x大于'edge1'则返回1.0。å¦åˆ™åœ¨0.0å’Œ1.0之间返"
+"回Hermite多项å¼æ’值的值。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( 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 ""
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr "返回å‚æ•°çš„åŒæ›²æ­£åˆ‡å€¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
-msgstr ""
+#, fuzzy
+msgid "Finds the truncated value of the parameter."
+msgstr "查找å‚数的截断值。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
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
+#, fuzzy
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
@@ -8312,20 +8501,25 @@ msgstr "修改Uniform Scalar"
#: 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 lookup."
+msgstr "修改Uniform纹ç†"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "Cubic texture uniform."
+msgid "2D texture uniform lookup."
msgstr "修改Uniform纹ç†"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr "修改Uniform纹ç†"
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8335,7 +8529,7 @@ msgstr "å˜æ¢å¯¹è¯æ¡†..."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8346,31 +8540,31 @@ msgstr ""
#: 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 ""
+msgid "Calculates the determinant of a transform."
+msgstr "计算å˜æ¢çš„行列å¼ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
-msgstr ""
+msgid "Calculates the inverse of a transform."
+msgstr "计算å˜æ¢çš„倒数。"
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
-msgstr ""
+msgid "Calculates the transpose of a transform."
+msgstr "计算一个å˜æ¢çš„转置。"
#: 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
@@ -8394,113 +8588,138 @@ msgstr "更改 Vec è¿ç®—符(Vec Operator)"
#: 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 ""
-"Returns a vector that points in the same direction as a reference vector. "
+"Returns the vector that points in the same direction as a reference vector. "
"The function has three vector parameters : N, the vector to orient, I, the "
"incident vector, and Nref, the reference vector. If the dot product of I and "
"Nref is smaller than zero the return value is N. Otherwise -N is returned."
msgstr ""
+"返回指å‘与å‚考å‘é‡ç›¸åŒæ–¹å‘çš„å‘é‡ã€‚该函数有三个å‘é‡å‚数: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
+#, fuzzy
+msgid "Linear interpolation between two vectors using scalar."
+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 "
+"Returns the 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 ""
+msgid "Returns the vector that points in the direction of refraction."
+msgstr "返回指å‘折射方å‘的矢é‡ã€‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"如果'x'å°äºŽ'edge0'则返回0.0,如果x大于'edge1'则返回1.0。å¦åˆ™åœ¨0.0å’Œ1.0之间返"
+"回Hermite多项å¼æ’值的值。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"如果'x'å°äºŽ'edge0'则返回0.0,如果x大于'edge1'则返回1.0。å¦åˆ™åœ¨0.0å’Œ1.0之间返"
+"回Hermite多项å¼æ’值的值。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"如果'x'å°äºŽ'edge'则返回0.0,å¦åˆ™è¿”回1.0。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Step function( scalar(edge), scalar(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
@@ -8518,6 +8737,8 @@ 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 ""
@@ -8526,47 +8747,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8737,6 +8965,10 @@ msgid "Export templates for this platform are missing:"
msgstr "没有下列平å°çš„导出模æ¿:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "管ç†å¯¼å‡ºæ¨¡æ¿"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "导出为调试"
@@ -8892,6 +9124,15 @@ msgid "Unnamed Project"
msgstr "未命å项目"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Missing Project"
+msgstr "导入现有项目"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
msgstr "无法打开ä½äºŽâ€œ%sâ€çš„相应项目."
@@ -8982,8 +9223,8 @@ msgstr "移除此项目(项目的文件ä¸å—å½±å“)"
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "移除此项目(项目的文件ä¸å—å½±å“)"
#: editor/project_manager.cpp
@@ -9004,11 +9245,12 @@ msgstr "您确认è¦æ‰«æ%s目录下现有的Godot项目å—?"
#: editor/project_manager.cpp
msgid "Project Manager"
-msgstr "项目管ç†å‘˜"
+msgstr "项目管ç†å™¨"
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr "项目列表"
+#, fuzzy
+msgid "Projects"
+msgstr "项目"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9032,10 +9274,6 @@ msgid "Templates"
msgstr "模æ¿"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "退出"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr "ç«‹å³é‡æ–°å¯åŠ¨"
@@ -9377,6 +9615,10 @@ msgstr "区域:"
msgid "AutoLoad"
msgstr "自动加载(AutoLoad)"
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "æ’件"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr "置零"
@@ -9429,14 +9671,6 @@ msgstr "选择虚方法"
msgid "Select Method"
msgstr "选择方法"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr "无法执行PVRTC工具:"
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr "无法加载使用PVRTC工具转æ¢çš„图片:"
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
msgid "Batch Rename"
msgstr "批é‡é‡å‘½å"
@@ -9728,6 +9962,11 @@ msgid "Remove Node(s)"
msgstr "移除节点"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "更改输入å称"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -9772,6 +10011,11 @@ msgid "Extend Script"
msgstr "打开脚本"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Reparent to New Node"
+msgstr "é‡è®¾çˆ¶èŠ‚点"
+
+#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
msgstr "创建场景根节点"
@@ -9846,24 +10090,27 @@ msgid "Node configuration warning:"
msgstr "节点é…置警告:"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
"节点具有信å·è¿žæŽ¥å’Œåˆ†ç»„。\n"
"å•å‡»ä»¥æ˜¾ç¤ºä¿¡å·æŽ¥å£ã€‚"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
"节点有信å·è¿žæŽ¥ã€‚\n"
"å•å‡»æŸ¥çœ‹ä¿¡å·æ ã€‚"
#: editor/scene_tree_editor.cpp
+#, fuzzy
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
"分组中的节点。\n"
@@ -9970,6 +10217,11 @@ msgid "Error loading script from %s"
msgstr "从%s加载脚本出错"
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "覆盖"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
@@ -10003,7 +10255,8 @@ msgid "Script is valid."
msgstr "脚本å¯ç”¨"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+#, fuzzy
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr "ä»…å…许使用: a-z, A-Z, 0-9 或 _"
#: editor/script_create_dialog.cpp
@@ -10166,6 +10419,10 @@ msgid "Change Shortcut"
msgstr "更改快æ·æ–¹å¼"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "编辑器设置"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "å¿«æ·é”®"
@@ -10579,10 +10836,30 @@ msgid "Set Variable Type"
msgstr "设置å˜é‡ç±»åž‹"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "与引擎内置类型å称冲çªã€‚"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "新建一个四边形。"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "å˜é‡ï¼š"
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "新建一个四边形。"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "创建新多边形。"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr "å称ä¸æ˜¯æœ‰æ•ˆçš„标识符:"
@@ -10768,10 +11045,6 @@ msgid "Cut Nodes"
msgstr "剪切节点"
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr "粘贴节点"
-
-#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
msgstr "编辑æˆå‘˜"
@@ -11337,7 +11610,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "角度宽于 90 度的 SpotLight 无法投射出阴影。"
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -11436,6 +11709,7 @@ msgid ""
"WorldEnvironment requires its \"Environment\" property to contain an "
"Environment to have a visible effect."
msgstr ""
+"WorldEnvironment è¦æ±‚其“Environmentâ€å±žæ€§æ˜¯ä¸€ä¸ª Environment,以产生å¯è§æ•ˆæžœã€‚"
#: scene/3d/world_environment.cpp
msgid ""
@@ -11497,8 +11771,9 @@ msgid "Pick a color from the screen."
msgstr "从å±å¹•ä¸­é€‰æ‹©ä¸€ç§é¢œè‰²ã€‚"
#: scene/gui/color_picker.cpp
+#, fuzzy
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
#, fuzzy
@@ -11585,35 +11860,23 @@ msgstr ""
"示其内容,使其æˆä¸ºå­æŽ§ä»¶çš„所以它å¯ä»¥æœ‰ä¸€ä¸ªå°ºå¯¸å¤§å°å€¼ã€‚å¦åˆ™è¯·è®¾ç½®ä¸ºRender "
"target,并将其内部纹ç†åˆ†é…给一些节点以显示。"
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "åˆå§‹åŒ–FreeType出错。"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "未知的字体格å¼ã€‚"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "加载字体出错。"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "字体大å°éžæ³•ã€‚"
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr "输入"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
-msgstr "éžæ³•çš„ç€è‰²å™¨æºã€‚"
+msgstr "预览的æºèµ„æºæ— æ•ˆã€‚"
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
msgstr "éžæ³•çš„ç€è‰²å™¨æºã€‚"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "该类型的比较函数无效。"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr "对函数的赋值。"
@@ -11630,6 +11893,124 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸­æŒ‡å®šã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å…许修改常é‡ã€‚"
+#~ msgid "No Matches"
+#~ msgstr "无匹é…项"
+
+#~ msgid ""
+#~ "Can't open file_type_cache.cch for writing, not saving file type cache!"
+#~ msgstr "无法以å¯å†™æ–¹å¼æ‰“å¼€file_type_cache.cchï¼"
+
+#~ msgid "Cannot navigate to '%s' as it has not been found in the file system!"
+#~ msgstr "因为文件系统没找到文件,ä¸èƒ½å®šä½åˆ°'%s'ï¼"
+
+#~ msgid "Error loading image:"
+#~ msgstr "加载图片出错:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "图片中没有é€æ˜Žåº¦> 128çš„åƒç´ ..."
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "父级没有实体é¢æ¥å¡«å……。"
+
+#~ msgid "Couldn't map area."
+#~ msgstr "无法绘制区域。"
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "é¢ä¸å«æœ‰åŒºåŸŸï¼"
+
+#~ msgid "No faces!"
+#~ msgstr "没有é¢ï¼"
+
+#~ msgid "Error: could not load file."
+#~ msgstr "错误:无法加载文件。"
+
+#~ msgid "Error could not load file."
+#~ msgstr "错误,无法加载文件。"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "å¯ç”¨å¤šæ™®å‹’效应"
+
+#~ msgid "Select Mode (Q)"
+#~ msgstr "é€‰æ‹©æ¨¡å¼ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "移动模å¼ï¼ˆW)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "旋转模å¼ï¼ˆE)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "缩放模å¼ï¼ˆR)"
+
+#~ msgid "Local Coords"
+#~ msgstr "本地åæ ‡"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "å¸é™„æ¨¡å¼ (%s)"
+
+#~ msgid "Tool Select"
+#~ msgstr "选择工具"
+
+#~ msgid "Tool Move"
+#~ msgstr "移动工具"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "旋转工具"
+
+#~ msgid "Tool Scale"
+#~ msgstr "缩放工具"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "移除此项目(项目的文件ä¸å—å½±å“)"
+
+#~ msgid "Project List"
+#~ msgstr "项目列表"
+
+#~ msgid "Exit"
+#~ msgstr "退出"
+
+#~ msgid "Could not execute PVRTC tool:"
+#~ msgstr "无法执行PVRTC工具:"
+
+#~ msgid "Can't load back converted image using PVRTC tool:"
+#~ msgstr "无法加载使用PVRTC工具转æ¢çš„图片:"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "åˆå§‹åŒ–FreeType出错。"
+
+#~ msgid "Unknown font format."
+#~ msgstr "未知的字体格å¼ã€‚"
+
+#~ msgid "Error loading font."
+#~ msgstr "加载字体出错。"
+
+#~ msgid "Invalid font size."
+#~ msgstr "字体大å°éžæ³•ã€‚"
+
+#~ msgid "Previous Folder"
+#~ msgstr "上一个文件夹"
+
+#~ msgid "Next Folder"
+#~ msgstr "下一个文件夹"
+
+#~ msgid "Automatically Open Screenshots"
+#~ msgstr "自动打开截图"
+
+#~ msgid "Open in an external image editor."
+#~ msgstr "使用外部图åƒç¼–辑器打开。"
+
+#~ msgid "Reverse"
+#~ msgstr "å选"
+
+#~ msgid "Mirror X"
+#~ msgstr "沿X轴翻转"
+
+#~ msgid "Mirror Y"
+#~ msgstr "沿Y轴翻转"
+
#~ msgid "Generating solution..."
#~ msgstr "正在创生æˆå†³æ–¹æ¡ˆ..."
@@ -12208,9 +12589,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Erase selection"
#~ msgstr "擦除选中"
-#~ msgid "Could not find tile:"
-#~ msgstr "找ä¸åˆ°ç –å—:"
-
#~ msgid "Item name or ID:"
#~ msgstr "项目å称或ID:"
@@ -12474,9 +12852,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Info"
#~ msgstr "ä¿¡æ¯"
-#~ msgid "Re-Import..."
-#~ msgstr "é‡æ–°å¯¼å…¥..."
-
#~ msgid "No bit masks to import!"
#~ msgstr "没有è¦å¯¼å…¥çš„bit masksï¼"
@@ -12866,9 +13241,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Stereo"
#~ msgstr "立体声"
-#~ msgid "Window"
-#~ msgstr "窗å£"
-
#~ msgid "Scaling to %s%%."
#~ msgstr "缩放到%s%%。"
@@ -13103,9 +13475,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Add Image Group"
#~ msgstr "添加图片分组"
-#~ msgid "Delete Image Group"
-#~ msgstr "删除图片分组"
-
#~ msgid "Project Export Settings"
#~ msgstr "项目导出设置"
@@ -13190,9 +13559,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Export Project PCK"
#~ msgstr "导出项目PCK文件"
-#~ msgid "Export..."
-#~ msgstr "导出..."
-
#~ msgid "Project Export"
#~ msgstr "项目导出"
@@ -13268,9 +13634,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Deploy File Server Clients"
#~ msgstr "部署文件æœåŠ¡å®¢æˆ·ç«¯"
-#~ msgid "Group Editor"
-#~ msgstr "分组编辑"
-
#~ msgid "Keep Existing, Merge with New"
#~ msgstr "ä¿ç•™å·²æœ‰ï¼Œä¸Žæ–°çš„åˆå¹¶ã€‚"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 4488955481..89e0d28fcf 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -59,7 +59,6 @@ msgid "On call to '%s':"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr ""
@@ -137,6 +136,31 @@ msgstr ""
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "動畫變化數值"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "動畫變化éŽæ¸¡"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "動畫變化éŽæ¸¡"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "動畫變化數值"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "動畫軌跡變化數值模å¼"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "更改動畫å稱:"
@@ -671,17 +695,18 @@ msgid "Line Number:"
msgstr "行數:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+#, fuzzy
+msgid "Replaced %d occurrence(s)."
+msgstr "å–代了 %d 個。"
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "沒有相åŒ"
+msgid "%d match."
+msgstr ""
-#: editor/code_editor.cpp
+#: editor/code_editor.cpp editor/editor_help.cpp
#, fuzzy
-msgid "Replaced %d occurrence(s)."
-msgstr "å–代了 %d 個。"
+msgid "%d matches."
+msgstr "沒有相åŒ"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -920,8 +945,7 @@ msgstr "最愛:"
msgid "Recent:"
msgstr "最近:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -1016,7 +1040,7 @@ msgid ""
"Remove them anyway? (no undo)"
msgstr ""
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
#, fuzzy
msgid "Cannot remove:"
msgstr "無法移除:\n"
@@ -1054,7 +1078,7 @@ msgstr ""
msgid "Show Dependencies"
msgstr ""
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr ""
@@ -1149,14 +1173,14 @@ msgstr "授權æ¢æ¬¾"
#: editor/editor_about.cpp
#, fuzzy
-msgid "Thirdparty License"
+msgid "Third-party Licenses"
msgstr "第三方授權æ¢æ¬¾"
#: editor/editor_about.cpp
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
@@ -1176,7 +1200,7 @@ msgid "Licenses"
msgstr "授權æ¢æ¬¾"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+msgid "Error opening package file, not in ZIP format."
msgstr ""
#: editor/editor_asset_installer.cpp
@@ -1194,7 +1218,6 @@ msgid "Success!"
msgstr "æˆåŠŸï¼"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "安è£"
@@ -1708,12 +1731,11 @@ msgid "New"
msgstr ""
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "å°Žå…¥"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "匯出"
@@ -1786,7 +1808,7 @@ msgstr "é–‹å•Ÿ Project Manager?"
msgid "New Folder..."
msgstr "新增資料夾"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "é‡æ–°æ•´ç†"
@@ -1837,7 +1859,7 @@ msgstr ""
msgid "Go Up"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件"
@@ -1865,27 +1887,32 @@ msgstr "下移最愛"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "上一個tab"
+msgid "Go to previous folder."
+msgstr "無法新增資料夾"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "新增資料夾"
+msgid "Go to next folder."
+msgstr "無法新增資料夾"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "無法新增資料夾"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "在幫助檔æœå°‹"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "無法新增資料夾"
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2144,6 +2171,10 @@ msgstr "清空"
msgid "Clear Output"
msgstr "下一個腳本"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr ""
@@ -2458,6 +2489,15 @@ msgid "Pick a Main Scene"
msgstr "é¸æ“‡ä¸»å ´æ™¯"
#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "關閉場景"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "關閉場景"
+
+#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
@@ -2564,6 +2604,11 @@ msgstr "é‹è¡Œå ´æ™¯"
msgid "Close Tab"
msgstr "關閉"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "關閉"
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr ""
@@ -2624,6 +2669,11 @@ msgstr "上一個開啟的scene"
#: editor/editor_node.cpp
#, fuzzy
+msgid "Copy Text"
+msgstr "複製路徑"
+
+#: editor/editor_node.cpp
+#, fuzzy
msgid "Next tab"
msgstr "下一個"
@@ -2653,6 +2703,10 @@ msgstr ""
msgid "Open Scene..."
msgstr "開啓場景"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "開啓最近的"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "儲存場景"
@@ -2663,14 +2717,6 @@ msgid "Save All Scenes"
msgstr "儲存所有場景"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "關閉場景"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "開啓最近的"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "轉為..."
@@ -2700,26 +2746,37 @@ msgstr ""
msgid "Miscellaneous project or scene-wide tools."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "專案"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "專案設定"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "工具"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "匯出"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
#, fuzzy
msgid "Open Project Data Folder"
msgstr "é–‹å•Ÿ Project Manager?"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "工具"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "把資æºå¦å­˜ç‚º..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2800,12 +2857,13 @@ msgid ""
"filesystem."
msgstr ""
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "編輯器"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "編輯器設定"
#: editor/editor_node.cpp
@@ -2823,15 +2881,6 @@ 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 "全螢幕"
@@ -2856,14 +2905,15 @@ msgstr "編輯器設定"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "管ç†è¼¸å‡ºç¯„本"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "管ç†è¼¸å‡ºç¯„本"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "幫助"
@@ -2871,12 +2921,13 @@ msgstr "幫助"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "æœå°‹"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
msgstr "關閉場景"
@@ -3164,6 +3215,11 @@ msgstr "時間:"
msgid "Calls"
msgstr ""
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "檔案"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr ""
@@ -3331,7 +3387,7 @@ msgstr ""
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Re-Download"
+msgid "Redownload"
msgstr "é‡æ–°ä¸‹è¼‰"
#: editor/export_template_manager.cpp
@@ -3348,6 +3404,10 @@ msgid "Download"
msgstr "下載"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr ""
@@ -3413,13 +3473,11 @@ msgid "No response."
msgstr "沒有回應。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request Failed."
msgstr "請求失敗。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr ""
@@ -3434,14 +3492,19 @@ msgid "Download Complete."
msgstr "下載出ç¾éŒ¯èª¤"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "無法移除:\n"
+
+#: editor/export_template_manager.cpp
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr ""
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr "請求時出ç¾éŒ¯èª¤"
#: editor/export_template_manager.cpp
@@ -3539,20 +3602,12 @@ msgstr "移除é¸é …"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "最愛:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3588,15 +3643,15 @@ msgid "Provided name contains invalid characters."
msgstr "有效字符:"
#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Name contains invalid characters."
msgstr "有效字符:"
#: editor/filesystem_dock.cpp
-msgid "A file or folder with this name already exists."
-msgstr ""
-
-#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Renaming file:"
msgstr "儲存TileSet時出ç¾éŒ¯èª¤ï¼"
@@ -3662,6 +3717,11 @@ msgstr "複製"
msgid "Move To..."
msgstr "æ¬åˆ°..."
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "新增場景"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3732,6 +3792,11 @@ msgstr ""
msgid "Overwrite"
msgstr ""
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "儲存場景"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr ""
@@ -3801,6 +3866,14 @@ msgid "Search complete"
msgstr "在幫助檔æœå°‹"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "錯誤:動畫å稱已存在ï¼"
@@ -3810,12 +3883,22 @@ msgstr "錯誤:動畫å稱已存在ï¼"
msgid "Invalid group name."
msgstr "無效å稱"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "專案"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "刪除佈局"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+msgid "Nodes Not in Group"
msgstr ""
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3829,12 +3912,13 @@ msgid "Nodes in Group"
msgstr ""
#: editor/groups_editor.cpp
-msgid "Add to Group"
+msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr ""
+#, fuzzy
+msgid "Group Editor"
+msgstr "開啟資料夾"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -4051,7 +4135,7 @@ msgid "MultiNode Set"
msgstr ""
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+msgid "Select a single node to edit its signals and groups."
msgstr ""
#: editor/plugin_config_dialog.cpp
@@ -4852,10 +4936,6 @@ msgid "View Files"
msgstr "檔案"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr ""
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr ""
@@ -4868,15 +4948,47 @@ msgid "No response from host:"
msgstr "主機沒有回應:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request failed, return code:"
msgstr "請求失敗,"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "請求失敗。"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "無法移除:\n"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "請求失敗,"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "時間:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4920,6 +5032,11 @@ msgid "Idle"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "安è£"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "é‡è©¦"
@@ -4950,13 +5067,17 @@ msgid "Last"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "全部"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "å°Žå…¥"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "æ’件"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4964,8 +5085,9 @@ msgid "Sort:"
msgstr "排åºï¼š"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr ""
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "請求中..."
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4977,8 +5099,9 @@ msgid "Site:"
msgstr "地å€:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
-msgstr ""
+#, fuzzy
+msgid "Support"
+msgstr "å°Žå…¥"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -4989,6 +5112,11 @@ msgid "Testing"
msgstr "測試"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "載入"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "Assets ZIP 檔"
@@ -5039,35 +5167,39 @@ msgid "Rotation Step:"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Move Vertical Guide"
+msgstr "新增"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new vertical guide"
+msgid "Create Vertical Guide"
msgstr "新增"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
-msgstr ""
+#, fuzzy
+msgid "Remove Vertical Guide"
+msgstr "åªé™é¸ä¸­"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
-msgstr ""
+#, fuzzy
+msgid "Move Horizontal Guide"
+msgstr "åªé™é¸ä¸­"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Create new horizontal guide"
+msgid "Create Horizontal Guide"
msgstr "新增"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
-msgid "Remove horizontal guide"
+msgid "Remove Horizontal Guide"
msgstr "åªé™é¸ä¸­"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
-msgstr ""
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
+msgstr "新增"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5153,6 +5285,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "é‹è¡Œå ´æ™¯"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "é‹è¡Œå ´æ™¯"
@@ -5183,6 +5320,7 @@ msgid "Zoom Reset"
msgstr "縮å°"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "é¸æ“‡æ¨¡å¼"
@@ -5203,14 +5341,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "移動模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "é¸æ“‡æ¨¡å¼"
@@ -5235,6 +5376,7 @@ msgid "Toggle snapping."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr ""
@@ -5252,11 +5394,6 @@ msgid "Use Rotation Snap"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Configure Snap..."
-msgstr ""
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
msgstr ""
@@ -5269,6 +5406,11 @@ msgid "Smart Snapping"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
msgstr ""
@@ -5485,16 +5627,6 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr ""
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5816,14 +5948,6 @@ msgid "Surface source is invalid (no faces)."
msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr ""
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr ""
@@ -5908,19 +6032,23 @@ msgid "Generation Time (sec):"
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
+msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "The geometry doesn't contain any faces."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
@@ -6262,7 +6390,6 @@ msgid "Grid Settings"
msgstr "設定"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6372,12 +6499,7 @@ msgstr "儲存TileSet時出ç¾éŒ¯èª¤ï¼"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "無法新增資料夾"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "無法新增資料夾"
#: editor/plugins/script_editor_plugin.cpp
@@ -6407,7 +6529,7 @@ msgstr "載入錯誤:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "新增資料夾"
#: editor/plugins/script_editor_plugin.cpp
@@ -6494,6 +6616,11 @@ msgid "Open..."
msgstr "é–‹å•Ÿ"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "下一個腳本"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr ""
@@ -6535,13 +6662,13 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Close Docs"
-msgstr "關閉場景"
+msgid "Close All"
+msgstr "關閉"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Close All"
-msgstr "關閉"
+msgid "Close Docs"
+msgstr "關閉場景"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
@@ -6632,6 +6759,11 @@ msgstr ""
msgid "Search Results"
msgstr "在幫助檔æœå°‹"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "關閉場景"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6705,6 +6837,7 @@ msgid "Syntax Highlighter"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6742,26 +6875,6 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "全螢幕"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "跳到下一步"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "跳到上一步"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "移除é¸é …"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "跳到行"
@@ -6782,6 +6895,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "縮放selection"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6800,32 +6918,37 @@ msgid "Auto Indent"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
+msgid "Find Previous"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "篩é¸æª”案..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "跳到下一步"
+msgid "Toggle Bookmark"
+msgstr "全螢幕"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "跳到上一步"
+msgid "Go to Next Bookmark"
+msgstr "跳到下一步"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr ""
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "跳到上一步"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "篩é¸æª”案..."
+msgid "Remove All Bookmarks"
+msgstr "移除é¸é …"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -6838,9 +6961,24 @@ msgid "Go to Line..."
msgstr "跳到行"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
msgstr ""
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "跳到下一步"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "跳到上一步"
+
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
"This shader has been modified on on disk.\n"
@@ -7023,7 +7161,11 @@ msgid "Rear"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
@@ -7082,8 +7224,9 @@ msgid "Audio Listener"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "啟用多普拉效應"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "更改動畫長度"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -7138,9 +7281,8 @@ msgid "Snap Nodes To Floor"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "é¸æ“‡æ¨¡å¼"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7150,31 +7292,10 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+msgid "Use Local Space"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Snap Mode (%s)"
-msgstr "é¸æ“‡æ¨¡å¼"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr ""
@@ -7216,27 +7337,6 @@ msgid "Focus Selection"
msgstr "åªé™é¸ä¸­"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "所有é¸é …"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr ""
-
-#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Toggle Freelook"
msgstr "全螢幕"
@@ -7292,7 +7392,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "設定"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7603,10 +7704,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr ""
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr ""
@@ -7697,11 +7794,11 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 1"
+msgid "Subitem 1"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Item 2"
+msgid "Subitem 2"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
@@ -7814,14 +7911,6 @@ msgid "Transpose"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7836,8 +7925,8 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8153,6 +8242,10 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "新增訊號"
@@ -8240,6 +8333,12 @@ msgid "Duplicate Nodes"
msgstr "複製動畫幀"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Paste Nodes"
+msgstr "貼上"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "ä¸é¸"
@@ -8262,6 +8361,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "新增資料夾"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "新增資料夾"
@@ -8337,6 +8441,22 @@ msgid "Color uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8344,10 +8464,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8437,7 +8591,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8445,7 +8599,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8457,7 +8611,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8474,7 +8628,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8543,11 +8697,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8563,7 +8717,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8574,7 +8728,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8583,7 +8737,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8591,11 +8745,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8635,11 +8789,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8649,7 +8807,7 @@ msgstr "縮放selection"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8667,15 +8825,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8727,7 +8885,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8742,6 +8900,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8755,19 +8917,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8776,7 +8938,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8785,14 +8947,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8837,47 +8999,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9059,6 +9228,10 @@ msgid "Export templates for this platform are missing:"
msgstr ""
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "管ç†è¼¸å‡ºç¯„本"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr ""
@@ -9213,6 +9386,15 @@ msgstr ""
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "專案"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Can't open project at '%s'."
msgstr "ä¸èƒ½é€£æŽ¥ã€‚"
@@ -9285,8 +9467,8 @@ msgstr ""
#: editor/project_manager.cpp
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr ""
#: editor/project_manager.cpp
@@ -9306,8 +9488,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "專案"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9332,10 +9515,6 @@ msgid "Templates"
msgstr "移除é¸é …"
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr "離開"
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9682,6 +9861,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "æ’件"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9739,14 +9922,6 @@ msgstr "é¸æ“‡æ¨¡å¼"
msgid "Select Method"
msgstr "é¸æ“‡æ¨¡å¼"
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -10048,6 +10223,11 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Change type of node(s)"
+msgstr "動畫變化數值"
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10095,6 +10275,11 @@ msgstr "下一個腳本"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "新增"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "儲存場景"
@@ -10173,19 +10358,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10284,6 +10469,10 @@ msgid "Error loading script from %s"
msgstr "載入字形出ç¾éŒ¯èª¤"
#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr "N/A"
@@ -10316,7 +10505,7 @@ msgid "Script is valid."
msgstr "腳本"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10484,6 +10673,10 @@ msgid "Change Shortcut"
msgstr ""
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "編輯器設定"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr ""
@@ -10910,10 +11103,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "有效å稱。"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "新增"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "新增"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "縮放selection"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11112,11 +11325,6 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
-msgid "Paste Nodes"
-msgstr "貼上"
-
-#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
msgstr "檔案"
@@ -11864,22 +12072,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr ""
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "字形格å¼ä¸æ˜Ž"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "載入字形出ç¾éŒ¯èª¤"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "無效字型"
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11894,6 +12086,11 @@ msgstr "無效字型"
msgid "Invalid source for shader."
msgstr "無效字型"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "無效字型"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11911,6 +12108,49 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "無法新增資料夾"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "啟用多普拉效應"
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "é¸æ“‡æ¨¡å¼"
+
+#, fuzzy
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "é¸æ“‡æ¨¡å¼"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "所有é¸é …"
+
+#~ msgid "Exit"
+#~ msgstr "離開"
+
+#~ msgid "Unknown font format."
+#~ msgstr "字形格å¼ä¸æ˜Ž"
+
+#~ msgid "Error loading font."
+#~ msgstr "載入字形出ç¾éŒ¯èª¤"
+
+#~ msgid "Invalid font size."
+#~ msgstr "無效字型"
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "上一個tab"
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "新增資料夾"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "è¦é›¢é–‹ç·¨è¼¯å™¨å—Ž?"
+
+#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "資æºåŠ è¼‰å¤±æ•—。"
@@ -11927,10 +12167,6 @@ msgstr ""
#~ msgstr "縮放selection"
#, fuzzy
-#~ msgid "Build Project"
-#~ msgstr "專案"
-
-#, fuzzy
#~ msgid "View log"
#~ msgstr "檔案"
@@ -12074,9 +12310,6 @@ msgstr ""
#~ msgid "Anim Track Change Interpolation"
#~ msgstr "動畫軌跡變化Interpolation"
-#~ msgid "Anim Track Change Value Mode"
-#~ msgstr "動畫軌跡變化數值模å¼"
-
#~ msgid "Edit Selection Curve"
#~ msgstr "編輯Selection Curve"
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 27afde910f..cfda19870f 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -14,12 +14,15 @@
# ken l <macauhome@gmail.com>, 2018.
# Eric K <eric900601@gmail.com>, 2019.
# cnieFIT <dtotncq@gmail.com>, 2019.
+# Bluesir Bruce <a5566740293@gmail.com>, 2019.
+# leela <53352@protonmail.com>, 2019.
+# Kenneth Lo <closer.tw@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-04-25 11:54+0000\n"
-"Last-Translator: cnieFIT <dtotncq@gmail.com>\n"
+"PO-Revision-Date: 2019-08-29 13:35+0000\n"
+"Last-Translator: Kenneth Lo <closer.tw@gmail.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
"Language: zh_TW\n"
@@ -27,7 +30,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.9-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -69,7 +72,6 @@ msgid "On call to '%s':"
msgstr "調用“%sâ€æ™‚:"
#: editor/animation_bezier_editor.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Free"
msgstr "释放"
@@ -86,9 +88,8 @@ msgid "Time:"
msgstr "時間:"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Value:"
-msgstr "數值"
+msgstr "數值:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
@@ -141,6 +142,31 @@ msgstr "更改回調"
#: editor/animation_track_editor.cpp
#, fuzzy
+msgid "Anim Multi Change Keyframe Time"
+msgstr "變更關éµç•«æ ¼çš„時間"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transition"
+msgstr "變更轉場效果"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Transform"
+msgstr "變更動畫變æ›"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Keyframe Value"
+msgstr "變更關éµç•«æ ¼çš„數值"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
+msgid "Anim Multi Change Call"
+msgstr "更改回調"
+
+#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Change Animation Length"
msgstr "變更動畫長度"
@@ -295,19 +321,18 @@ msgid "Delete Key(s)"
msgstr "刪除動畫關éµç•«æ ¼"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Update Mode"
-msgstr "改變字典 value"
+msgstr "變更動畫更新模å¼"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Interpolation Mode"
-msgstr "改變字典 value"
+msgstr "變更動畫內æ’模å¼"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Loop Mode"
-msgstr "變更動畫迴圈"
+msgstr "變更動畫循環模å¼"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -319,7 +344,7 @@ msgstr "為 %s 新增動畫軌並æ’入畫格?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "創建 %d 個動畫軌並æ’入畫格?"
+msgstr "新增 %d 個動畫軌並æ’入畫格?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -345,9 +370,8 @@ msgid "Anim Create & Insert"
msgstr "新增/æ’入動畫"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Insert Track & Key"
-msgstr "動畫新增軌跡與按éµ"
+msgstr "動畫新增軌跡與畫格"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
@@ -373,7 +397,11 @@ msgid ""
"-AudioStreamPlayer\n"
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
-msgstr "音訊曲目åªèƒ½æŒ‡å‘以下類型的節點:"
+msgstr ""
+"音訊軌åªèƒ½æŒ‡å‘以下類型的節點:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
@@ -446,6 +474,7 @@ msgid ""
msgstr "這個é¸é …ä¸é©ç”¨æ–¼è²å¡žçˆ¾ç·¨è¼¯ï¼Œå› ç‚ºå®ƒåªæ˜¯ä¸€å€‹å–®è»Œã€‚"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid ""
"This animation belongs to an imported scene, so changes to imported tracks "
"will not be saved.\n"
@@ -457,10 +486,17 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"這個動畫存在於匯入的場景中,因此å°åŒ¯å…¥è»Œæ‰€åšçš„變更ä¸æœƒè¢«å„²å­˜ã€‚\n"
+"\n"
+"若是è¦é–‹å•Ÿã€ŒåŠ å…¥å®¢åˆ¶è»Œã€çš„功能,請在場景的匯入設定中將「動畫 -> 存放ã€è¨­å®š"
+"為\n"
+"「檔案ã€ï¼Œé–‹å•Ÿã€Œå‹•ç•« -> ä¿å­˜å®¢åˆ¶è»Œã€ï¼Œç„¶å¾Œé‡æ–°å…¥åŒ¯å…¥ã€‚\n"
+"或者,你å¯ä»¥åœ¨åŒ¯å…¥æ™‚,將動畫資料匯入單ç¨çš„檔案之中。"
#: editor/animation_track_editor.cpp
+#, fuzzy
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
@@ -492,11 +528,12 @@ msgstr "動畫空間。"
#: editor/animation_track_editor.cpp
msgid "Seconds"
-msgstr ""
+msgstr "秒"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "FPS"
-msgstr ""
+msgstr "æ¯ç§’張數"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -656,16 +693,18 @@ msgid "Line Number:"
msgstr "行號:"
#: editor/code_editor.cpp
-msgid "Found %d match(es)."
-msgstr ""
+msgid "Replaced %d occurrence(s)."
+msgstr "å–代了 %d 個。"
#: editor/code_editor.cpp editor/editor_help.cpp
-msgid "No Matches"
-msgstr "無符åˆæ¢ä»¶"
+#, fuzzy
+msgid "%d match."
+msgstr "找到 %d 件符åˆçµæžœã€‚"
-#: editor/code_editor.cpp
-msgid "Replaced %d occurrence(s)."
-msgstr "å–代了 %d 個。"
+#: editor/code_editor.cpp editor/editor_help.cpp
+#, fuzzy
+msgid "%d matches."
+msgstr "找到 %d 件符åˆçµæžœã€‚"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -744,9 +783,8 @@ msgid "From Signal:"
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
@@ -776,7 +814,7 @@ msgstr "é¡å¤–呼å«åƒæ•¸:"
#: editor/connections_dialog.cpp
#, fuzzy
msgid "Advanced"
-msgstr "平衡的"
+msgstr "進階設定"
#: editor/connections_dialog.cpp
#, fuzzy
@@ -786,7 +824,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"
@@ -794,12 +832,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,22 +857,20 @@ msgid "Connect"
msgstr "連接"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "訊號:"
+msgstr "訊號:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr "連接 '%s' 到 '%s'"
+msgstr "將 '%s' 連接到 '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
msgstr "將 '%s' 從 '%s' 中斷連接"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect all from signal: '%s'"
-msgstr "將 '%s' 從 '%s' 中斷連接"
+msgstr "中斷所有來自 '%s' 的訊號連接"
#: editor/connections_dialog.cpp
msgid "Connect..."
@@ -847,42 +882,39 @@ 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â€è¨Šè™Ÿä¸­åˆ é™¤æ‰€æœ‰é€£æŽ¥å—Žï¼Ÿ"
+msgstr "確定è¦åˆ é™¤æ‰€æœ‰ä¾†è‡ª \"%s\" 的訊號連接嗎?"
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr "信號"
+msgstr "訊號"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
-msgstr "確定è¦åˆ é™¤æ­¤è¨Šè™Ÿçš„所有連接嗎?"
+msgstr "確定è¦åˆªé™¤æ‰€æœ‰ä¾†è‡ªæ­¤è¨Šè™Ÿçš„連接嗎?"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect All"
-msgstr "æ–·ç·š"
+msgstr "中斷所有連接"
#: editor/connections_dialog.cpp
msgid "Edit..."
msgstr "編輯…"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Go To Method"
-msgstr "方法"
+msgstr "å‰å¾€æ–¹æ³•"
#: editor/create_dialog.cpp
+#, fuzzy
msgid "Change %s Type"
msgstr "變更 %s 尺寸"
@@ -903,8 +935,7 @@ msgstr "我的最愛:"
msgid "Recent:"
msgstr "最近存å–:"
-#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
#: editor/property_selector.cpp editor/quick_open.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search:"
@@ -932,13 +963,12 @@ 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
@@ -1007,7 +1037,7 @@ msgstr ""
"刪除這些檔案å¯èƒ½é€ æˆå…¶ä»–資æºç„¡æ³•æ­£å¸¸é‹ä½œ\n"
"此動作無法復原, 確定è¦åˆªé™¤å—Ž?"
-#: editor/dependency_editor.cpp editor/export_template_manager.cpp
+#: editor/dependency_editor.cpp
msgid "Cannot remove:"
msgstr "無法移除:"
@@ -1045,7 +1075,7 @@ msgstr "確定è¦æ°¸ä¹…刪除 %d 個物件 ? (無法復原)"
msgid "Show Dependencies"
msgstr "相ä¾"
-#: editor/dependency_editor.cpp editor/editor_node.cpp
+#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
msgstr "孤立資料管ç†å™¨"
@@ -1140,14 +1170,16 @@ msgid "License"
msgstr "授權"
#: editor/editor_about.cpp
-msgid "Thirdparty License"
+#, fuzzy
+msgid "Third-party Licenses"
msgstr "第三方授權æ¢æ¬¾"
#: editor/editor_about.cpp
+#, fuzzy
msgid ""
-"Godot Engine relies on a number of thirdparty free and open source "
+"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
-"is an exhaustive list of all such thirdparty components with their "
+"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
"Godot Engine ä¾è³´è‘—許多與 MIT 授權æ¢æ¬¾ç›¸å®¹ã€è‡ªç”±é–‹æºçš„第三方函å¼åº«ã€‚以下是這"
@@ -1166,7 +1198,8 @@ msgid "Licenses"
msgstr "授權"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-msgid "Error opening package file, not in zip format."
+#, fuzzy
+msgid "Error opening package file, not in ZIP format."
msgstr "é–‹å•Ÿå¥—ä»¶æª”æ¡ˆå‡ºéŒ¯ï¼Œéž zip æ ¼å¼ã€‚"
#: editor/editor_asset_installer.cpp
@@ -1184,7 +1217,6 @@ msgid "Success!"
msgstr "æˆåŠŸ!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Install"
msgstr "安è£"
@@ -1318,7 +1350,7 @@ msgstr "é–‹å•Ÿ Audio 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"
@@ -1392,7 +1424,7 @@ msgstr "無效å稱.ä¸èƒ½è·Ÿå·²ç¶“存在的全局常é‡å稱é‡è¤‡."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "無法使用關éµå­—當作自動載入的å稱。"
#: editor/editor_autoload_settings.cpp
#, fuzzy
@@ -1405,8 +1437,9 @@ msgid "Rename Autoload"
msgstr "é‡æ–°å‘½å Autoload"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Toggle AutoLoad Globals"
-msgstr ""
+msgstr "åˆ‡æ› AutoLoad 的全域變數"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -1472,7 +1505,7 @@ msgstr "正在儲存變更..."
#: editor/editor_data.cpp
msgid "Updating scene..."
-msgstr "更新場景中..."
+msgstr "場景更新中…"
#: editor/editor_data.cpp editor/editor_properties.cpp
#, fuzzy
@@ -1520,7 +1553,7 @@ msgstr "儲存檔案:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "在é æœŸçš„路徑中找ä¸åˆ°åŒ¯å…¥æ¨¡æ¿ï¼š"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1531,20 +1564,27 @@ msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"使用 GLES2 時,目標平å°è¦æ±‚使用 'ETC' æ質壓縮。請在「專案設定ã€ä¸­é–‹å•Ÿã€ŒåŒ¯å…¥ "
+"Etcã€ã€‚"
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"使用 GLES3 時,目標平å°è¦æ±‚使用 'ETC2' æ質壓縮。請在「專案設定ã€ä¸­é–‹å•Ÿã€ŒåŒ¯"
+"å…¥ Etc 2ã€ã€‚"
#: editor/editor_export.cpp
+#, fuzzy
msgid ""
"Target platform requires 'ETC' texture compression for the driver fallback "
"to GLES2.\n"
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"使用「回退至 GLES2ã€çš„驅動器時,目標平å°è¦æ±‚使用 'ETC' 貼圖壓縮。\n"
+"請在「專案設定ã€ä¸­é–‹å•Ÿã€ŒåŒ¯å…¥ Etcã€ï¼Œæˆ–是關閉「開啟驅動器回退ã€é¸é …。"
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1564,7 +1604,7 @@ msgstr "找ä¸åˆ°ç¯„本檔案:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "匯出為 32 ä½å…ƒåŸ·è¡Œæª”時,內嵌的 PCK 大å°ä¸å¾—è¶…éŽ 4 GB。"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1582,9 +1622,8 @@ msgid "Asset Library"
msgstr "é–‹å•Ÿç´ æ倉庫"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Scene Tree Editing"
-msgstr "場景樹 (節點):"
+msgstr "正在編譯場景樹"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1607,8 +1646,9 @@ msgid "Erase profile '%s'? (no undo)"
msgstr "å–代全部"
#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "Profile 必須為有效的檔å,而且其中ä¸å¾—åŒ…å« '.' 字元。"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1616,8 +1656,9 @@ msgid "Profile with this name already exists."
msgstr "具有此å稱的檔或資料夾已存在。"
#: editor/editor_feature_profile.cpp
+#, fuzzy
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(編譯已關閉,屬性已關閉)"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1656,13 +1697,14 @@ msgstr "æœå°‹ Class"
#: 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. Remove it first before importing, import "
"aborted."
-msgstr ""
+msgstr "Profile '%s' 已經存在。在匯入的å‰è«‹å…ˆç§»é™¤ã€‚中止匯入。"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1671,7 +1713,7 @@ msgstr "載入場景時發生錯誤"
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "未設定"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1689,12 +1731,11 @@ msgid "New"
msgstr "新增"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_manager.cpp
msgid "Import"
msgstr "å°Žå…¥"
-#: editor/editor_feature_profile.cpp editor/editor_node.cpp
-#: editor/project_export.cpp
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "輸出"
@@ -1765,7 +1806,7 @@ msgstr "在檔案管ç†å“¡å…§é¡¯ç¤º"
msgid "New Folder..."
msgstr "新增資料夾..."
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Refresh"
msgstr "é‡æ–°æ•´ç†"
@@ -1816,7 +1857,7 @@ msgstr "å¾€å‰"
msgid "Go Up"
msgstr "往上"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
msgstr "切æ›é¡¯ç¤ºéš±è—檔案"
@@ -1843,27 +1884,32 @@ msgstr "å‘下移動收è—"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Previous Folder"
-msgstr "上個分é "
+msgid "Go to previous folder."
+msgstr "無法新增資料夾"
#: editor/editor_file_dialog.cpp
#, fuzzy
-msgid "Next Folder"
-msgstr "新增資料夾"
+msgid "Go to next folder."
+msgstr "無法新增資料夾"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
msgid "Go to parent folder."
msgstr "無法新增資料夾"
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#, fuzzy
+msgid "Refresh files."
+msgstr "æœå°‹ Class"
+
#: editor/editor_file_dialog.cpp
#, fuzzy
msgid "(Un)favorite current folder."
msgstr "無法新增資料夾"
-#: editor/editor_file_dialog.cpp
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
-msgid "Toggle visibility of hidden files."
+msgid "Toggle the visibility of hidden files."
msgstr "切æ›é¡¯ç¤ºéš±è—檔案"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
@@ -2093,8 +2139,9 @@ msgid "Set"
msgstr "集åˆ"
#: editor/editor_inspector.cpp
+#, fuzzy
msgid "Set Multiple:"
-msgstr ""
+msgstr "複數設定:"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2120,6 +2167,10 @@ msgstr "清除"
msgid "Clear Output"
msgstr "輸出:"
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
#: editor/editor_node.cpp
msgid "Project export failed with error code %d."
msgstr "專案輸出失敗,錯誤代碼是 %d。"
@@ -2138,10 +2189,11 @@ msgid "Error saving resource!"
msgstr "儲存資æºéŒ¯èª¤!"
#: 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 "無法ä¿å­˜æ­¤è³‡æºï¼Œå› ç‚ºå®ƒä¸å±¬æ–¼å·²ç·¨è¼¯çš„場景。先讓它唯一。"
+msgstr "無法儲存此資æºï¼Œå› ç‚ºå®ƒä¸å±¬æ–¼å·²ç·¨è¼¯çš„場景。請先讓它æˆç‚ºå”¯ä¸€ã€‚"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -2203,16 +2255,18 @@ 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 ""
+"åµæ¸¬åˆ°æ­¤å ´æ™¯ä¸­æœ‰å¾ªç’°å¯¦ä¾‹åŒ–引入ç¾è±¡ï¼Œå› æ­¤ç„¡æ³•å„²å­˜ã€‚\n"
+"請先解決此å•é¡Œå¾Œå†è©¦ä¸€æ¬¡ã€‚"
#: editor/editor_node.cpp
msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
-msgstr ""
+msgstr "無法儲存此場景。å¯èƒ½æœ‰ä¸å®Œæ•´çš„ä¾å­˜é—œä¿‚(實例化或是繼承上的)。"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr "無法覆蓋ä»è™•æ–¼æ‰“開狀態的場景ï¼"
+msgstr "無法覆寫ä»è™•æ–¼é–‹å•Ÿç‹€æ…‹çš„場景ï¼"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -2252,31 +2306,35 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
-"此資æºå±¬æ–¼å·²å°Žå…¥çš„場景, å› æ­¤ä¸å¯ç·¨è¼¯ã€‚\n"
-"請閱讀與導入場景相關的文檔, 以便更好地瞭解此工作æµã€‚"
+"此資æºå±¬æ–¼åŒ¯å…¥çš„場景,因此ä¸å¯ç·¨è¼¯ã€‚\n"
+"請閱讀與匯入場景相關的文件,以便更加瞭解工作æµç¨‹ã€‚"
#: 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 ""
+"此資æºå±¬æ–¼è¢«å¯¦ä¾‹åŒ–或被繼承的場景。\n"
+"儲存場景時,此資æºçš„變更ä¸æœƒè¢«ä¿å­˜ã€‚"
#: editor/editor_node.cpp
msgid ""
"This resource was imported, so it's not editable. Change its settings in the "
"import panel and then re-import."
msgstr ""
+"這個資æºæ˜¯åŒ¯å…¥é€²ä¾†çš„,因此無法編譯。請修改匯入控制é¢æ¿ä¸Šçš„設定,å†é‡æ–°åŒ¯å…¥ä¸€"
+"次。"
#: editor/editor_node.cpp
-#, 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"
+"請閱讀與匯入場景相關的文件,以便更加瞭解工作æµç¨‹ã€‚"
#: editor/editor_node.cpp
#, fuzzy
@@ -2290,11 +2348,11 @@ msgstr ""
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
-msgstr "沒有è¦é‹è¡Œçš„已定義場景。"
+msgstr "沒有已定義的場景å¯é‹è¡Œã€‚"
#: editor/editor_node.cpp
msgid "Current scene was never saved, please save it prior to running."
-msgstr "在é‹è¡Œå ´æ™¯å‰ï¼Œè«‹å…ˆå­˜æª”。"
+msgstr "ç›®å‰çš„場景從未被儲存,在é‹è¡Œå ´æ™¯å‰è«‹å…ˆå­˜æª”。"
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
@@ -2306,7 +2364,7 @@ msgstr "開啟場景"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr "打開基本場景"
+msgstr "開啟基本場景"
#: editor/editor_node.cpp
#, fuzzy
@@ -2315,7 +2373,7 @@ msgstr "快速開啟場景..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr "快速開啟場景..."
+msgstr "快速開啟場景…"
#: editor/editor_node.cpp
msgid "Quick Open Script..."
@@ -2336,11 +2394,11 @@ msgstr "å·²ä¿å­˜%s個已修改的資æºã€‚"
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr "ä¿å­˜å ´æ™¯éœ€è¦æ ¹ç¯€é»žã€‚"
+msgstr "儲存場景需è¦æ ¹ç¯€é»žã€‚"
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr "å¦å­˜å ´æ™¯ç‚º..."
+msgstr "å¦å­˜å ´æ™¯ç‚ºâ€¦"
#: editor/editor_node.cpp
msgid "No"
@@ -2352,11 +2410,11 @@ msgstr "是"
#: editor/editor_node.cpp
msgid "This scene has never been saved. Save before running?"
-msgstr "此場景尚未存檔, 執行å‰è«‹å…ˆå­˜æª”"
+msgstr "此場景從未被儲存。執行å‰å…ˆå­˜æª”?"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
-msgstr "在設置場景å‰ï¼Œç„¡æ³•å®Œæˆè©²æŒ‡å®šæ“作。"
+msgstr "這項æ“作必須è¦æœ‰å ´æ™¯å­˜åœ¨ã€‚"
#: editor/editor_node.cpp
msgid "Export Mesh Library"
@@ -2376,11 +2434,11 @@ msgstr "在設置著節點(selected node)å‰ï¼Œç„¡æ³•å®Œæˆè©²æŒ‡å®šæ“作。"
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr "ç›®å‰çš„場景尚未存檔,ä»è¦é–‹å•Ÿå—Žï¼Ÿ"
+msgstr "ç›®å‰çš„場景尚未儲存。還是è¦é–‹å•Ÿå—Žï¼Ÿ"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr "無法é‡æ–°è¼‰å…¥æœªå­˜æª”的場景."
+msgstr "無法é‡æ–°è¼‰å…¥å¾žæœªå­˜æª”的場景。"
#: editor/editor_node.cpp
msgid "Revert"
@@ -2413,11 +2471,11 @@ msgstr "儲存並離開"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr "關閉å‰ï¼Œè¦å„²å­˜ä¿®æ”¹çš„場景嗎?"
+msgstr "退出程å¼å‰ï¼Œè¦å„²å­˜ä»¥ä¸‹ä¿®æ”¹éŽçš„場景嗎?"
#: editor/editor_node.cpp
msgid "Save changes the following scene(s) before opening Project Manager?"
-msgstr "開啟專案管ç†å‰ï¼Œè¦å„²å­˜ä¿®æ”¹çš„場景嗎?"
+msgstr "開啟專案管ç†å‰ï¼Œè¦å„²å­˜ä»¥ä¸‹ä¿®æ”¹éŽçš„場景嗎?"
#: editor/editor_node.cpp
msgid ""
@@ -2427,7 +2485,16 @@ msgstr "ä¸æŽ¨è–¦æ­¤é¸é …。被強制é‡æ–°æ•´ç†çš„情形,å¯èƒ½æ˜¯å› ç¨‹å¼
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
-msgstr "é¸å–一個主è¦å ´æ™¯"
+msgstr "é¸å–主è¦å ´æ™¯"
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "關閉場景"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Reopen Closed Scene"
+msgstr "關閉場景"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2461,21 +2528,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 ""
-"場景\"%s\"為自動導入,並ä¸èƒ½è¢«ä¿®æ”¹ã€‚\n"
-"è‹¥è¦é€²è¡Œæ›´æ”¹ï¼Œè«‹å»ºç«‹æ–°çš„場景。"
+"場景 '%s' 為自動匯入的,ä¸èƒ½è¢«ä¿®æ”¹ã€‚\n"
+"è‹¥è¦é€²è¡Œæ›´æ”¹ï¼Œè«‹å»ºç«‹æ–°çš„繼承的場景。"
#: editor/editor_node.cpp
msgid ""
"Error loading scene, it must be inside the project path. Use 'Import' to "
"open the scene, then save it inside the project path."
msgstr ""
-"讀å–場景時發生錯誤,場景必須放置於專案資料夾內。請用「導入ã€é–‹å•Ÿè©²å ´æ™¯å¾Œï¼Œå†"
+"讀å–場景時發生錯誤,場景必須放置於專案資料夾中。請用「導入ã€é–‹å•Ÿè©²å ´æ™¯å¾Œï¼Œå†"
"儲存於專案資料夾。"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Scene '%s' has broken dependencies:"
-msgstr "場景 '%s' çš„ä¾å­˜é—œä¿‚已被破壞。"
+msgstr "場景 '%s' çš„ä¾å­˜é—œä¿‚已被破壞:"
#: editor/editor_node.cpp
msgid "Clear Recent Scenes"
@@ -2487,6 +2553,8 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"尚未定義主場景。è¦é¸æ“‡ä¸€å€‹å ´æ™¯å—Žï¼Ÿ\n"
+"你之後å¯ä»¥åœ¨ã€Œæ‡‰ç”¨ç¨‹å¼ã€åˆ†é¡žä¸­çš„「專案設定ã€è®Šæ›´é€™è¨­å®šã€‚"
#: editor/editor_node.cpp
msgid ""
@@ -2528,6 +2596,11 @@ msgstr "é‹è¡Œæ­¤å ´æ™¯"
msgid "Close Tab"
msgstr "關閉分é "
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Undo Close Tab"
+msgstr "關閉分é "
+
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
msgstr "關閉其他é¸é …å¡"
@@ -2584,6 +2657,11 @@ msgid "Go to previously opened scene."
msgstr "å‰å¾€ä¸Šæ¬¡é–‹å•Ÿçš„場景。"
#: editor/editor_node.cpp
+#, fuzzy
+msgid "Copy Text"
+msgstr "複製路徑"
+
+#: editor/editor_node.cpp
msgid "Next tab"
msgstr "下一個分é "
@@ -2611,6 +2689,10 @@ msgstr "從ç¾æœ‰å ´æ™¯ä¸­å»ºç«‹â€¦"
msgid "Open Scene..."
msgstr "開啟場景…"
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "最近開啟的場景"
+
#: editor/editor_node.cpp
msgid "Save Scene"
msgstr "儲存場景"
@@ -2621,14 +2703,6 @@ msgid "Save All Scenes"
msgstr "儲存全部場景"
#: editor/editor_node.cpp
-msgid "Close Scene"
-msgstr "關閉場景"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-msgid "Open Recent"
-msgstr "最近開啟的場景"
-
-#: editor/editor_node.cpp
msgid "Convert To..."
msgstr "轉æ›æˆâ€¦"
@@ -2658,25 +2732,36 @@ msgstr "æ¢å¾©å ´æ™¯"
msgid "Miscellaneous project or scene-wide tools."
msgstr "其他專案或全螢幕工具。"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Project"
msgstr "專案"
#: editor/editor_node.cpp
-msgid "Project Settings"
+#, fuzzy
+msgid "Project Settings..."
msgstr "專案設定"
-#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
-msgid "Tools"
-msgstr "工具"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Export..."
+msgstr "輸出"
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
msgstr "開啟專案資料夾"
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "工具"
+
#: editor/editor_node.cpp
-msgid "Install Android Build Template"
-msgstr ""
+#, fuzzy
+msgid "Orphan Resource Explorer..."
+msgstr "孤立資料管ç†å™¨"
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2763,12 +2848,13 @@ msgstr ""
"啟用此é¸é …後,腳本的所有修改,都會立å³å映於é‹è¡Œä¸­çš„éŠæˆ²ã€‚\n"
"在é ç«¯è£ç½®æ¸¬è©¦æ™‚,é…åˆç¶²è·¯æ–‡ä»¶ç³»çµ±(NFS)使用能更æ高效率。"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "編輯器"
-#: editor/editor_node.cpp editor/settings_config_dialog.cpp
-msgid "Editor Settings"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Editor Settings..."
msgstr "編輯器設定"
#: editor/editor_node.cpp
@@ -2786,15 +2872,6 @@ 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 "全螢幕顯示"
@@ -2817,14 +2894,15 @@ msgstr "開啟 編輯器設定 資料夾"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Manage Editor Features"
+msgid "Manage Editor Features..."
msgstr "管ç†è¼¸å‡ºæ¨¡æ¿"
-#: editor/editor_node.cpp editor/project_export.cpp
-msgid "Manage Export Templates"
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Manage Export Templates..."
msgstr "管ç†è¼¸å‡ºæ¨¡æ¿"
-#: editor/editor_node.cpp
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
msgstr "幫助"
@@ -2832,12 +2910,13 @@ msgstr "幫助"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
msgstr "æœå°‹"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "線上文件"
@@ -3116,6 +3195,11 @@ msgstr "時間"
msgid "Calls"
msgstr "調用"
+#: editor/editor_properties.cpp
+#, fuzzy
+msgid "Edit Text:"
+msgstr "編輯主題…"
+
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
msgstr "啟用"
@@ -3281,7 +3365,8 @@ msgid "Import From Node:"
msgstr "從節點導入:"
#: editor/export_template_manager.cpp
-msgid "Re-Download"
+#, fuzzy
+msgid "Redownload"
msgstr "é‡æ–°ä¸‹è¼‰"
#: editor/export_template_manager.cpp
@@ -3298,6 +3383,10 @@ msgid "Download"
msgstr "下載"
#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
msgid "(Missing)"
msgstr "(缺少)"
@@ -3361,12 +3450,10 @@ msgid "No response."
msgstr "沒有回應。"
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request Failed."
msgstr "請求失敗."
#: editor/export_template_manager.cpp
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Redirect Loop."
msgstr "é‡æ–°å®šå‘循環."
@@ -3380,14 +3467,20 @@ msgid "Download Complete."
msgstr "下載完æˆã€‚"
#: editor/export_template_manager.cpp
+#, fuzzy
+msgid "Cannot remove temporary file:"
+msgstr "無法將主題ä¿å­˜åˆ°æª”案:"
+
+#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
-"Templates installation failed. The problematic templates archives can be "
-"found at '%s'."
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
msgstr "範本安è£å¤±æ•—。有å•é¡Œçš„範本存檔å¯ä»¥åœ¨ \"%s\" 中找到。"
#: editor/export_template_manager.cpp
#, fuzzy
-msgid "Error requesting url: "
+msgid "Error requesting URL:"
msgstr "載入場景時發生錯誤"
#: editor/export_template_manager.cpp
@@ -3482,20 +3575,12 @@ msgstr "載入場景時發生錯誤"
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr "從清單中é¸æ“‡é¡åƒ: (Shift + 單擊: 在ç€è¦½å™¨ä¸­æ‰“é–‹)"
-#: editor/file_type_cache.cpp
-msgid "Can't open file_type_cache.cch for writing, not saving file type cache!"
-msgstr ""
-
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Favorites"
msgstr "我的最愛:"
#: editor/filesystem_dock.cpp
-msgid "Cannot navigate to '%s' as it has not been found in the file system!"
-msgstr ""
-
-#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
@@ -3532,14 +3617,14 @@ msgid "Provided name contains invalid characters."
msgstr "æ供的å稱包å«ç„¡æ•ˆå­—å…ƒ"
#: editor/filesystem_dock.cpp
-msgid "Name contains invalid characters."
-msgstr "å稱包å«ç„¡æ•ˆå­—元。"
-
-#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
msgstr "具有此å稱的檔或資料夾已存在。"
#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "å稱包å«ç„¡æ•ˆå­—元。"
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Renaming file:"
msgstr "載入時發生錯誤:"
@@ -3602,6 +3687,11 @@ msgstr "複製動畫關éµç•«æ ¼"
msgid "Move To..."
msgstr "移動到..。"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "New Scene..."
+msgstr "新場景"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "New Script..."
@@ -3672,6 +3762,11 @@ msgstr "æ­¤ä½ç½®å·²å­˜åœ¨åŒå的檔案或資料夾。"
msgid "Overwrite"
msgstr "覆蓋"
+#: editor/filesystem_dock.cpp
+#, fuzzy
+msgid "Create Scene"
+msgstr "從場景創建"
+
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
msgstr "創建腳本"
@@ -3741,6 +3836,14 @@ msgid "Search complete"
msgstr "æœå°‹è©žå½™"
#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "添加到組"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "從群組移除"
+
+#: editor/groups_editor.cpp
#, fuzzy
msgid "Group name already exists."
msgstr "Autoload「%sã€å·²ç¶“存在!"
@@ -3750,12 +3853,23 @@ msgstr "Autoload「%sã€å·²ç¶“存在!"
msgid "Invalid group name."
msgstr "ä¸èƒ½ä½¿ç”¨çš„å稱。"
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Rename Group"
+msgstr "管ç†çµ„"
+
+#: editor/groups_editor.cpp
+#, fuzzy
+msgid "Delete Group"
+msgstr "刪除佈局"
+
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
msgstr "組"
#: editor/groups_editor.cpp
-msgid "Nodes not in Group"
+#, fuzzy
+msgid "Nodes Not in Group"
msgstr "ä¸åœ¨çµ„中的節點"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
@@ -3769,12 +3883,13 @@ msgid "Nodes in Group"
msgstr "組中的節點"
#: editor/groups_editor.cpp
-msgid "Add to Group"
-msgstr "添加到組"
+msgid "Empty groups will be automatically removed."
+msgstr ""
#: editor/groups_editor.cpp
-msgid "Remove from Group"
-msgstr "從群組移除"
+#, fuzzy
+msgid "Group Editor"
+msgstr "開啟腳本編輯器"
#: editor/groups_editor.cpp
msgid "Manage Groups"
@@ -3985,7 +4100,8 @@ msgid "MultiNode Set"
msgstr "多節點集"
#: editor/node_dock.cpp
-msgid "Select a Node to edit Signals and Groups."
+#, fuzzy
+msgid "Select a single node to edit its signals and groups."
msgstr "é¸æ“‡è¦ç·¨è¼¯è¨Šè™Ÿå’Œçµ„的節點。"
#: editor/plugin_config_dialog.cpp
@@ -4774,10 +4890,6 @@ msgid "View Files"
msgstr "查看檔案"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Can't resolve hostname:"
-msgstr "無法解æžä¸»æ©Ÿå稱:"
-
-#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connection error, please try again."
msgstr "連接錯誤, è«‹é‡è©¦ã€‚"
@@ -4790,14 +4902,47 @@ msgid "No response from host:"
msgstr "主機沒有響應:"
#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr "無法解æžä¸»æ©Ÿå稱:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
msgstr "請求失敗, 返回代碼:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed."
+msgstr "請求失敗."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Cannot save response to:"
+msgstr "無法將主題ä¿å­˜åˆ°æª”案:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
msgstr "請求失敗, é‡å®šå‘次數太多"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Redirect loop."
+msgstr "é‡æ–°å®šå‘循環."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Request failed, timeout"
+msgstr "請求失敗, 返回代碼:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Timeout."
+msgstr "時間"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
msgstr ""
@@ -4839,6 +4984,11 @@ msgid "Idle"
msgstr "空閒"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Install..."
+msgstr "安è£"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
msgstr "é‡è©¦"
@@ -4868,13 +5018,17 @@ msgid "Last"
msgstr "最後"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "All"
msgstr "全部"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
-msgid "Plugins"
+#, fuzzy
+msgid "Import..."
+msgstr "å°Žå…¥"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Plugins..."
msgstr "挿件"
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
@@ -4882,8 +5036,9 @@ msgid "Sort:"
msgstr "排åº:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Reverse"
-msgstr "å轉"
+#, fuzzy
+msgid "Reverse sorting."
+msgstr "正在請求…"
#: editor/plugins/asset_library_editor_plugin.cpp
#: editor/project_settings_editor.cpp
@@ -4895,7 +5050,8 @@ msgid "Site:"
msgstr "地å€:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Support..."
+#, fuzzy
+msgid "Support"
msgstr "支æŒâ€¦"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4907,6 +5063,11 @@ msgid "Testing"
msgstr "測試"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
+msgid "Loading..."
+msgstr "載入"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
msgstr "ZIP資æºåŒ…"
@@ -4958,31 +5119,38 @@ msgid "Rotation Step:"
msgstr "旋轉步驟:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move vertical guide"
+#, fuzzy
+msgid "Move Vertical Guide"
msgstr "垂直移動尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new vertical guide"
+#, fuzzy
+msgid "Create Vertical Guide"
msgstr "創建新的垂直尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove vertical guide"
+#, fuzzy
+msgid "Remove Vertical Guide"
msgstr "刪除垂直尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Move horizontal guide"
+#, fuzzy
+msgid "Move Horizontal Guide"
msgstr "移動水平尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal guide"
+#, fuzzy
+msgid "Create Horizontal Guide"
msgstr "創建新的水平尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Remove horizontal guide"
+#, fuzzy
+msgid "Remove Horizontal Guide"
msgstr "移除水平尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
-msgid "Create new horizontal and vertical guides"
+#, fuzzy
+msgid "Create Horizontal and Vertical Guides"
msgstr "創建新的水平和垂直尺標"
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5068,6 +5236,11 @@ msgstr "粘貼姿勢"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
+msgid "Clear Guides"
+msgstr "清除姿勢"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
msgstr "從節點製作自定義骨骼"
@@ -5097,6 +5270,7 @@ msgid "Zoom Reset"
msgstr "é‡ç½®ç¸®æ”¾"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
msgstr "é¸æ“‡æ¨¡å¼"
@@ -5117,14 +5291,17 @@ msgid "Alt+RMB: Depth list selection"
msgstr "Alt+滑鼠å³éµ:顯示鼠標點擊ä½ç½®ä¸‹æ‰€æœ‰çš„節點清單"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
msgstr "移動模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
msgstr "旋轉模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
msgid "Scale Mode"
msgstr "縮放模å¼"
@@ -5149,6 +5326,7 @@ msgid "Toggle snapping."
msgstr "切æ›å¸é™„。"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
msgstr "使用å¸é™„"
@@ -5167,12 +5345,6 @@ msgid "Use Rotation Snap"
msgstr "使用旋轉å¸é™„"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Configure Snap..."
-msgstr "é…ç½®å¸é™„…"
-
-#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap Relative"
msgstr "相å°å¸é™„"
@@ -5188,6 +5360,12 @@ msgid "Smart Snapping"
msgstr "智慧å¸é™„"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Configure Snap..."
+msgstr "é…ç½®å¸é™„…"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Snap to Parent"
msgstr "å¸é™„到父級節點"
@@ -5407,16 +5585,6 @@ msgstr "設置控制程åº"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "Error loading image:"
-msgstr "加載影åƒæ™‚出錯:"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
-msgid "No pixels with transparency > 128 in image..."
-msgstr "å½±åƒä¸­æ²’有é€æ˜Žåº¦å¤§æ–¼128的點數…"
-
-#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
-#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
msgstr ""
@@ -5741,14 +5909,6 @@ msgid "Surface source is invalid (no faces)."
msgstr "表é¢æºç„¡æ•ˆï¼ˆæ²’有é¢ï¼‰ã€‚"
#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Parent has no solid faces to populate."
-msgstr "父級沒有è¦å¡«å……的實體é¢ã€‚"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
-msgid "Couldn't map area."
-msgstr "無法映射å€åŸŸã€‚"
-
-#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
msgstr "é¸æ“‡æºç¶²æ ¼ï¼š"
@@ -5833,20 +5993,27 @@ msgid "Generation Time (sec):"
msgstr "生æˆæ™‚é–“ (秒):"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Faces contain no area!"
-msgstr "é¢ä¸åŒ…å«ä»»ä½•å€åŸŸï¼"
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+#, fuzzy
+msgid "The geometry doesn't contain any faces."
+msgstr "節點ä¸åŒ…å«å¹¾ä½•åœ–å½¢ (é¢)。"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "No faces!"
+msgid "\"%s\" doesn't inherit from Spatial."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry."
+#, fuzzy
+msgid "\"%s\" doesn't contain geometry."
msgstr "節點ä¸åŒ…å«å¹¾ä½•åœ–形。"
#: editor/plugins/particles_editor_plugin.cpp
-msgid "Node does not contain geometry (faces)."
-msgstr "節點ä¸åŒ…å«å¹¾ä½•åœ–å½¢ (é¢)。"
+#, fuzzy
+msgid "\"%s\" doesn't contain face geometry."
+msgstr "節點ä¸åŒ…å«å¹¾ä½•åœ–形。"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6184,7 +6351,6 @@ msgid "Grid Settings"
msgstr "專案設定"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap"
msgstr ""
@@ -6294,12 +6460,7 @@ msgstr "載入場景時發生錯誤"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "Error: could not load file."
-msgstr "無法新增資料夾"
-
-#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
-msgid "Error could not load file."
+msgid "Could not load file at:"
msgstr "無法新增資料夾"
#: editor/plugins/script_editor_plugin.cpp
@@ -6328,7 +6489,7 @@ msgstr "載入時發生錯誤:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
-msgid "New TextFile..."
+msgid "New Text File..."
msgstr "新增資料夾..."
#: editor/plugins/script_editor_plugin.cpp
@@ -6416,6 +6577,11 @@ msgid "Open..."
msgstr "開啟…"
#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Reopen Closed Script"
+msgstr "開啟最近存å–"
+
+#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
msgstr "全部ä¿å­˜"
@@ -6455,13 +6621,13 @@ msgid "Save Theme"
msgstr "ä¿å­˜ä¸»é¡Œ"
#: editor/plugins/script_editor_plugin.cpp
-msgid "Close Docs"
-msgstr "關閉檔案"
-
-#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
msgstr "全部關閉"
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "關閉檔案"
+
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
msgstr "é‹è¡Œ"
@@ -6551,6 +6717,11 @@ msgstr "調試器"
msgid "Search Results"
msgstr "æœå°‹çµæžœ"
+#: editor/plugins/script_editor_plugin.cpp
+#, fuzzy
+msgid "Clear Recent Scripts"
+msgstr "清除最近開啟的場景"
+
#: editor/plugins/script_text_editor.cpp
#, fuzzy
msgid "Connections to method:"
@@ -6624,6 +6795,7 @@ msgid "Syntax Highlighter"
msgstr "高亮顯示語法"
#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
@@ -6661,26 +6833,6 @@ msgstr "切æ›æ³¨é‡‹"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Toggle Bookmark"
-msgstr "切æ›è‡ªç”±è§€å¯Ÿæ¨¡å¼"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Next Bookmark"
-msgstr "轉到下一個中斷點"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Go to Previous Bookmark"
-msgstr "轉到上一個中斷點"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
-msgid "Remove All Bookmarks"
-msgstr "删除所有項目"
-
-#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
msgstr "å‰å¾€ç¬¬...è¡Œ"
@@ -6701,6 +6853,11 @@ msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Evaluate Selection"
+msgstr "縮放所é¸"
+
+#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
@@ -6719,32 +6876,37 @@ msgid "Auto Indent"
msgstr "自動縮進"
#: editor/plugins/script_text_editor.cpp
-#: modules/visual_script/visual_script_editor.cpp
-msgid "Toggle Breakpoint"
-msgstr "設置中斷點"
+msgid "Find Previous"
+msgstr "查找上一個"
#: editor/plugins/script_text_editor.cpp
-msgid "Remove All Breakpoints"
-msgstr "刪除所有中斷點"
+#, fuzzy
+msgid "Find in Files..."
+msgstr "在檔中查找..。"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Next Breakpoint"
-msgstr "轉到下一個中斷點"
+msgid "Toggle Bookmark"
+msgstr "切æ›è‡ªç”±è§€å¯Ÿæ¨¡å¼"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Go to Previous Breakpoint"
-msgstr "轉到上一個中斷點"
+msgid "Go to Next Bookmark"
+msgstr "轉到下一個中斷點"
#: editor/plugins/script_text_editor.cpp
-msgid "Find Previous"
-msgstr "查找上一個"
+#, fuzzy
+msgid "Go to Previous Bookmark"
+msgstr "轉到上一個中斷點"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
-msgid "Find in Files..."
-msgstr "在檔中查找..。"
+msgid "Remove All Bookmarks"
+msgstr "删除所有項目"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -6756,8 +6918,23 @@ msgid "Go to Line..."
msgstr "å‰å¾€ç¬¬...è¡Œ"
#: editor/plugins/script_text_editor.cpp
-msgid "Contextual Help"
-msgstr ""
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "設置中斷點"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "刪除所有中斷點"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Next Breakpoint"
+msgstr "轉到下一個中斷點"
+
+#: editor/plugins/script_text_editor.cpp
+#, fuzzy
+msgid "Go to Previous Breakpoint"
+msgstr "轉到上一個中斷點"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -6936,9 +7113,15 @@ msgid "Rear"
msgstr "後"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align with View"
+#, fuzzy
+msgid "Align Transform with View"
msgstr "與視圖å°é½Š"
+#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Align Rotation with View"
+msgstr "將所é¸å…§å®¹èˆ‡è¦–圖å°é½Š"
+
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
msgstr ""
@@ -6993,8 +7176,9 @@ msgid "Audio Listener"
msgstr "音訊監è½å™¨"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Doppler Enable"
-msgstr "啟用多普拉效應"
+#, fuzzy
+msgid "Enable Doppler"
+msgstr "啟用篩é¸"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -7047,9 +7231,8 @@ msgid "Snap Nodes To Floor"
msgstr "將節點æ•æ‰åˆ°åœ°é¢"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Select Mode (Q)"
-msgstr "é¸æ“‡æ¨¡å¼ (Q)"
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7059,30 +7242,11 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Move Mode (W)"
-msgstr "ç§»å‹•æ¨¡å¼ (W)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Rotate Mode (E)"
-msgstr "æ—‹è½‰æ¨¡å¼ (E)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Scale Mode (R)"
-msgstr "ç¸®æ”¾æ¨¡å¼ (R)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Coords"
-msgstr "本地å標"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Local Space Mode (%s)"
+#, fuzzy
+msgid "Use Local Space"
msgstr "本地空間模å¼ï¼ˆ%s)"
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Snap Mode (%s)"
-msgstr "æ•æ‰æ¨¡å¼ (%s)"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
msgstr "底部視圖"
@@ -7124,27 +7288,6 @@ msgid "Focus Selection"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Align Selection With View"
-msgstr "將所é¸å…§å®¹èˆ‡è¦–圖å°é½Š"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
-msgid "Tool Select"
-msgstr "工具é¸æ“‡"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Move"
-msgstr "工具移動"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Rotate"
-msgstr "工具旋轉"
-
-#: editor/plugins/spatial_editor_plugin.cpp
-msgid "Tool Scale"
-msgstr "縮放工具"
-
-#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
msgstr "切æ›è‡ªç”±è§€å¯Ÿæ¨¡å¼"
@@ -7200,7 +7343,8 @@ msgstr "顯示網格"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-msgid "Settings"
+#, fuzzy
+msgid "Settings..."
msgstr "設定"
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7517,10 +7661,6 @@ msgid "TextureRegion"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-msgid "Can't save theme to file:"
-msgstr "無法將主題ä¿å­˜åˆ°æª”案:"
-
-#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
msgstr "添加所有項目"
@@ -7611,12 +7751,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 1"
+msgid "Subitem 1"
msgstr "é …ç›®"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
-msgid "Item 2"
+msgid "Subitem 2"
msgstr "é …ç›®"
#: editor/plugins/theme_editor_plugin.cpp
@@ -7725,14 +7865,6 @@ msgid "Transpose"
msgstr "轉置"
#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror X"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
-msgid "Mirror Y"
-msgstr ""
-
-#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
@@ -7747,8 +7879,8 @@ msgstr "繪製ç£è²¼"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
-"Shift+RMB: Line Draw\n"
-"Shift+Ctrl+RMB: Rectangle Paint"
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
@@ -8058,6 +8190,10 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Add input +"
msgstr "添加輸入"
@@ -8146,6 +8282,11 @@ msgid "Duplicate Nodes"
msgstr "複製節點"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Delete Nodes"
msgstr "刪除"
@@ -8169,6 +8310,11 @@ msgstr "燈光"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
+msgid "Show resulted shader code."
+msgstr "創建節點"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Create Shader Node"
msgstr "創建節點"
@@ -8247,6 +8393,22 @@ msgid "Color uniform."
msgstr "清除變æ›"
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
@@ -8254,10 +8416,44 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
"Returns an associated vector if the provided boolean value is true or false."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
msgstr ""
@@ -8349,7 +8545,7 @@ msgid "Returns the arc-cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."
+msgid "Returns the inverse hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8357,7 +8553,7 @@ msgid "Returns the arc-sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter."
+msgid "Returns the inverse hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8369,7 +8565,7 @@ msgid "Returns the arc-tangent of the parameters."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."
+msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8386,7 +8582,7 @@ msgid "Returns the cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter."
+msgid "Returns the hyperbolic cosine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8455,11 +8651,11 @@ msgid "1.0 / scalar"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest integer to the parameter."
+msgid "Finds the nearest integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the nearest even integer to the parameter."
+msgid "Finds the nearest even integer to the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8475,7 +8671,7 @@ msgid "Returns the sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic sine of the parameter."
+msgid "Returns the hyperbolic sine of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8486,7 +8682,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8495,7 +8691,7 @@ msgstr ""
msgid ""
"Step function( scalar(edge), scalar(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8503,11 +8699,11 @@ msgid "Returns the tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter."
+msgid "Returns the hyperbolic tangent of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Finds the truncated value of the parameter."
+msgid "Finds the truncated value of the parameter."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8548,11 +8744,15 @@ msgid "Perform the texture lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Cubic texture uniform."
+msgid "Cubic texture uniform lookup."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "2D texture uniform."
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8562,7 +8762,7 @@ msgstr "轉æ›å°è©±æ¡†..。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) Calculate the outer product of a pair of vectors.\n"
+"Calculate the outer product of a pair of vectors.\n"
"\n"
"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
"one column) and the second parameter 'r' as a row vector (matrix with one "
@@ -8580,15 +8780,15 @@ msgid "Decomposes transform to four vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the determinant of a transform."
+msgid "Calculates the determinant of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the inverse of a transform."
+msgid "Calculates the inverse of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) Calculates the transpose of a transform."
+msgid "Calculates the transpose of a transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8640,7 +8840,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the same direction as a reference vector. "
+"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."
@@ -8655,6 +8855,10 @@ msgid "Linear interpolation between two vectors."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
msgstr ""
@@ -8668,19 +8872,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"Returns a vector that points in the direction of reflection ( a : incident "
+"Returns the vector that points in the direction of reflection ( a : incident "
"vector, b : normal vector )."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "Returns a vector that points in the direction of refraction."
+msgid "Returns the vector that points in the direction of refraction."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8689,7 +8893,7 @@ msgstr ""
msgid ""
"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than "
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
@@ -8698,14 +8902,14 @@ msgstr ""
msgid ""
"Step function( vector(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Step function( scalar(edge), vector(x) ).\n"
"\n"
-"Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8750,47 +8954,54 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function."
+msgid ""
+"Custom Godot Shader Language expression, which placed on top of the resulted "
+"shader. You can place various function definitions inside and call it later "
+"in the Expressions. You can also declare varyings, uniforms and constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function."
+msgid "(Fragment/Light mode only) Vector derivative function."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using "
-"local differencing."
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
-"(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative "
-"in 'x' and 'y'."
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8962,6 +9173,10 @@ msgid "Export templates for this platform are missing:"
msgstr "缺少此平臺的導出範本:"
#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr "管ç†è¼¸å‡ºæ¨¡æ¿"
+
+#: editor/project_export.cpp
msgid "Export With Debug"
msgstr "導出為調試"
@@ -9112,8 +9327,16 @@ msgstr "未命åé …ç›®"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Missing Project"
+msgstr "å°Žå…¥ç¾æœ‰é …ç›®"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Can't open project at '%s'."
-msgstr "無法打開ä½æ–¼â€œ%sâ€çš„項目。"
+msgstr "無法打開ä½æ–¼'%s'的項目。"
#: editor/project_manager.cpp
msgid "Are you sure to open more than one project?"
@@ -9199,8 +9422,8 @@ msgstr "是å¦å¾žæ¸…單中删除項目?(資料夾內容將ä¸è¢«ä¿®æ”¹ï¼‰"
#: editor/project_manager.cpp
#, fuzzy
msgid ""
-"Remove all missing projects from the list? (Folders contents will not be "
-"modified)"
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
msgstr "是å¦å¾žæ¸…單中删除項目?(資料夾內容將ä¸è¢«ä¿®æ”¹ï¼‰"
#: editor/project_manager.cpp
@@ -9220,8 +9443,9 @@ msgid "Project Manager"
msgstr ""
#: editor/project_manager.cpp
-msgid "Project List"
-msgstr ""
+#, fuzzy
+msgid "Projects"
+msgstr "專案"
#: editor/project_manager.cpp
msgid "Scan"
@@ -9245,10 +9469,6 @@ msgid "Templates"
msgstr ""
#: editor/project_manager.cpp
-msgid "Exit"
-msgstr ""
-
-#: editor/project_manager.cpp
msgid "Restart Now"
msgstr ""
@@ -9593,6 +9813,10 @@ msgstr ""
msgid "AutoLoad"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "挿件"
+
#: editor/property_editor.cpp
msgid "Zero"
msgstr ""
@@ -9645,14 +9869,6 @@ msgstr ""
msgid "Select Method"
msgstr ""
-#: editor/pvrtc_compress.cpp
-msgid "Could not execute PVRTC tool:"
-msgstr ""
-
-#: editor/pvrtc_compress.cpp
-msgid "Can't load back converted image using PVRTC tool:"
-msgstr ""
-
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "Batch Rename"
@@ -9953,6 +10169,10 @@ msgid "Remove Node(s)"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
@@ -10000,6 +10220,11 @@ msgstr "開啟最近存å–"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Reparent to New Node"
+msgstr "新增 %s"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Make Scene Root"
msgstr "儲存場景"
@@ -10077,19 +10302,19 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connection(s) and group(s).\n"
+"Node has %s connection(s) and %s group(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node has connections.\n"
+"Node has %s connection(s).\n"
"Click to show signals dock."
msgstr ""
#: editor/scene_tree_editor.cpp
msgid ""
-"Node is in group(s).\n"
+"Node is in %s group(s).\n"
"Click to show groups dock."
msgstr ""
@@ -10188,6 +10413,11 @@ msgid "Error loading script from %s"
msgstr ""
#: editor/script_create_dialog.cpp
+#, fuzzy
+msgid "Overrides"
+msgstr "覆蓋"
+
+#: editor/script_create_dialog.cpp
msgid "N/A"
msgstr ""
@@ -10220,7 +10450,7 @@ msgid "Script is valid."
msgstr "動畫樹有效。"
#: editor/script_create_dialog.cpp
-msgid "Allowed: a-z, A-Z, 0-9 and _"
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
msgstr ""
#: editor/script_create_dialog.cpp
@@ -10392,6 +10622,10 @@ msgid "Change Shortcut"
msgstr "æ·å¾‘"
#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr "編輯器設定"
+
+#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
msgstr "æ·å¾‘"
@@ -10831,10 +11065,30 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Override an existing built-in function."
+msgstr "無效å稱.ä¸èƒ½èˆ‡ç¾æœ‰çš„內置類型å稱沖çª."
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new function."
+msgstr "創建新矩形。"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new variable."
+msgstr "創建新矩形。"
+
+#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
+msgid "Create a new signal."
+msgstr "創建新多邊形。"
+
+#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
msgstr ""
@@ -11023,10 +11277,6 @@ msgid "Cut Nodes"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-msgid "Paste Nodes"
-msgstr ""
-
-#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
msgid "Edit Member"
msgstr "éŽæ¿¾æª”案..."
@@ -11792,22 +12042,6 @@ msgid ""
"texture to some node for display."
msgstr ""
-#: scene/resources/dynamic_font.cpp
-msgid "Error initializing FreeType."
-msgstr "åˆå§‹åŒ– FreeType 錯誤。"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Unknown font format."
-msgstr "未知的字體格å¼ã€‚"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Error loading font."
-msgstr "讀å–字體錯誤。"
-
-#: scene/resources/dynamic_font.cpp
-msgid "Invalid font size."
-msgstr "無效的字體大å°ã€‚"
-
#: scene/resources/visual_shader.cpp
msgid "Input"
msgstr ""
@@ -11822,6 +12056,11 @@ msgstr "無效的字體大å°ã€‚"
msgid "Invalid source for shader."
msgstr "無效的字體大å°ã€‚"
+#: scene/resources/visual_shader_nodes.cpp
+#, fuzzy
+msgid "Invalid comparison function for that type."
+msgstr "無效的字體大å°ã€‚"
+
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
msgstr ""
@@ -11838,6 +12077,96 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No Matches"
+#~ msgstr "無符åˆæ¢ä»¶"
+
+#~ msgid "Error loading image:"
+#~ msgstr "加載影åƒæ™‚出錯:"
+
+#~ msgid "No pixels with transparency > 128 in image..."
+#~ msgstr "å½±åƒä¸­æ²’有é€æ˜Žåº¦å¤§æ–¼128的點數…"
+
+#~ msgid "Parent has no solid faces to populate."
+#~ msgstr "父級沒有è¦å¡«å……的實體é¢ã€‚"
+
+#~ msgid "Couldn't map area."
+#~ msgstr "無法映射å€åŸŸã€‚"
+
+#~ msgid "Faces contain no area!"
+#~ msgstr "é¢ä¸åŒ…å«ä»»ä½•å€åŸŸï¼"
+
+#, fuzzy
+#~ msgid "Error: could not load file."
+#~ msgstr "無法新增資料夾"
+
+#~ msgid "Doppler Enable"
+#~ msgstr "啟用多普拉效應"
+
+#, fuzzy
+#~ msgid "Select Mode (Q)"
+#~ msgstr "é¸æ“‡æ¨¡å¼ (Q)"
+
+#~ msgid "Move Mode (W)"
+#~ msgstr "ç§»å‹•æ¨¡å¼ (W)"
+
+#~ msgid "Rotate Mode (E)"
+#~ msgstr "æ—‹è½‰æ¨¡å¼ (E)"
+
+#~ msgid "Scale Mode (R)"
+#~ msgstr "ç¸®æ”¾æ¨¡å¼ (R)"
+
+#~ msgid "Local Coords"
+#~ msgstr "本地å標"
+
+#~ msgid "Snap Mode (%s)"
+#~ msgstr "æ•æ‰æ¨¡å¼ (%s)"
+
+#, fuzzy
+#~ msgid "Tool Select"
+#~ msgstr "工具é¸æ“‡"
+
+#~ msgid "Tool Move"
+#~ msgstr "工具移動"
+
+#~ msgid "Tool Rotate"
+#~ msgstr "工具旋轉"
+
+#~ msgid "Tool Scale"
+#~ msgstr "縮放工具"
+
+#, fuzzy
+#~ msgid ""
+#~ "Remove all missing projects from the list? (Folders contents will not be "
+#~ "modified)"
+#~ msgstr "是å¦å¾žæ¸…單中删除項目?(資料夾內容將ä¸è¢«ä¿®æ”¹ï¼‰"
+
+#~ msgid "Error initializing FreeType."
+#~ msgstr "åˆå§‹åŒ– FreeType 錯誤。"
+
+#~ msgid "Unknown font format."
+#~ msgstr "未知的字體格å¼ã€‚"
+
+#~ msgid "Error loading font."
+#~ msgstr "讀å–字體錯誤。"
+
+#~ msgid "Invalid font size."
+#~ msgstr "無效的字體大å°ã€‚"
+
+#, fuzzy
+#~ msgid "Previous Folder"
+#~ msgstr "上個分é "
+
+#, fuzzy
+#~ msgid "Next Folder"
+#~ msgstr "新增資料夾"
+
+#, fuzzy
+#~ msgid "Open in an external image editor."
+#~ msgstr "開啟下一個編輯器"
+
+#~ msgid "Reverse"
+#~ msgstr "å轉"
+
#, fuzzy
#~ msgid "Failed to create solution."
#~ msgstr "無法新增資料夾"
diff --git a/main/SCsub b/main/SCsub
index e7fe6ab4e1..62bc155c67 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -6,6 +6,7 @@ from platform_methods import run_in_subprocess
import main_builders
env.main_sources = []
+
env.add_source_files(env.main_sources, "*.cpp")
# order matters here. higher index controller database files write on top of lower index database files
@@ -14,7 +15,9 @@ controller_databases = ["#main/gamecontrollerdb.txt", "#main/gamecontrollerdb_20
env.Depends("#main/default_controller_mappings.gen.cpp", controller_databases)
env.CommandNoCache("#main/default_controller_mappings.gen.cpp", controller_databases, run_in_subprocess(main_builders.make_default_controller_mappings))
-env.main_sources.append("#main/default_controller_mappings.gen.cpp")
+# Don't warn about duplicate entry here, we need it registered manually for first build,
+# even if later builds will pick it up twice due to above *.cpp globbing.
+env.add_source_files(env.main_sources, "#main/default_controller_mappings.gen.cpp", warn_duplicates=False)
env.Depends("#main/splash.gen.h", "#main/splash.png")
env.CommandNoCache("#main/splash.gen.h", "#main/splash.png", run_in_subprocess(main_builders.make_splash))
diff --git a/main/gamecontrollerdb.txt b/main/gamecontrollerdb.txt
index 440c0a8621..0e30cfe8d0 100644
--- a/main/gamecontrollerdb.txt
+++ b/main/gamecontrollerdb.txt
@@ -9,6 +9,7 @@
03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -26,6 +27,7 @@
03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+03000000bc2000006321000000000000,BETOP CONTROLLER,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -38,6 +40,8 @@
03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e040000ea02000000000000,Controller (Xbox One For Windows) - Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,
03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -64,6 +68,7 @@
03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
+030000006f0e00000102000000007801,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -73,6 +78,7 @@
03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
+030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
@@ -83,6 +89,7 @@
030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -96,11 +103,14 @@
030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000491900000304000000000000,Ipega PG-9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
030000006e0500000a20000000000000,JC-DUX60 ELECOM MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,
030000006e0500000520000000000000,JC-P301U,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
030000006e0500000320000000000000,JC-U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
+030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
+030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
03000000bd12000003c0000000000000,JY-P70UR,a:b1,b:b0,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b4,x:b3,y:b2,platform:Windows,
03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
@@ -139,7 +149,7 @@
03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
-03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,x:b9,y:b8,back:b13,guide:b12,start:b3,leftstick:b5,rightstick:b4,leftshoulder:b7,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a6,lefttrigger:a4,righttrigger:a5,platform:Windows,
+03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -147,6 +157,7 @@
03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
+030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -201,6 +212,7 @@
03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
+03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b0,y:b1,platform:Windows,
03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows,
03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
@@ -211,6 +223,7 @@
03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -244,6 +257,7 @@
03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
@@ -259,18 +273,21 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
-03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,x:b2,y:b3,back:b10,start:b9,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Mac OS X,
+03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
+030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
+030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
+030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -296,9 +313,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,x:b2,y:b3,back:b9,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Mac OS X,
+03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
+030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
@@ -311,8 +329,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000321500000009000000020000,Razer Serval,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Mac OS X,
-030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Mac OS X,
+03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
+030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
@@ -321,6 +339,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
+0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -338,6 +357,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
+030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -349,6 +369,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
# Linux
+05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
@@ -360,9 +381,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00003901000020060000,Afterglow Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,x:b3,y:b4,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Linux,
+05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
@@ -381,6 +403,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000007d0400000540000000010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
@@ -396,6 +419,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000ee00000011010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -408,9 +432,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
+03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,
+050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,
+050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -439,6 +466,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000079000000d218000011010000,MAGIC-NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
+03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
@@ -450,9 +478,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,x:b2,y:b3,back:b9,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Linux,
+05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
-05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,x:b2,y:b3,back:b9,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Linux,
+05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,
@@ -461,15 +489,17 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,x:b2,y:b3,back:b14,guide:b16,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,
-03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,x:b2,y:b3,back:b14,guide:b16,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,
+03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
+05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -524,6 +554,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000bc2000000055000010010000,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000632500002305000010010000,ShanWan USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
diff --git a/main/input_default.cpp b/main/input_default.cpp
index a03d015fc3..60675f1115 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -472,6 +472,10 @@ void InputDefault::stop_joy_vibration(int p_device) {
joy_vibration[p_device] = vibration;
}
+void InputDefault::vibrate_handheld(int p_duration_ms) {
+ OS::get_singleton()->vibrate_handheld(p_duration_ms);
+}
+
void InputDefault::set_gravity(const Vector3 &p_gravity) {
_THREAD_SAFE_METHOD_
@@ -629,6 +633,10 @@ Input::CursorShape InputDefault::get_default_cursor_shape() const {
}
void InputDefault::set_default_cursor_shape(CursorShape p_shape) {
+
+ if (default_shape == p_shape)
+ return;
+
default_shape = p_shape;
// The default shape is set in Viewport::_gui_input_event. To instantly
// see the shape in the viewport we need to trigger a mouse motion event.
@@ -686,7 +694,8 @@ void InputDefault::release_pressed_events() {
_joy_axis.clear();
for (Map<StringName, InputDefault::Action>::Element *E = action_state.front(); E; E = E->next()) {
- action_release(E->key());
+ if (E->get().pressed)
+ action_release(E->key());
}
}
diff --git a/main/input_default.h b/main/input_default.h
index 80ee17656c..4fc4ad6506 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -226,6 +226,7 @@ public:
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
virtual void stop_joy_vibration(int p_device);
+ virtual void vibrate_handheld(int p_duration_ms = 500);
void set_main_loop(MainLoop *p_main_loop);
void set_mouse_position(const Point2 &p_posf);
diff --git a/main/main.cpp b/main/main.cpp
index ef5c4109db..9ae885a5ce 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -30,6 +30,7 @@
#include "main.h"
+#include "core/crypto/crypto.h"
#include "core/input_map.h"
#include "core/io/file_access_network.h"
#include "core/io/file_access_pack.h"
@@ -37,8 +38,6 @@
#include "core/io/image_loader.h"
#include "core/io/ip.h"
#include "core/io/resource_loader.h"
-#include "core/io/stream_peer_ssl.h"
-#include "core/io/stream_peer_tcp.h"
#include "core/message_queue.h"
#include "core/os/dir_access.h"
#include "core/os/os.h"
@@ -387,6 +386,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool upwards = false;
String debug_mode;
String debug_host;
+ bool skip_breakpoints = false;
String main_pack;
bool quiet_stdout = false;
int rtm = -1;
@@ -599,6 +599,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
auto_build_solutions = true;
editor = true;
+#ifdef DEBUG_METHODS_ENABLED
+ } else if (I->get() == "--gdnative-generate-json-api") {
+ // Register as an editor instance to use the GLES2 fallback automatically on hardware that doesn't support the GLES3 backend
+ editor = true;
+
+ // We still pass it to the main arguments since the argument handling itself is not done in this function
+ main_args.push_back(I->get());
+#endif
} else if (I->get() == "--export" || I->get() == "--export-debug") { // Export project
editor = true;
@@ -730,6 +738,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
print_fps = true;
} else if (I->get() == "--disable-crash-handler") {
OS::get_singleton()->disable_crash_handler();
+ } else if (I->get() == "--skip-breakpoints") {
+ skip_breakpoints = true;
} else {
main_args.push_back(I->get());
}
@@ -783,8 +793,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater"));
GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10);
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
- GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_frame", 10);
- ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
+ GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_second", 100);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
+ GLOBAL_DEF("network/limits/debugger_stdout/max_warnings_per_second", 100);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_warnings_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_warnings_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
if (debug_mode == "remote") {
@@ -797,6 +809,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
Error derr = sdr->connect_to_host(debug_host, debug_port);
+ sdr->set_skip_breakpoints(skip_breakpoints);
+
if (derr != OK) {
memdelete(sdr);
} else {
@@ -814,10 +828,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String bp = breakpoints[i];
int sp = bp.find_last(":");
- if (sp == -1) {
- ERR_EXPLAIN("Invalid breakpoint: '" + bp + "', expected file:line format.");
- ERR_CONTINUE(true);
- }
+ ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format.");
script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp));
}
@@ -938,7 +949,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
}
- video_mode.use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", true);
+ video_mode.use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true);
OS::get_singleton()->_use_vsync = video_mode.use_vsync;
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
@@ -1373,10 +1384,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_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory.");
}
DocData doc;
doc.generate(doc_base);
@@ -1460,8 +1468,7 @@ bool Main::start() {
} else if (script != "") {
Ref<Script> script_res = ResourceLoader::load(script);
- ERR_EXPLAIN("Can't load script: " + script);
- ERR_FAIL_COND_V(script_res.is_null(), false);
+ ERR_FAIL_COND_V_MSG(script_res.is_null(), false, "Can't load script: " + script);
if (check_only) {
return false;
@@ -1475,8 +1482,7 @@ bool Main::start() {
if (!script_loop) {
if (obj)
memdelete(obj);
- ERR_EXPLAIN("Can't load script '" + script + "', it does not inherit from a MainLoop type");
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "Can't load script '" + script + "', it does not inherit from a MainLoop type.");
}
script_loop->set_init_script(script_res);
@@ -1500,17 +1506,13 @@ bool Main::start() {
} else {
Object *ml = ClassDB::instance(main_loop_type);
- if (!ml) {
- ERR_EXPLAIN("Can't instance MainLoop type");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(!ml, false, "Can't instance MainLoop type.");
main_loop = Object::cast_to<MainLoop>(ml);
if (!main_loop) {
memdelete(ml);
- ERR_EXPLAIN("Invalid MainLoop type");
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "Invalid MainLoop type.");
}
}
}
@@ -1573,8 +1575,7 @@ bool Main::start() {
}
RES res = ResourceLoader::load(path);
- ERR_EXPLAIN("Can't autoload: " + path);
- ERR_CONTINUE(res.is_null());
+ ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + path);
Node *n = NULL;
if (res->is_class("PackedScene")) {
Ref<PackedScene> ps = res;
@@ -1583,20 +1584,17 @@ bool Main::start() {
Ref<Script> script_res = res;
StringName ibt = script_res->get_instance_base_type();
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
- ERR_EXPLAIN("Script does not inherit a Node: " + path);
- ERR_CONTINUE(!valid_type);
+ ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + path);
Object *obj = ClassDB::instance(ibt);
- ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
- ERR_CONTINUE(obj == NULL);
+ ERR_CONTINUE_MSG(obj == NULL, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
n = Object::cast_to<Node>(obj);
n->set_script(script_res.get_ref_ptr());
}
- ERR_EXPLAIN("Path in autoload not a node or script: " + path);
- ERR_CONTINUE(!n);
+ ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path);
n->set_name(name);
//defer so references are all valid on _ready()
@@ -1754,8 +1752,8 @@ bool Main::start() {
if (!project_manager && !editor) { // game
- // Load SSL Certificates from Project Settings (or builtin)
- StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
+ // Load SSL Certificates from Project Settings (or builtin).
+ Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificates", ""));
if (game_path != "") {
Node *scene = NULL;
@@ -1763,8 +1761,7 @@ bool Main::start() {
if (scenedata.is_valid())
scene = scenedata->instance();
- ERR_EXPLAIN("Failed loading scene: " + local_game_path);
- ERR_FAIL_COND_V(!scene, false);
+ ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path);
sml->add_current_scene(scene);
#ifdef OSX_ENABLED
@@ -1808,17 +1805,15 @@ bool Main::start() {
}
if (project_manager || editor) {
- // Load SSL Certificates from Editor Settings (or builtin)
- String certs = EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String();
- if (certs != "")
- StreamPeerSSL::load_certs_from_file(certs);
- else
- StreamPeerSSL::load_certs_from_memory(StreamPeerSSL::get_project_cert_array());
-
- // Hide console window if requested (Windows-only)
+ // Hide console window if requested (Windows-only).
bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window");
OS::get_singleton()->set_console_visible(!hide_console);
}
+
+ if (project_manager || editor) {
+ // Load SSL Certificates from Editor Settings (or builtin)
+ Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String());
+ }
#endif
}
@@ -1852,7 +1847,7 @@ bool Main::is_iterating() {
return iterating > 0;
}
-// For performance metrics
+// For performance metrics.
static uint64_t physics_process_max = 0;
static uint64_t idle_process_max = 0;
@@ -1880,6 +1875,7 @@ bool Main::iteration() {
double scaled_step = step * time_scale;
Engine::get_singleton()->_frame_step = step;
+ Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction;
uint64_t physics_process_ticks = 0;
uint64_t idle_process_ticks = 0;
diff --git a/main/main.h b/main/main.h
index 694305526a..b0b90dc0fe 100644
--- a/main/main.h
+++ b/main/main.h
@@ -31,10 +31,6 @@
#ifndef MAIN_H
#define MAIN_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/error_list.h"
#include "core/os/thread.h"
#include "core/typedefs.h"
diff --git a/main/main_timer_sync.cpp b/main/main_timer_sync.cpp
index f7388c8517..edacb20f28 100644
--- a/main/main_timer_sync.cpp
+++ b/main/main_timer_sync.cpp
@@ -178,6 +178,10 @@ MainFrameTime MainTimerSync::advance_checked(float p_frame_slice, int p_iteratio
// track deficit
time_deficit = p_idle_step - ret.idle_step;
+ // p_frame_slice is 1.0 / iterations_per_sec
+ // i.e. the time in seconds taken by a physics tick
+ ret.interpolation_fraction = time_accum / p_frame_slice;
+
return ret;
}
diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h
index 179119edce..93d335b27f 100644
--- a/main/main_timer_sync.h
+++ b/main/main_timer_sync.h
@@ -36,6 +36,7 @@
struct MainFrameTime {
float idle_step; // time to advance idles for (argument to process())
int physics_steps; // number of times to iterate the physics engine
+ float interpolation_fraction; // fraction through the current physics tick
void clamp_idle(float min_idle_step, float max_idle_step);
};
diff --git a/main/tests/test_gdscript.cpp b/main/tests/test_gdscript.cpp
index e82af93293..b2b2c22bf9 100644
--- a/main/tests/test_gdscript.cpp
+++ b/main/tests/test_gdscript.cpp
@@ -300,14 +300,11 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
} break;
default: {
- String error = "Parser bug at " + itos(p_expr->line) + ", invalid expression type: " + itos(p_expr->type);
- ERR_EXPLAIN(error);
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Parser bug at " + itos(p_expr->line) + ", invalid expression type: " + itos(p_expr->type));
}
}
return txt;
- //return "("+txt+")";
}
static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_indent) {
@@ -910,8 +907,7 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
if (incr == 0) {
- ERR_EXPLAIN("unhandled opcode: " + itos(code[ip]));
- ERR_BREAK(true);
+ ERR_BREAK_MSG(true, "Unhandled opcode: " + itos(code[ip]));
}
ip += incr;
@@ -936,11 +932,7 @@ MainLoop *test(TestType p_type) {
}
FileAccess *fa = FileAccess::open(test, FileAccess::READ);
-
- if (!fa) {
- ERR_EXPLAIN("Could not open file: " + test);
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!fa, NULL, "Could not open file: " + test);
Vector<uint8_t> buf;
int flen = fa->get_len();
diff --git a/main/tests/test_gui.h b/main/tests/test_gui.h
index 1752818981..075bc40aa7 100644
--- a/main/tests/test_gui.h
+++ b/main/tests/test_gui.h
@@ -33,9 +33,6 @@
#include "core/os/main_loop.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
namespace TestGUI {
MainLoop *test();
diff --git a/main/tests/test_math.cpp b/main/tests/test_math.cpp
index f341159079..68ecb2b1b2 100644
--- a/main/tests/test_math.cpp
+++ b/main/tests/test_math.cpp
@@ -494,11 +494,7 @@ MainLoop *test() {
}
FileAccess *fa = FileAccess::open(test, FileAccess::READ);
-
- if (!fa) {
- ERR_EXPLAIN("Could not open file: " + test);
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!fa, NULL, "Could not open file: " + test);
Vector<uint8_t> buf;
int flen = fa->get_len();
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index 070420e432..bf5b4588ea 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -121,6 +121,25 @@ MainLoop *test() {
delete[] keys;
}
+ // regression test / test for issue related to #31402
+ {
+
+ OS::get_singleton()->print("test for issue #31402 started...\n");
+
+ const int num_test_values = 12;
+ int test_values[num_test_values] = { 0, 24, 48, 72, 96, 120, 144, 168, 192, 216, 240, 264 };
+
+ int dummy = 0;
+ OAHashMap<int, int> map;
+ map.clear();
+
+ for (int i = 0; i < num_test_values; ++i) {
+ map.set(test_values[i], dummy);
+ }
+
+ OS::get_singleton()->print("test for issue #31402 passed.\n");
+ }
+
return NULL;
}
} // namespace TestOAHashMap
diff --git a/main/tests/test_physics.h b/main/tests/test_physics.h
index 699e31f492..a281f669e0 100644
--- a/main/tests/test_physics.h
+++ b/main/tests/test_physics.h
@@ -31,10 +31,6 @@
#ifndef TEST_PHYSICS_H
#define TEST_PHYSICS_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestPhysics {
diff --git a/main/tests/test_render.h b/main/tests/test_render.h
index 3810760b56..6dda57db5b 100644
--- a/main/tests/test_render.h
+++ b/main/tests/test_render.h
@@ -31,10 +31,6 @@
#ifndef TEST_RENDER_H
#define TEST_RENDER_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/main_loop.h"
namespace TestRender {
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/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 05df888f40..7a41880645 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -432,6 +432,10 @@ bool test_26() {
OS::get_singleton()->print("\n\nTest 26: RegEx substitution\n");
+#ifndef MODULE_REGEX_ENABLED
+ OS::get_singleton()->print("\tRegEx module disabled, can't run test.");
+ return false;
+#else
String s = "Double all the vowels.";
OS::get_singleton()->print("\tString: %ls\n", s.c_str());
@@ -443,6 +447,7 @@ bool test_26() {
OS::get_singleton()->print("\tResult: %ls\n", s.c_str());
return (s == "Doouublee aall thee vooweels.");
+#endif
}
struct test_27_data {
@@ -1078,6 +1083,44 @@ bool test_34() {
return state;
}
+bool test_35() {
+#define COUNT_TEST(x) \
+ { \
+ bool success = x; \
+ state = state && success; \
+ if (!success) { \
+ OS::get_singleton()->print("\tfailed at: %s\n", #x); \
+ } \
+ }
+
+ OS::get_singleton()->print("\n\nTest 35: count and countn function\n");
+ bool state = true;
+
+ COUNT_TEST(String("").count("Test") == 0);
+ COUNT_TEST(String("Test").count("") == 0);
+ COUNT_TEST(String("Test").count("test") == 0);
+ COUNT_TEST(String("Test").count("TEST") == 0);
+ COUNT_TEST(String("TEST").count("TEST") == 1);
+ COUNT_TEST(String("Test").count("Test") == 1);
+ COUNT_TEST(String("aTest").count("Test") == 1);
+ COUNT_TEST(String("Testa").count("Test") == 1);
+ COUNT_TEST(String("TestTestTest").count("Test") == 3);
+ COUNT_TEST(String("TestTestTest").count("TestTest") == 1);
+ COUNT_TEST(String("TestGodotTestGodotTestGodot").count("Test") == 3);
+
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 8) == 1);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 12) == 2);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4, 16) == 3);
+ COUNT_TEST(String("TestTestTestTest").count("Test", 4) == 3);
+
+ COUNT_TEST(String("Test").countn("test") == 1);
+ COUNT_TEST(String("Test").countn("TEST") == 1);
+ COUNT_TEST(String("testTest-Testatest").countn("tEst") == 4);
+ COUNT_TEST(String("testTest-TeStatest").countn("tEsT", 4, 16) == 2);
+
+ return state;
+}
+
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
@@ -1116,6 +1159,7 @@ TestFunc test_funcs[] = {
test_32,
test_33,
test_34,
+ test_35,
0
};
diff --git a/methods.py b/methods.py
index bb4adfb70b..86ab7cd9af 100644
--- a/methods.py
+++ b/methods.py
@@ -8,14 +8,28 @@ import subprocess
from compat import iteritems, isbasestring, decode_utf8
-def add_source_files(self, sources, filetype, lib_env=None, shared=False):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path + "/" + filetype))
-
- for path in filetype:
- sources.append(self.Object(path))
+def add_source_files(self, sources, files, warn_duplicates=True):
+ # Convert string to list of absolute paths (including expanding wildcard)
+ if isbasestring(files):
+ # Keep SCons project-absolute path as they are (no wildcard support)
+ if files.startswith('#'):
+ if '*' in files:
+ print("ERROR: Wildcards can't be expanded in SCons project-absolute path: '{}'".format(files))
+ return
+ files = [files]
+ else:
+ dir_path = self.Dir('.').abspath
+ files = sorted(glob.glob(dir_path + "/" + files))
+
+ # Add each path as compiled Object following environment (self) configuration
+ for path in files:
+ obj = self.Object(path)
+ if obj in sources:
+ if warn_duplicates:
+ print("WARNING: Object \"{}\" already included in environment sources.".format(obj))
+ else:
+ continue
+ sources.append(obj)
def disable_warnings(self):
@@ -603,7 +617,11 @@ def detect_darwin_sdk_path(platform, env):
raise
def get_compiler_version(env):
- version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
+ # Not using this method on clang because it returns 4.2.1 # https://reviews.llvm.org/D56803
+ if using_gcc(env):
+ version = decode_utf8(subprocess.check_output([env['CXX'], '-dumpversion']).strip())
+ else:
+ version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip())
match = re.search('[0-9][0-9.]*', version)
if match is not None:
return match.group().split('.')
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 0e8a41a9fc..12b9af21e5 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -180,9 +180,9 @@ $GODOT_HEAD_INCLUDE
[statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
elem.style.display = 'none';
});
- if (animateStatusIndeterminate in animationCallbacks) {
- animationCallbacks.erase(animateStatusIndeterminate);
- }
+ animationCallbacks = animationCallbacks.filter(function(value) {
+ return (value != animateStatusIndeterminate);
+ });
switch (mode) {
case 'progress':
statusProgress.style.display = 'block';
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index db241ad172..e309233a8b 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -86,6 +86,9 @@ do
if grep -q "thirdparty" <<< $file; then
continue;
fi
+ if grep -q "platform/android/java/lib/src/com" <<< $file; then
+ continue;
+ fi
# ignore file if we do check for file extensions and the file
# does not match any of the extensions specified in $FILE_EXTS
diff --git a/misc/ide/jetbrains/AndroidManifest.xml b/misc/ide/jetbrains/AndroidManifest.xml
deleted file mode 100644
index 232a95e779..0000000000
--- a/misc/ide/jetbrains/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.godot.game"
- android:versionCode="1"
- android:versionName="1.0"
- android:installLocation="auto"
- >
-<supports-screens android:smallScreens="true"
- android:normalScreens="true"
- android:largeScreens="true"
- android:xlargeScreens="true"/>
-
- <uses-feature android:glEsVersion="0x00020000" android:required="true" />
-
-
-
- <application android:label="@string/godot_project_name_string" android:icon="@drawable/icon" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" >
- <activity android:name="org.godotengine.godot.Godot"
- android:label="@string/godot_project_name_string"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:launchMode="singleTask"
- android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize"
- android:resizeableActivity="false"
- tools:ignore="UnusedAttribute">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service android:name="org.godotengine.godot.GodotDownloaderService" />
-
-
-
- </application>
-
- <instrumentation android:icon="@drawable/icon"
- android:label="@string/godot_project_name_string"
- android:name="org.godotengine.godot.GodotInstrumentation"
- android:targetPackage="com.godot.game" />
-
-</manifest>
diff --git a/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar b/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index f6b961fd5a..0000000000
--- a/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties b/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index b477add150..0000000000
--- a/misc/ide/jetbrains/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Sun Mar 31 16:34:43 PDT 2019
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
diff --git a/misc/ide/jetbrains/gradlew b/misc/ide/jetbrains/gradlew
deleted file mode 100755
index cccdd3d517..0000000000
--- a/misc/ide/jetbrains/gradlew
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env sh
-
-##############################################################################
-##
-## Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
- echo "$*"
-}
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=$((i+1))
- done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
-fi
-
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=$(save "$@")
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
-exec "$JAVACMD" "$@"
diff --git a/misc/ide/jetbrains/gradlew.bat b/misc/ide/jetbrains/gradlew.bat
deleted file mode 100644
index f9553162f1..0000000000
--- a/misc/ide/jetbrains/gradlew.bat
+++ /dev/null
@@ -1,84 +0,0 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/misc/travis/clang-format.sh b/misc/travis/clang-format.sh
index 5463a6cedf..097b2a9378 100755
--- a/misc/travis/clang-format.sh
+++ b/misc/travis/clang-format.sh
@@ -11,7 +11,7 @@ else
RANGE=HEAD
fi
-FILES=$(git diff-tree --no-commit-id --name-only -r $RANGE | grep -v thirdparty/ | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$")
+FILES=$(git diff-tree --no-commit-id --name-only -r $RANGE | grep -v thirdparty/ | grep -v platform/android/java/lib/src/com/ | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$")
echo "Checking files:\n$FILES"
# create a random filename to store our generated patch
diff --git a/modules/SCsub b/modules/SCsub
index 36c2472c42..42d89d6ce2 100644
--- a/modules/SCsub
+++ b/modules/SCsub
@@ -6,9 +6,9 @@ env_modules = env.Clone()
Export('env_modules')
-env.modules_sources = [
- "register_module_types.gen.cpp",
-]
+env.modules_sources = []
+
+env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp")
for x in env.module_list:
if (x in env.disabled_modules):
diff --git a/modules/arkit/arkit_interface.h b/modules/arkit/arkit_interface.h
index 8129611287..e1dbca1488 100644
--- a/modules/arkit/arkit_interface.h
+++ b/modules/arkit/arkit_interface.h
@@ -3,10 +3,10 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
-/* http://www.godotengine.org */
+/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index de58f93276..9614f775a5 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -3,10 +3,10 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
-/* http://www.godotengine.org */
+/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
@@ -430,7 +430,7 @@ void ARKitInterface::process() {
// get some info about our screen and orientation
Size2 screen_size = OS::get_singleton()->get_window_size();
- UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
+ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// Grab our camera image for our backbuffer
CVPixelBufferRef pixelBuffer = current_frame.capturedImage;
@@ -531,7 +531,7 @@ void ARKitInterface::process() {
// we need to invert this, probably row v.s. column notation
affine_transform = CGAffineTransformInvert(affine_transform);
- if (orientation != UIDeviceOrientationPortrait) {
+ if (orientation != UIInterfaceOrientationPortrait) {
affine_transform.b = -affine_transform.b;
affine_transform.d = -affine_transform.d;
affine_transform.ty = 1.0 - affine_transform.ty;
@@ -582,28 +582,28 @@ void ARKitInterface::process() {
// copy our current frame transform
matrix_float4x4 m44 = camera.transform;
- if (orientation == UIDeviceOrientationLandscapeLeft) {
+ if (orientation == UIInterfaceOrientationLandscapeLeft) {
transform.basis.elements[0].x = m44.columns[0][0];
transform.basis.elements[1].x = m44.columns[0][1];
transform.basis.elements[2].x = m44.columns[0][2];
transform.basis.elements[0].y = m44.columns[1][0];
transform.basis.elements[1].y = m44.columns[1][1];
transform.basis.elements[2].y = m44.columns[1][2];
- } else if (orientation == UIDeviceOrientationPortrait) {
+ } else if (orientation == UIInterfaceOrientationPortrait) {
transform.basis.elements[0].x = m44.columns[1][0];
transform.basis.elements[1].x = m44.columns[1][1];
transform.basis.elements[2].x = m44.columns[1][2];
transform.basis.elements[0].y = -m44.columns[0][0];
transform.basis.elements[1].y = -m44.columns[0][1];
transform.basis.elements[2].y = -m44.columns[0][2];
- } else if (orientation == UIDeviceOrientationLandscapeRight) {
+ } else if (orientation == UIInterfaceOrientationLandscapeRight) {
transform.basis.elements[0].x = -m44.columns[0][0];
transform.basis.elements[1].x = -m44.columns[0][1];
transform.basis.elements[2].x = -m44.columns[0][2];
transform.basis.elements[0].y = -m44.columns[1][0];
transform.basis.elements[1].y = -m44.columns[1][1];
transform.basis.elements[2].y = -m44.columns[1][2];
- } else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
+ } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
// this may not be correct
transform.basis.elements[0].x = m44.columns[1][0];
transform.basis.elements[1].x = m44.columns[1][1];
diff --git a/modules/arkit/arkit_session_delegate.h b/modules/arkit/arkit_session_delegate.h
index afe093656b..9303552ca6 100644
--- a/modules/arkit/arkit_session_delegate.h
+++ b/modules/arkit/arkit_session_delegate.h
@@ -3,10 +3,10 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
-/* http://www.godotengine.org */
+/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
diff --git a/modules/arkit/arkit_session_delegate.mm b/modules/arkit/arkit_session_delegate.mm
index 56485c987c..d4072fc391 100644
--- a/modules/arkit/arkit_session_delegate.mm
+++ b/modules/arkit/arkit_session_delegate.mm
@@ -3,10 +3,10 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
-/* http://www.godotengine.org */
+/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub
index 8a77e4f803..275f1ff5e9 100644
--- a/modules/assimp/SCsub
+++ b/modules/assimp/SCsub
@@ -9,6 +9,7 @@ env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/include'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/IFC'])
env_assimp.Prepend(CPPPATH=['#thirdparty/misc'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code'])
+env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/common'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/irrXML/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/unzip/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser'])
@@ -65,18 +66,13 @@ 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(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED'])
-if (not env.msvc):
- env_assimp.Append(CXXFLAGS=['-std=c++11'])
-elif (env.msvc == False and env['platform'] == 'windows'):
- env_assimp.Append(LDFLAGS=['-pthread'])
-
if(env['platform'] == 'windows'):
env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS'])
env_assimp.Append(CPPDEFINES=[('PLATFORM', 'WINDOWS')])
@@ -89,7 +85,13 @@ elif(env['platform'] == 'osx'):
env_thirdparty = env_assimp.Clone()
env_thirdparty.disable_warnings()
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Common/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/PostProcessing/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Material/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/FBX/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/MMD/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF2/*.cpp'))
# Godot's own source files
env_assimp.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index f23c66dbcf..f2f51d9dd3 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -28,24 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "assimp/DefaultLogger.hpp"
-#include "assimp/Importer.hpp"
-#include "assimp/LogStream.hpp"
-#include "assimp/Logger.hpp"
-#include "assimp/SceneCombiner.h"
-#include "assimp/cexport.h"
-#include "assimp/cimport.h"
-#include "assimp/matrix4x4.h"
-#include "assimp/pbrmaterial.h"
-#include "assimp/postprocess.h"
-#include "assimp/scene.h"
-
+#include "editor_scene_importer_assimp.h"
#include "core/bind/core_bind.h"
#include "core/io/image_loader.h"
#include "editor/editor_file_system.h"
#include "editor/import/resource_importer_scene.h"
-#include "editor_scene_importer_assimp.h"
#include "editor_settings.h"
+#include "import_utils.h"
#include "scene/3d/camera.h"
#include "scene/3d/light.h"
#include "scene/3d/mesh_instance.h"
@@ -53,7 +42,19 @@
#include "scene/main/node.h"
#include "scene/resources/material.h"
#include "scene/resources/surface_tool.h"
-#include "zutil.h"
+
+#include <assimp/SceneCombiner.h>
+#include <assimp/cexport.h>
+#include <assimp/cimport.h>
+#include <assimp/matrix4x4.h>
+#include <assimp/pbrmaterial.h>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <zutil.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/LogStream.hpp>
+#include <assimp/Logger.hpp>
#include <string>
void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const {
@@ -92,18 +93,6 @@ uint32_t EditorSceneImporterAssimp::get_import_flags() const {
return IMPORT_SCENE;
}
-AssimpStream::AssimpStream() {
- // empty
-}
-
-AssimpStream::~AssimpStream() {
- // empty
-}
-
-void AssimpStream::write(const char *message) {
- print_verbose(String("Open Asset Import: ") + String(message).strip_edges());
-}
-
void EditorSceneImporterAssimp::_bind_methods() {
}
@@ -122,34 +111,34 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
//}
importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT);
+
//importer.SetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD, 1.0f);
int32_t post_process_Steps = aiProcess_CalcTangentSpace |
+ aiProcess_GlobalScale | // imports models and listens to their file scale for CM to M conversions
//aiProcess_FlipUVs |
- //aiProcess_FlipWindingOrder |
+ aiProcess_FlipWindingOrder | // very important for culling so that it is done in the correct order.
//aiProcess_DropNormals |
//aiProcess_GenSmoothNormals |
- aiProcess_JoinIdenticalVertices |
+ //aiProcess_JoinIdenticalVertices |
aiProcess_ImproveCacheLocality |
- aiProcess_LimitBoneWeights |
//aiProcess_RemoveRedundantMaterials | // Causes a crash
- aiProcess_SplitLargeMeshes |
+ //aiProcess_SplitLargeMeshes |
aiProcess_Triangulate |
aiProcess_GenUVCoords |
//aiProcess_FindDegenerates |
- aiProcess_SortByPType |
- aiProcess_FindInvalidData |
+ //aiProcess_SortByPType |
+ // aiProcess_FindInvalidData |
aiProcess_TransformUVCoords |
aiProcess_FindInstances |
//aiProcess_FixInfacingNormals |
- //aiProcess_ValidateDataStructure |
+ aiProcess_ValidateDataStructure |
aiProcess_OptimizeMeshes |
//aiProcess_OptimizeGraph |
//aiProcess_Debone |
- aiProcess_EmbedTextures |
- aiProcess_SplitByBoneCount |
+ // aiProcess_EmbedTextures |
+ //aiProcess_SplitByBoneCount |
0;
- const aiScene *scene = importer.ReadFile(s_path.c_str(),
- post_process_Steps);
+ aiScene *scene = (aiScene *)importer.ReadFile(s_path.c_str(), post_process_Steps);
ERR_EXPLAIN(String("Open Asset Import failed to open: ") + String(importer.GetErrorString()));
ERR_FAIL_COND_V(scene == NULL, NULL);
return _generate_scene(p_path, scene, p_flags, p_bake_fps, max_bone_weights);
@@ -282,159 +271,7 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
ERR_FAIL_V(p_values[0]);
}
-void EditorSceneImporterAssimp::_generate_bone_groups(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<String, Transform> &bind_xforms) {
-
- Transform mesh_offset = _get_global_assimp_node_transform(p_assimp_node);
- //mesh_offset.basis = Basis();
- for (uint32_t i = 0; i < p_assimp_node->mNumMeshes; i++) {
- const aiMesh *mesh = state.assimp_scene->mMeshes[i];
- int owned_by = -1;
- for (uint32_t j = 0; j < mesh->mNumBones; j++) {
- const aiBone *bone = mesh->mBones[j];
- String name = _assimp_get_string(bone->mName);
-
- if (ownership.has(name)) {
- owned_by = ownership[name];
- break;
- }
- }
-
- if (owned_by == -1) { //no owned, create new unique id
- owned_by = 1;
- for (Map<String, int>::Element *E = ownership.front(); E; E = E->next()) {
- owned_by = MAX(E->get() + 1, owned_by);
- }
- }
-
- for (uint32_t j = 0; j < mesh->mNumBones; j++) {
- const aiBone *bone = mesh->mBones[j];
- String name = _assimp_get_string(bone->mName);
- ownership[name] = owned_by;
- //store the actual full path for the bone transform
- //when skeleton finds its place in the tree, it will be restored
- bind_xforms[name] = mesh_offset * _assimp_matrix_transform(bone->mOffsetMatrix);
- }
- }
-
- for (size_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- _generate_bone_groups(state, p_assimp_node->mChildren[i], ownership, bind_xforms);
- }
-}
-
-void EditorSceneImporterAssimp::_fill_node_relationships(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, int p_skeleton_id, Skeleton *p_skeleton, const String &p_parent_name, int &holecount, const Vector<SkeletonHole> &p_holes, const Map<String, Transform> &bind_xforms) {
-
- String name = _assimp_get_string(p_assimp_node->mName);
- if (name == String()) {
- name = "AuxiliaryBone" + itos(holecount++);
- }
-
- Transform pose = _assimp_matrix_transform(p_assimp_node->mTransformation);
-
- if (!ownership.has(name)) {
- //not a bone, it's a hole
- Vector<SkeletonHole> holes = p_holes;
- SkeletonHole hole; //add a new one
- hole.name = name;
- hole.pose = pose;
- hole.node = p_assimp_node;
- hole.parent = p_parent_name;
- holes.push_back(hole);
-
- for (size_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- _fill_node_relationships(state, p_assimp_node->mChildren[i], ownership, skeleton_map, p_skeleton_id, p_skeleton, name, holecount, holes, bind_xforms);
- }
-
- return;
- } else if (ownership[name] != p_skeleton_id) {
- //oh, it's from another skeleton? fine.. reparent all bones to this skeleton.
- int prev_owner = ownership[name];
- ERR_EXPLAIN("A previous skeleton exists for bone '" + name + "', this type of skeleton layout is unsupported.");
- ERR_FAIL_COND(skeleton_map.has(prev_owner));
- for (Map<String, int>::Element *E = ownership.front(); E; E = E->next()) {
- if (E->get() == prev_owner) {
- E->get() = p_skeleton_id;
- }
- }
- }
-
- //valid bone, first fill holes if needed
- for (int i = 0; i < p_holes.size(); i++) {
-
- int bone_idx = p_skeleton->get_bone_count();
- p_skeleton->add_bone(p_holes[i].name);
- int parent_idx = p_skeleton->find_bone(p_holes[i].parent);
- if (parent_idx >= 0) {
- p_skeleton->set_bone_parent(bone_idx, parent_idx);
- }
-
- Transform pose_transform = _get_global_assimp_node_transform(p_holes[i].node);
- p_skeleton->set_bone_rest(bone_idx, pose_transform);
-
- state.bone_owners[p_holes[i].name] = skeleton_map[p_skeleton_id];
- }
-
- //finally fill bone
-
- int bone_idx = p_skeleton->get_bone_count();
- p_skeleton->add_bone(name);
- int parent_idx = p_skeleton->find_bone(p_parent_name);
- if (parent_idx >= 0) {
- p_skeleton->set_bone_parent(bone_idx, parent_idx);
- }
- //p_skeleton->set_bone_pose(bone_idx, pose);
- if (bind_xforms.has(name)) {
- //for now this is the full path to the bone in rest pose
- //when skeleton finds it's place in the tree, it will get fixed
- p_skeleton->set_bone_rest(bone_idx, bind_xforms[name]);
- }
- state.bone_owners[name] = skeleton_map[p_skeleton_id];
- //go to children
- for (size_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- _fill_node_relationships(state, p_assimp_node->mChildren[i], ownership, skeleton_map, p_skeleton_id, p_skeleton, name, holecount, Vector<SkeletonHole>(), bind_xforms);
- }
-}
-
-void EditorSceneImporterAssimp::_generate_skeletons(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, const Map<String, Transform> &bind_xforms) {
-
- //find skeletons at this level, there may be multiple root nodes for each
- Map<int, List<aiNode *> > skeletons_found;
- for (size_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- String name = _assimp_get_string(p_assimp_node->mChildren[i]->mName);
- if (ownership.has(name)) {
- int skeleton = ownership[name];
- if (!skeletons_found.has(skeleton)) {
- skeletons_found[skeleton] = List<aiNode *>();
- }
- skeletons_found[skeleton].push_back(p_assimp_node->mChildren[i]);
- }
- }
-
- //go via the potential skeletons found and generate the actual skeleton
- for (Map<int, List<aiNode *> >::Element *E = skeletons_found.front(); E; E = E->next()) {
- ERR_CONTINUE(skeleton_map.has(E->key())); //skeleton already exists? this can't be.. skip
- Skeleton *skeleton = memnew(Skeleton);
- //this the only way to reliably use multiple meshes with one skeleton, at the cost of less precision
- skeleton->set_use_bones_in_world_transform(true);
- skeleton_map[E->key()] = state.skeletons.size();
- state.skeletons.push_back(skeleton);
- int holecount = 1;
- //fill the bones and their relationships
- for (List<aiNode *>::Element *F = E->get().front(); F; F = F->next()) {
- _fill_node_relationships(state, F->get(), ownership, skeleton_map, E->key(), skeleton, "", holecount, Vector<SkeletonHole>(), bind_xforms);
- }
- }
-
- //go to the children
- for (uint32_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- String name = _assimp_get_string(p_assimp_node->mChildren[i]->mName);
- if (ownership.has(name)) {
- continue; //a bone, so don't bother with this
- }
- _generate_skeletons(state, p_assimp_node->mChildren[i], ownership, skeleton_map, bind_xforms);
- }
-}
-
-Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, const aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights) {
+Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights) {
ERR_FAIL_COND_V(scene == NULL, NULL);
ImportState state;
@@ -445,60 +282,37 @@ Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, const
state.fbx = false;
state.animation_player = NULL;
- real_t scale_factor = 1.0f;
- {
- //handle scale
- String ext = p_path.get_file().get_extension().to_lower();
- if (ext == "fbx") {
- if (scene->mMetaData != NULL) {
- float factor = 1.0;
- scene->mMetaData->Get("UnitScaleFactor", factor);
- scale_factor = factor * 0.01f;
- }
- state.fbx = true;
- }
- }
-
- state.root->set_scale(Vector3(scale_factor, scale_factor, scale_factor));
-
//fill light map cache
for (size_t l = 0; l < scene->mNumLights; l++) {
aiLight *ai_light = scene->mLights[l];
ERR_CONTINUE(ai_light == NULL);
- state.light_cache[_assimp_get_string(ai_light->mName)] = l;
+ state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l;
}
//fill camera cache
for (size_t c = 0; c < scene->mNumCameras; c++) {
aiCamera *ai_camera = scene->mCameras[c];
ERR_CONTINUE(ai_camera == NULL);
- state.camera_cache[_assimp_get_string(ai_camera->mName)] = c;
+ state.camera_cache[AssimpUtils::get_assimp_string(ai_camera->mName)] = c;
}
if (scene->mRootNode) {
- Map<String, Transform> bind_xforms; //temporary map to store bind transforms
- //guess the skeletons, since assimp does not really support them directly
- Map<String, int> ownership; //bone names to groups
- //fill this map with bone names and which group where they detected to, going mesh by mesh
- _generate_bone_groups(state, state.assimp_scene->mRootNode, ownership, bind_xforms);
- Map<int, int> skeleton_map; //maps previously created groups to actual skeletons
- //generates the skeletons when bones are found in the hierarchy, and follows them (including gaps/holes).
- _generate_skeletons(state, state.assimp_scene->mRootNode, ownership, skeleton_map, bind_xforms);
//generate nodes
for (uint32_t i = 0; i < scene->mRootNode->mNumChildren; i++) {
- _generate_node(state, scene->mRootNode->mChildren[i], state.root);
+ _generate_node(state, NULL, scene->mRootNode->mChildren[i], state.root);
}
- //assign skeletons to nodes
-
- for (Map<MeshInstance *, Skeleton *>::Element *E = state.mesh_skeletons.front(); E; E = E->next()) {
- MeshInstance *mesh = E->key();
- Skeleton *skeleton = E->get();
- NodePath skeleton_path = mesh->get_path_to(skeleton);
- mesh->set_skeleton_path(skeleton_path);
+ // finalize skeleton
+ for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ Skeleton *skeleton = key_value_pair->key();
+ // convert world to local for skeleton bone rests
+ skeleton->localize_rests();
}
+
+ print_verbose("generating mesh phase from skeletal mesh");
+ generate_mesh_phase_from_skeletal_mesh(state);
}
if (p_flags & IMPORT_ANIMATION && scene->mNumAnimations) {
@@ -603,12 +417,14 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
}
}
+// animation tracks are per bone
+
void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_animation_index, int p_bake_fps) {
ERR_FAIL_INDEX(p_animation_index, (int)state.assimp_scene->mNumAnimations);
const aiAnimation *anim = state.assimp_scene->mAnimations[p_animation_index];
- String name = _assimp_anim_string_to_string(anim->mName);
+ String name = AssimpUtils::get_anim_string_from_assimp(anim->mName);
if (name == String()) {
name = "Animation " + itos(p_animation_index + 1);
}
@@ -618,7 +434,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
if (state.assimp_scene->mMetaData != NULL && Math::is_equal_approx(ticks_per_second, 0.0f)) {
int32_t time_mode = 0;
state.assimp_scene->mMetaData->Get("TimeMode", time_mode);
- ticks_per_second = _get_fbx_fps(time_mode, state.assimp_scene);
+ ticks_per_second = AssimpUtils::get_fbx_fps(time_mode, state.assimp_scene);
}
//?
@@ -639,36 +455,31 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
for (size_t i = 0; i < anim->mNumChannels; i++) {
const aiNodeAnim *track = anim->mChannels[i];
- String node_name = _assimp_get_string(track->mNodeName);
- /*
- if (node_name.find(ASSIMP_FBX_KEY) != -1) {
- String p_track_type = node_name.get_slice(ASSIMP_FBX_KEY, 1);
- if (p_track_type == "_Translation" || p_track_type == "_Rotation" || p_track_type == "_Scaling") {
- continue;
- }
- }
-*/
+ String node_name = AssimpUtils::get_assimp_string(track->mNodeName);
+
if (track->mNumRotationKeys == 0 && track->mNumPositionKeys == 0 && track->mNumScalingKeys == 0) {
continue; //do not bother
}
- bool is_bone = state.bone_owners.has(node_name);
- NodePath node_path;
- Skeleton *skeleton = NULL;
+ for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ Skeleton *skeleton = key_value_pair->key();
- if (is_bone) {
- skeleton = state.skeletons[state.bone_owners[node_name]];
- String path = state.root->get_path_to(skeleton);
- path += ":" + node_name;
- node_path = path;
- } else {
+ bool is_bone = skeleton->find_bone(node_name) != -1;
+ //print_verbose("Bone " + node_name + " is bone? " + (is_bone ? "Yes" : "No"));
+ NodePath node_path;
- ERR_CONTINUE(!state.node_map.has(node_name));
- Node *node = state.node_map[node_name];
- node_path = state.root->get_path_to(node);
- }
+ if (is_bone) {
+ String path = state.root->get_path_to(skeleton);
+ path += ":" + node_name;
+ node_path = path;
+ } else {
+ ERR_CONTINUE(!state.node_map.has(node_name));
+ Node *node = state.node_map[node_name];
+ node_path = state.root->get_path_to(node);
+ }
- _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, node_path, node_name);
+ _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, node_path, node_name);
+ }
}
//blend shape tracks
@@ -677,7 +488,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
const aiMeshMorphAnim *anim_mesh = anim->mMorphMeshChannels[i];
- const String prop_name = _assimp_get_string(anim_mesh->mName);
+ const String prop_name = AssimpUtils::get_assimp_string(anim_mesh->mName);
const String mesh_name = prop_name.split("*")[0];
ERR_CONTINUE(prop_name.split("*").size() != 2);
@@ -717,514 +528,41 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
}
}
-float EditorSceneImporterAssimp::_get_fbx_fps(int32_t time_mode, const aiScene *p_scene) {
- switch (time_mode) {
- case AssetImportFbx::TIME_MODE_DEFAULT: return 24; //hack
- case AssetImportFbx::TIME_MODE_120: return 120;
- case AssetImportFbx::TIME_MODE_100: return 100;
- case AssetImportFbx::TIME_MODE_60: return 60;
- case AssetImportFbx::TIME_MODE_50: return 50;
- case AssetImportFbx::TIME_MODE_48: return 48;
- case AssetImportFbx::TIME_MODE_30: return 30;
- case AssetImportFbx::TIME_MODE_30_DROP: return 30;
- case AssetImportFbx::TIME_MODE_NTSC_DROP_FRAME: return 29.9700262f;
- case AssetImportFbx::TIME_MODE_NTSC_FULL_FRAME: return 29.9700262f;
- case AssetImportFbx::TIME_MODE_PAL: return 25;
- case AssetImportFbx::TIME_MODE_CINEMA: return 24;
- case AssetImportFbx::TIME_MODE_1000: return 1000;
- case AssetImportFbx::TIME_MODE_CINEMA_ND: return 23.976f;
- case AssetImportFbx::TIME_MODE_CUSTOM:
- int32_t frame_rate;
- p_scene->mMetaData->Get("FrameRate", frame_rate);
- return frame_rate;
- }
- return 0;
-}
-
-Transform EditorSceneImporterAssimp::_get_global_assimp_node_transform(const aiNode *p_current_node) {
- aiNode const *current_node = p_current_node;
- Transform xform;
- while (current_node != NULL) {
- xform = _assimp_matrix_transform(current_node->mTransformation) * xform;
- current_node = current_node->mParent;
- }
- return xform;
-}
-
-Ref<Texture> EditorSceneImporterAssimp::_load_texture(ImportState &state, String p_path) {
- Vector<String> split_path = p_path.get_basename().split("*");
- if (split_path.size() == 2) {
- size_t texture_idx = split_path[1].to_int();
- ERR_FAIL_COND_V(texture_idx >= state.assimp_scene->mNumTextures, Ref<Texture>());
- aiTexture *tex = state.assimp_scene->mTextures[texture_idx];
- String filename = _assimp_raw_string_to_string(tex->mFilename);
- filename = filename.get_file();
- print_verbose("Open Asset Import: Loading embedded texture " + filename);
- if (tex->mHeight == 0) {
- if (tex->CheckFormat("png")) {
- Ref<Image> img = Image::_png_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
- ERR_FAIL_COND_V(img.is_null(), Ref<Texture>());
-
- Ref<ImageTexture> t;
- t.instance();
- t->create_from_image(img);
- t->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
- return t;
- } else if (tex->CheckFormat("jpg")) {
- Ref<Image> img = Image::_jpg_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
- ERR_FAIL_COND_V(img.is_null(), Ref<Texture>());
- Ref<ImageTexture> t;
- t.instance();
- t->create_from_image(img);
- t->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
- return t;
- } else if (tex->CheckFormat("dds")) {
- ERR_EXPLAIN("Open Asset Import: Embedded dds not implemented");
- ERR_FAIL_COND_V(true, Ref<Texture>());
- //Ref<Image> img = Image::_dds_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
- //ERR_FAIL_COND_V(img.is_null(), Ref<Texture>());
- //Ref<ImageTexture> t;
- //t.instance();
- //t->create_from_image(img);
- //t->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
- //return t;
- }
- } else {
- Ref<Image> img;
- img.instance();
- PoolByteArray arr;
- uint32_t size = tex->mWidth * tex->mHeight;
- arr.resize(size);
- memcpy(arr.write().ptr(), tex->pcData, size);
- ERR_FAIL_COND_V(arr.size() % 4 != 0, Ref<Texture>());
- //ARGB8888 to RGBA8888
- for (int32_t i = 0; i < arr.size() / 4; i++) {
- arr.write().ptr()[(4 * i) + 3] = arr[(4 * i) + 0];
- arr.write().ptr()[(4 * i) + 0] = arr[(4 * i) + 1];
- arr.write().ptr()[(4 * i) + 1] = arr[(4 * i) + 2];
- arr.write().ptr()[(4 * i) + 2] = arr[(4 * i) + 3];
- }
- img->create(tex->mWidth, tex->mHeight, true, Image::FORMAT_RGBA8, arr);
- ERR_FAIL_COND_V(img.is_null(), Ref<Texture>());
-
- Ref<ImageTexture> t;
- t.instance();
- t->create_from_image(img);
- t->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
- return t;
- }
- return Ref<Texture>();
- }
- Ref<Texture> p_texture = ResourceLoader::load(p_path, "Texture");
- return p_texture;
-}
-
-Ref<Material> EditorSceneImporterAssimp::_generate_material_from_index(ImportState &state, int p_index, bool p_double_sided) {
-
- ERR_FAIL_INDEX_V(p_index, (int)state.assimp_scene->mNumMaterials, Ref<Material>());
-
- aiMaterial *ai_material = state.assimp_scene->mMaterials[p_index];
- Ref<SpatialMaterial> mat;
- mat.instance();
-
- int32_t mat_two_sided = 0;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) {
- if (mat_two_sided > 0) {
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- }
- }
-
- //const String mesh_name = _assimp_get_string(ai_mesh->mName);
- aiString mat_name;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_NAME, mat_name)) {
- mat->set_name(_assimp_get_string(mat_name));
- }
+//
+// Mesh Generation from indices ? why do we need so much mesh code
+// [debt needs looked into]
+Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
+ ImportState &state,
+ const Vector<int> &p_surface_indices,
+ const aiNode *assimp_node,
+ Skeleton *p_skeleton) {
- aiTextureType tex_normal = aiTextureType_NORMALS;
- {
- aiString ai_filename = aiString();
- String filename = "";
- aiTextureMapMode map_mode[2];
-
- if (AI_SUCCESS == ai_material->GetTexture(tex_normal, 0, &ai_filename, NULL, NULL, NULL, NULL, map_mode)) {
- filename = _assimp_raw_string_to_string(ai_filename);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
-
- 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);
- }
- }
- }
- }
-
- {
- aiString ai_filename = aiString();
- String filename = "";
-
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_NORMAL_TEXTURE, ai_filename)) {
- filename = _assimp_raw_string_to_string(ai_filename);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
- }
- }
- }
- }
-
- aiTextureType tex_emissive = aiTextureType_EMISSIVE;
-
- if (ai_material->GetTextureCount(tex_emissive) > 0) {
-
- aiString ai_filename = aiString();
- String filename = "";
- aiTextureMapMode map_mode[2];
-
- if (AI_SUCCESS == ai_material->GetTexture(tex_emissive, 0, &ai_filename, NULL, NULL, NULL, NULL, map_mode)) {
- filename = _assimp_raw_string_to_string(ai_filename);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- _set_texture_mapping_mode(map_mode, texture);
- mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
- mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, texture);
- }
- }
- }
- }
-
- aiTextureType tex_albedo = aiTextureType_DIFFUSE;
- if (ai_material->GetTextureCount(tex_albedo) > 0) {
-
- aiString ai_filename = aiString();
- String filename = "";
- aiTextureMapMode map_mode[2];
- if (AI_SUCCESS == ai_material->GetTexture(tex_albedo, 0, &ai_filename, NULL, NULL, NULL, NULL, map_mode)) {
- filename = _assimp_raw_string_to_string(ai_filename);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- if (texture->get_data()->detect_alpha() != Image::ALPHA_NONE) {
- _set_texture_mapping_mode(map_mode, texture);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
- }
- }
- }
- } else {
- aiColor4D clr_diffuse;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_COLOR_DIFFUSE, clr_diffuse)) {
- if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a));
- }
- }
-
- aiString tex_gltf_base_color_path = aiString();
- aiTextureMapMode map_mode[2];
- if (AI_SUCCESS == ai_material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE, &tex_gltf_base_color_path, NULL, NULL, NULL, NULL, map_mode)) {
- String filename = _assimp_raw_string_to_string(tex_gltf_base_color_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- if (texture->get_data()->detect_alpha() == Image::ALPHA_BLEND) {
- _set_texture_mapping_mode(map_mode, texture);
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
- }
- }
- } else {
- aiColor4D pbr_base_color;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR, pbr_base_color)) {
- if (Math::is_equal_approx(pbr_base_color.a, 1.0f) == false) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_albedo(Color(pbr_base_color.r, pbr_base_color.g, pbr_base_color.b, pbr_base_color.a));
- }
- }
- {
- aiString tex_fbx_pbs_base_color_path = aiString();
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_BASE_COLOR_TEXTURE, tex_fbx_pbs_base_color_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_base_color_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- if (texture->get_data()->detect_alpha() == Image::ALPHA_BLEND) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
- }
- }
- } else {
- aiColor4D pbr_base_color;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_BASE_COLOR_FACTOR, pbr_base_color)) {
- mat->set_albedo(Color(pbr_base_color.r, pbr_base_color.g, pbr_base_color.b, pbr_base_color.a));
- }
- }
-
- aiUVTransform pbr_base_color_uv_xform;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_BASE_COLOR_UV_XFORM, pbr_base_color_uv_xform)) {
- mat->set_uv1_offset(Vector3(pbr_base_color_uv_xform.mTranslation.x, pbr_base_color_uv_xform.mTranslation.y, 0.0f));
- mat->set_uv1_scale(Vector3(pbr_base_color_uv_xform.mScaling.x, pbr_base_color_uv_xform.mScaling.y, 1.0f));
- }
- }
-
- {
- aiString tex_fbx_pbs_normal_path = aiString();
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_NORMAL_TEXTURE, tex_fbx_pbs_normal_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_normal_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
- }
- }
- }
- }
-
- if (p_double_sided) {
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- }
-
- {
- aiString tex_fbx_stingray_normal_path = aiString();
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_TEXTURE, tex_fbx_stingray_normal_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_stingray_normal_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
- }
- }
- }
- }
-
- {
- aiString tex_fbx_pbs_base_color_path = aiString();
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_TEXTURE, tex_fbx_pbs_base_color_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_base_color_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- if (texture->get_data()->detect_alpha() == Image::ALPHA_BLEND) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
- }
- }
- } else {
- aiColor4D pbr_base_color;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_BASE_COLOR_FACTOR, pbr_base_color)) {
- mat->set_albedo(Color(pbr_base_color.r, pbr_base_color.g, pbr_base_color.b, pbr_base_color.a));
- }
- }
-
- aiUVTransform pbr_base_color_uv_xform;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_UV_XFORM, pbr_base_color_uv_xform)) {
- mat->set_uv1_offset(Vector3(pbr_base_color_uv_xform.mTranslation.x, pbr_base_color_uv_xform.mTranslation.y, 0.0f));
- mat->set_uv1_scale(Vector3(pbr_base_color_uv_xform.mScaling.x, pbr_base_color_uv_xform.mScaling.y, 1.0f));
- }
- }
-
- {
- aiString tex_fbx_pbs_emissive_path = aiString();
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_TEXTURE, tex_fbx_pbs_emissive_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_emissive_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- _find_texture_path(state.path, path, found);
- if (texture != NULL) {
- if (texture->get_data()->detect_alpha() == Image::ALPHA_BLEND) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- }
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
- }
- }
- } else {
- aiColor4D pbr_emmissive_color;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_FACTOR, pbr_emmissive_color)) {
- mat->set_emission(Color(pbr_emmissive_color.r, pbr_emmissive_color.g, pbr_emmissive_color.b, pbr_emmissive_color.a));
- }
- }
-
- real_t pbr_emission_intensity;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_INTENSITY_FACTOR, pbr_emission_intensity)) {
- mat->set_emission_energy(pbr_emission_intensity);
- }
- }
-
- aiString tex_gltf_pbr_metallicroughness_path;
- if (AI_SUCCESS == ai_material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &tex_gltf_pbr_metallicroughness_path)) {
- String filename = _assimp_raw_string_to_string(tex_gltf_pbr_metallicroughness_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
- mat->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_BLUE);
- mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, texture);
- mat->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GREEN);
- }
- }
- } else {
- float pbr_roughness = 0.0f;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, pbr_roughness)) {
- mat->set_roughness(pbr_roughness);
- }
- float pbr_metallic = 0.0f;
-
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, pbr_metallic)) {
- mat->set_metallic(pbr_metallic);
- }
- }
- {
- aiString tex_fbx_pbs_metallic_path;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_TEXTURE, tex_fbx_pbs_metallic_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_metallic_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
- mat->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GRAYSCALE);
- }
- }
- } else {
- float pbr_metallic = 0.0f;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_FACTOR, pbr_metallic)) {
- mat->set_metallic(pbr_metallic);
- }
- }
-
- aiString tex_fbx_pbs_rough_path;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_TEXTURE, tex_fbx_pbs_rough_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_rough_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, texture);
- mat->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GRAYSCALE);
- }
- }
- } else {
- float pbr_roughness = 0.04f;
+ Ref<ArrayMesh> mesh;
+ mesh.instance();
+ bool has_uvs = false;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_FACTOR, pbr_roughness)) {
- mat->set_roughness(pbr_roughness);
- }
- }
- }
+ Map<String, uint32_t> morph_mesh_string_lookup;
- {
- aiString tex_fbx_pbs_metallic_path;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_METALNESS_TEXTURE, tex_fbx_pbs_metallic_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_metallic_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
- mat->set_metallic_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GRAYSCALE);
- }
- }
- } else {
- float pbr_metallic = 0.0f;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_METALNESS_FACTOR, pbr_metallic)) {
- mat->set_metallic(pbr_metallic);
- }
- }
+ for (int i = 0; i < p_surface_indices.size(); i++) {
+ const unsigned int mesh_idx = p_surface_indices[0];
+ const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx];
+ for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) {
- aiString tex_fbx_pbs_rough_path;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_TEXTURE, tex_fbx_pbs_rough_path)) {
- String filename = _assimp_raw_string_to_string(tex_fbx_pbs_rough_path);
- String path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
- bool found = false;
- _find_texture_path(state.path, path, found);
- if (found) {
- Ref<Texture> texture = _load_texture(state, path);
- if (texture != NULL) {
- mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, texture);
- mat->set_roughness_texture_channel(SpatialMaterial::TEXTURE_CHANNEL_GRAYSCALE);
+ String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName);
+ if (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) {
+ morph_mesh_string_lookup.insert(ai_anim_mesh_name, j);
+ mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
+ if (ai_anim_mesh_name.empty()) {
+ ai_anim_mesh_name = String("morph_") + itos(j);
}
- }
- } else {
- float pbr_roughness = 0.04f;
-
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_FACTOR, pbr_roughness)) {
- mat->set_roughness(pbr_roughness);
+ mesh->add_blend_shape(ai_anim_mesh_name);
}
}
}
- return mat;
-}
-
-Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, Skeleton *p_skeleton, bool p_double_sided_material) {
-
- Ref<ArrayMesh> mesh;
- mesh.instance();
- bool has_uvs = false;
-
+ //
+ // Process Vertex Weights
+ //
for (int i = 0; i < p_surface_indices.size(); i++) {
const unsigned int mesh_idx = p_surface_indices[i];
const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx];
@@ -1234,7 +572,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
if (p_skeleton) {
for (size_t b = 0; b < ai_mesh->mNumBones; b++) {
aiBone *bone = ai_mesh->mBones[b];
- String bone_name = _assimp_get_string(bone->mName);
+ String bone_name = AssimpUtils::get_assimp_string(bone->mName);
int bone_index = p_skeleton->find_bone(bone_name);
ERR_CONTINUE(bone_index == -1); //bone refers to an unexisting index, wtf.
@@ -1247,7 +585,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
uint32_t vertex_index = ai_weights.mVertexId;
bi.bone = bone_index;
bi.weight = ai_weights.mWeight;
- ;
if (!vertex_weights.has(vertex_index)) {
vertex_weights[vertex_index] = Vector<BoneInfo>();
@@ -1258,23 +595,34 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
}
}
+ //
+ // Create mesh from data from assimp
+ //
+
Ref<SurfaceTool> st;
st.instance();
st->begin(Mesh::PRIMITIVE_TRIANGLES);
for (size_t j = 0; j < ai_mesh->mNumVertices; j++) {
+
+ // Get the texture coordinates if they exist
if (ai_mesh->HasTextureCoords(0)) {
has_uvs = true;
st->add_uv(Vector2(ai_mesh->mTextureCoords[0][j].x, 1.0f - ai_mesh->mTextureCoords[0][j].y));
}
+
if (ai_mesh->HasTextureCoords(1)) {
has_uvs = true;
st->add_uv2(Vector2(ai_mesh->mTextureCoords[1][j].x, 1.0f - ai_mesh->mTextureCoords[1][j].y));
}
+
+ // Assign vertex colors
if (ai_mesh->HasVertexColors(0)) {
Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b, ai_mesh->mColors[0]->a);
st->add_color(color);
}
+
+ // Work out normal calculations? - this needs work it doesn't work properly on huestos
if (ai_mesh->mNormals != NULL) {
const aiVector3D normals = ai_mesh->mNormals[j];
const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
@@ -1289,6 +637,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
}
}
+ // We have vertex weights right?
if (vertex_weights.has(j)) {
Vector<BoneInfo> bone_info = vertex_weights[j];
@@ -1296,6 +645,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
bones.resize(bone_info.size());
Vector<float> weights;
weights.resize(bone_info.size());
+
+ // todo? do we really need to loop over all bones? - assimp may have helper to find all influences on this vertex.
for (int k = 0; k < bone_info.size(); k++) {
bones.write[k] = bone_info[k].bone;
weights.write[k] = bone_info[k].weight;
@@ -1305,47 +656,239 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
st->add_weights(weights);
}
+ // Assign vertex
const aiVector3D pos = ai_mesh->mVertices[j];
+
+ // note we must include node offset transform as this is relative to world space not local space.
Vector3 godot_pos = Vector3(pos.x, pos.y, pos.z);
st->add_vertex(godot_pos);
}
+ // fire replacement for face handling
for (size_t j = 0; j < ai_mesh->mNumFaces; j++) {
const aiFace face = ai_mesh->mFaces[j];
- ERR_CONTINUE(face.mNumIndices != 3);
- Vector<size_t> order;
- order.push_back(2);
- order.push_back(1);
- order.push_back(0);
- for (int32_t k = 0; k < order.size(); k++) {
- st->add_index(face.mIndices[order[k]]);
+ for (unsigned int k = 0; k < face.mNumIndices; k++) {
+ st->add_index(face.mIndices[k]);
}
}
+
if (ai_mesh->HasTangentsAndBitangents() == false && has_uvs) {
st->generate_tangents();
}
- Ref<Material> material;
+ aiMaterial *ai_material = state.assimp_scene->mMaterials[ai_mesh->mMaterialIndex];
+ Ref<SpatialMaterial> mat;
+ mat.instance();
+
+ int32_t mat_two_sided = 0;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) {
+ if (mat_two_sided > 0) {
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ }
+ }
+
+ const String mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mName);
+ aiString mat_name;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_NAME, mat_name)) {
+ mat->set_name(AssimpUtils::get_assimp_string(mat_name));
+ }
+
+ // Culling handling for meshes
+
+ // cull all back faces
+ mat->set_cull_mode(SpatialMaterial::CULL_BACK);
+
+ // Now process materials
+ aiTextureType base_color = aiTextureType_BASE_COLOR;
+ {
+ String filename, path;
+ AssimpImageData image_data;
+
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, base_color, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+
+ // anything transparent must be culled
+ if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ }
+
+ mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_diffuse = aiTextureType_DIFFUSE;
+ {
+ String filename, path;
+ AssimpImageData image_data;
+
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_diffuse, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+
+ // anything transparent must be culled
+ if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ }
+
+ mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
+ }
+
+ aiColor4D clr_diffuse;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_COLOR_DIFFUSE, clr_diffuse)) {
+ if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) {
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ }
+ mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a));
+ }
+ }
+
+ aiTextureType tex_normal = aiTextureType_NORMALS;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ } else {
+ aiString texture_path;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_NORMAL_TEXTURE, AI_PROPERTIES, texture_path)) {
+ if (AssimpUtils::CreateAssimpTexture(state, texture_path, filename, path, image_data)) {
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ }
+ }
+ }
+ }
+
+ aiTextureType tex_normal_camera = aiTextureType_NORMAL_CAMERA;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_emission_color = aiTextureType_EMISSION_COLOR;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_metalness = aiTextureType_METALNESS;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_roughness = aiTextureType_DIFFUSE_ROUGHNESS;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_emissive = aiTextureType_EMISSIVE;
+ {
+ String filename = "";
+ String path = "";
+ Ref<Image> texture;
+ AssimpImageData image_data;
+
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emissive, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture);
+ } else {
+ // Process emission textures
+ aiString texture_emissive_path;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) {
+ if (AssimpUtils::CreateAssimpTexture(state, texture_emissive_path, filename, path, image_data)) {
+ mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture);
+ }
+ } else {
+ float pbr_emission = 0.0f;
+ if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSIVE_FACTOR, AI_NULL, pbr_emission)) {
+ mat->set_emission(Color(pbr_emission, pbr_emission, pbr_emission, 1.0f));
+ }
+ }
+ }
+ }
+
+ aiTextureType tex_specular = aiTextureType_SPECULAR;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_specular, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
+ }
+ }
- if (!state.material_cache.has(ai_mesh->mMaterialIndex)) {
- material = _generate_material_from_index(state, ai_mesh->mMaterialIndex, p_double_sided_material);
+ aiTextureType tex_ao_map = aiTextureType_AMBIENT_OCCLUSION;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, image_data.texture);
+ }
}
Array array_mesh = st->commit_to_arrays();
Array morphs;
morphs.resize(ai_mesh->mNumAnimMeshes);
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
- Map<uint32_t, String> morph_mesh_idx_names;
+
for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) {
- if (i == 0) {
- //only do this the first time
- String ai_anim_mesh_name = _assimp_get_string(ai_mesh->mAnimMeshes[j]->mName);
- mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
- if (ai_anim_mesh_name.empty()) {
- ai_anim_mesh_name = String("morph_") + itos(j);
- }
- mesh->add_blend_shape(ai_anim_mesh_name);
+ String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName);
+
+ if (ai_anim_mesh_name.empty()) {
+ ai_anim_mesh_name = String("morph_") + itos(j);
}
Array array_copy;
@@ -1366,12 +909,11 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
vertices.write()[l] = position;
}
PoolVector3Array new_vertices = array_copy[VisualServer::ARRAY_VERTEX].duplicate(true);
-
- for (int32_t l = 0; l < vertices.size(); l++) {
+ ERR_CONTINUE(vertices.size() != new_vertices.size());
+ for (int32_t l = 0; l < new_vertices.size(); l++) {
PoolVector3Array::Write w = new_vertices.write();
w[l] = vertices[l];
}
- ERR_CONTINUE(vertices.size() != new_vertices.size());
array_copy[VisualServer::ARRAY_VERTEX] = new_vertices;
}
@@ -1385,7 +927,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
colors.write()[l] = color;
}
PoolColorArray new_colors = array_copy[VisualServer::ARRAY_COLOR].duplicate(true);
-
+ ERR_CONTINUE(colors.size() != new_colors.size());
for (int32_t l = 0; l < colors.size(); l++) {
PoolColorArray::Write w = new_colors.write();
w[l] = colors[l];
@@ -1397,12 +939,12 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
PoolVector3Array normals;
normals.resize(num_vertices);
for (size_t l = 0; l < num_vertices; l++) {
- const aiVector3D ai_normal = ai_mesh->mAnimMeshes[i]->mNormals[l];
+ const aiVector3D ai_normal = ai_mesh->mAnimMeshes[j]->mNormals[l];
Vector3 normal = Vector3(ai_normal.x, ai_normal.y, ai_normal.z);
normals.write()[l] = normal;
}
PoolVector3Array new_normals = array_copy[VisualServer::ARRAY_NORMAL].duplicate(true);
-
+ ERR_CONTINUE(normals.size() != new_normals.size());
for (int l = 0; l < normals.size(); l++) {
PoolVector3Array::Write w = new_normals.write();
w[l] = normals[l];
@@ -1415,7 +957,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
tangents.resize(num_vertices);
PoolColorArray::Write w = tangents.write();
for (size_t l = 0; l < num_vertices; l++) {
- _calc_tangent_from_mesh(ai_mesh, j, l, l, w);
+ AssimpUtils::calc_tangent_from_mesh(ai_mesh, j, l, l, w);
}
PoolRealArray new_tangents = array_copy[VisualServer::ARRAY_TANGENT].duplicate(true);
ERR_CONTINUE(new_tangents.size() != tangents.size() * 4);
@@ -1425,340 +967,387 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportS
new_tangents.write()[l + 2] = tangents[l].b;
new_tangents.write()[l + 3] = tangents[l].a;
}
-
array_copy[VisualServer::ARRAY_TANGENT] = new_tangents;
}
morphs[j] = array_copy;
}
-
mesh->add_surface_from_arrays(primitive, array_mesh, morphs);
- mesh->surface_set_material(i, material);
- mesh->surface_set_name(i, _assimp_get_string(ai_mesh->mName));
+ mesh->surface_set_material(i, mat);
+ mesh->surface_set_name(i, AssimpUtils::get_assimp_string(ai_mesh->mName));
}
return mesh;
}
-void EditorSceneImporterAssimp::_generate_node(ImportState &state, const aiNode *p_assimp_node, Node *p_parent) {
-
- Spatial *new_node = NULL;
- String node_name = _assimp_get_string(p_assimp_node->mName);
- Transform node_transform = _assimp_matrix_transform(p_assimp_node->mTransformation);
+/* to be moved into assimp */
+aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
+ for (unsigned int mesh_id = 0; mesh_id < scene->mNumMeshes; ++mesh_id) {
+ aiMesh *mesh = scene->mMeshes[mesh_id];
- if (p_assimp_node->mNumMeshes > 0) {
- /* MESH NODE */
- Ref<Mesh> mesh;
- Skeleton *skeleton = NULL;
- {
+ // iterate over all the bones on the mesh for this node only!
+ for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) {
- //see if we have mesh cache for this.
- Vector<int> surface_indices;
- for (uint32_t i = 0; i < p_assimp_node->mNumMeshes; i++) {
- int mesh_index = p_assimp_node->mMeshes[i];
- surface_indices.push_back(mesh_index);
-
- //take the chance and attempt to find the skeleton from the bones
- if (!skeleton) {
- aiMesh *ai_mesh = state.assimp_scene->mMeshes[p_assimp_node->mMeshes[i]];
- for (uint32_t j = 0; j < ai_mesh->mNumBones; j++) {
- aiBone *bone = ai_mesh->mBones[j];
- String bone_name = _assimp_get_string(bone->mName);
- if (state.bone_owners.has(bone_name)) {
- skeleton = state.skeletons[state.bone_owners[bone_name]];
- break;
- }
- }
- }
- }
- surface_indices.sort();
- String mesh_key;
- for (int i = 0; i < surface_indices.size(); i++) {
- if (i > 0) {
- mesh_key += ":";
- }
- mesh_key += itos(surface_indices[i]);
+ aiBone *bone = mesh->mBones[boneIndex];
+ if (bone->mName == bone_name) {
+ printf("matched bone by name: %s\n", bone->mName.C_Str());
+ return bone;
}
+ }
+ }
- if (!state.mesh_cache.has(mesh_key)) {
- //adding cache
- aiString cull_mode; //cull is on mesh, which is kind of stupid tbh
- bool double_sided_material = false;
- if (p_assimp_node->mMetaData) {
- p_assimp_node->mMetaData->Get("Culling", cull_mode);
- }
- if (cull_mode.length != 0 && cull_mode == aiString("CullingOff")) {
- double_sided_material = true;
- }
+ return NULL;
+}
- mesh = _generate_mesh_from_surface_indices(state, surface_indices, skeleton, double_sided_material);
- state.mesh_cache[mesh_key] = mesh;
+/**
+ * Create a new mesh for the node supplied
+ */
+void EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform) {
+ /* MESH NODE */
+ Ref<Mesh> mesh;
+ Skeleton *skeleton = NULL;
+ // see if we have mesh cache for this.
+ Vector<int> surface_indices;
+ for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) {
+ int mesh_index = assimp_node->mMeshes[i];
+ aiMesh *ai_mesh = state.assimp_scene->mMeshes[assimp_node->mMeshes[i]];
+
+ // Map<aiBone*, Skeleton*> // this is what we need
+ if (ai_mesh->mNumBones > 0) {
+ // we only need the first bone to retrieve the skeleton
+ const aiBone *first = ai_mesh->mBones[0];
+
+ ERR_FAIL_COND(first == NULL);
+
+ Map<const aiBone *, Skeleton *>::Element *match = state.bone_to_skeleton_lookup.find(first);
+ if (match != NULL) {
+ skeleton = match->value();
+
+ if (skeleton == NULL) {
+ print_error("failed to find bone skeleton for bone: " + AssimpUtils::get_assimp_string(first->mName));
+ } else {
+ print_verbose("successfully found skeleton for first bone on mesh, can properly handle animations now!");
+ }
+ // I really need the skeleton and bone to be known as this is something flaky in model exporters.
+ ERR_FAIL_COND(skeleton == NULL); // should not happen if bone was successfully created in previous step.
}
-
- mesh = state.mesh_cache[mesh_key];
}
+ surface_indices.push_back(mesh_index);
+ }
- MeshInstance *mesh_node = memnew(MeshInstance);
- if (skeleton) {
- state.mesh_skeletons[mesh_node] = skeleton;
+ surface_indices.sort();
+ String mesh_key;
+ for (int i = 0; i < surface_indices.size(); i++) {
+ if (i > 0) {
+ mesh_key += ":";
}
- mesh_node->set_mesh(mesh);
- new_node = mesh_node;
-
- } else if (state.light_cache.has(node_name)) {
-
- Light *light = NULL;
- aiLight *ai_light = state.assimp_scene->mLights[state.light_cache[node_name]];
- ERR_FAIL_COND(!ai_light);
+ mesh_key += itos(surface_indices[i]);
+ }
- if (ai_light->mType == aiLightSource_DIRECTIONAL) {
- light = memnew(DirectionalLight);
- Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
- dir.normalize();
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
- up.normalize();
+ if (!state.mesh_cache.has(mesh_key)) {
+ mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skeleton);
+ state.mesh_cache[mesh_key] = mesh;
+ }
- Transform light_transform;
- light_transform.set_look_at(pos, pos + dir, up);
+ //Transform transform = recursive_state.node_transform;
- node_transform *= light_transform;
+ // we must unfortunately overwrite mesh and skeleton transform with armature data
+ if (skeleton != NULL) {
+ print_verbose("Applying mesh and skeleton to armature");
+ // required for blender, maya etc
+ Map<Skeleton *, const Spatial *>::Element *match = state.armature_skeletons.find(skeleton);
+ node_transform = match->value()->get_transform();
+ }
- } else if (ai_light->mType == aiLightSource_POINT) {
- light = memnew(OmniLight);
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Transform xform;
- xform.origin = pos;
+ MeshInstance *mesh_node = memnew(MeshInstance);
+ mesh = state.mesh_cache[mesh_key];
+ mesh_node->set_mesh(mesh);
- node_transform *= xform;
+ attach_new_node(state,
+ mesh_node,
+ assimp_node,
+ parent_node,
+ node_name,
+ node_transform);
- light->set_transform(xform);
+ // set this once and for all
+ if (skeleton != NULL) {
+ // root must be informed of its new child
+ parent_node->add_child(skeleton);
- //light->set_param(Light::PARAM_ATTENUATION, 1);
- } else if (ai_light->mType == aiLightSource_SPOT) {
- light = memnew(SpotLight);
+ // owner must be set after adding to tree
+ skeleton->set_owner(state.root);
- Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
- dir.normalize();
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
- up.normalize();
+ skeleton->set_transform(node_transform);
- Transform light_transform;
- light_transform.set_look_at(pos, pos + dir, up);
- node_transform *= light_transform;
+ // must be done after added to tree
+ mesh_node->set_skeleton_path(mesh_node->get_path_to(skeleton));
+ }
+}
- //light->set_param(Light::PARAM_ATTENUATION, 0.0f);
- }
- ERR_FAIL_COND(light == NULL);
- light->set_color(Color(ai_light->mColorDiffuse.r, ai_light->mColorDiffuse.g, ai_light->mColorDiffuse.b));
- new_node = light;
- } else if (state.camera_cache.has(node_name)) {
+/** generate_mesh_phase_from_skeletal_mesh
+ * This must be executed after generate_nodes because the skeleton doesn't exist until that has completed the first pass
+ */
+void EditorSceneImporterAssimp::generate_mesh_phase_from_skeletal_mesh(ImportState &state) {
+ // prevent more than one skeleton existing per mesh
+ // * multiple root bones have this
+ // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node
+ for (Map<const aiNode *, const Node *>::Element *key_value_pair = state.assimp_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ const aiNode *assimp_node = key_value_pair->key();
+ Node *current_node = (Node *)key_value_pair->value();
+ Node *parent_node = current_node->get_parent();
- aiCamera *ai_camera = state.assimp_scene->mCameras[state.camera_cache[node_name]];
- ERR_FAIL_COND(!ai_camera);
+ ERR_CONTINUE(assimp_node == NULL);
+ ERR_CONTINUE(parent_node == NULL);
- Camera *camera = memnew(Camera);
+ String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
+ Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
- float near = ai_camera->mClipPlaneNear;
- if (Math::is_equal_approx(near, 0.0f)) {
- near = 0.1f;
+ if (assimp_node->mNumMeshes > 0) {
+ create_mesh(state, assimp_node, node_name, current_node, parent_node, node_transform);
}
- camera->set_perspective(Math::rad2deg(ai_camera->mHorizontalFOV) * 2.0f, near, ai_camera->mClipPlaneFar);
+ }
+}
- Vector3 pos = Vector3(ai_camera->mPosition.x, ai_camera->mPosition.y, ai_camera->mPosition.z);
- Vector3 look_at = Vector3(ai_camera->mLookAt.y, ai_camera->mLookAt.x, ai_camera->mLookAt.z).normalized();
- Vector3 up = Vector3(ai_camera->mUp.x, ai_camera->mUp.y, ai_camera->mUp.z);
+/**
+ * attach_new_node
+ * configures node, assigns parent node
+**/
+void EditorSceneImporterAssimp::attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform) {
+ ERR_FAIL_COND(new_node == NULL);
+ ERR_FAIL_COND(node == NULL);
+ ERR_FAIL_COND(parent_node == NULL);
+ ERR_FAIL_COND(state.root == NULL);
+
+ // assign properties to new godot note
+ new_node->set_name(Name);
+ new_node->set_transform(transform);
+
+ // add element as child to parent
+ parent_node->add_child(new_node);
+
+ // owner must be set after
+ new_node->set_owner(state.root);
+
+ // cache node mapping results by name and then by aiNode*
+ state.node_map[Name] = new_node;
+ state.assimp_node_map[node] = new_node;
+}
+/**
+ * Create a light for the scene
+ * Automatically caches lights for lookup later
+ */
+void EditorSceneImporterAssimp::create_light(ImportState &state, RecursiveState &recursive_state) {
+ Light *light = NULL;
+ aiLight *ai_light = state.assimp_scene->mLights[state.light_cache[recursive_state.node_name]];
+ ERR_FAIL_COND(!ai_light);
+
+ if (ai_light->mType == aiLightSource_DIRECTIONAL) {
+ light = memnew(DirectionalLight);
+ Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
+ dir.normalize();
+ Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
+ Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
+ up.normalize();
+
+ Transform light_transform;
+ light_transform.set_look_at(pos, pos + dir, up);
+
+ recursive_state.node_transform *= light_transform;
+
+ } else if (ai_light->mType == aiLightSource_POINT) {
+ light = memnew(OmniLight);
+ Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
Transform xform;
- xform.set_look_at(pos, look_at, up);
-
- new_node = camera;
- } else if (state.bone_owners.has(node_name)) {
-
- //have to actually put the skeleton somewhere, you know.
- Skeleton *skeleton = state.skeletons[state.bone_owners[node_name]];
- if (skeleton->get_parent()) {
- //a bone for a skeleton already added..
- //could go downwards here to add meshes children of skeleton bones
- //but let's not support it for now.
- return;
- }
- //restore rest poses to local, now that we know where the skeleton finally is
- Transform skeleton_transform;
- if (p_assimp_node->mParent) {
- skeleton_transform = _get_global_assimp_node_transform(p_assimp_node->mParent);
- }
- for (int i = 0; i < skeleton->get_bone_count(); i++) {
- Transform rest = skeleton_transform.affine_inverse() * skeleton->get_bone_rest(i);
- skeleton->set_bone_rest(i, rest.affine_inverse());
- }
+ xform.origin = pos;
- skeleton->localize_rests();
- node_name = "Skeleton"; //don't use the bone root name
- node_transform = Transform(); //don't transform
+ recursive_state.node_transform *= xform;
- new_node = skeleton;
- } else {
- //generic node
- new_node = memnew(Spatial);
- }
+ light->set_transform(xform);
- {
+ //light->set_param(Light::PARAM_ATTENUATION, 1);
+ } else if (ai_light->mType == aiLightSource_SPOT) {
+ light = memnew(SpotLight);
- new_node->set_name(node_name);
- new_node->set_transform(node_transform);
- p_parent->add_child(new_node);
- new_node->set_owner(state.root);
- }
+ Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
+ dir.normalize();
+ Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
+ Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
+ up.normalize();
- state.node_map[node_name] = new_node;
+ Transform light_transform;
+ light_transform.set_look_at(pos, pos + dir, up);
+ recursive_state.node_transform *= light_transform;
- for (size_t i = 0; i < p_assimp_node->mNumChildren; i++) {
- _generate_node(state, p_assimp_node->mChildren[i], new_node);
+ //light->set_param(Light::PARAM_ATTENUATION, 0.0f);
}
-}
+ ERR_FAIL_COND(light == NULL);
+
+ light->set_color(Color(ai_light->mColorDiffuse.r, ai_light->mColorDiffuse.g, ai_light->mColorDiffuse.b));
+ recursive_state.new_node = light;
-void EditorSceneImporterAssimp::_calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w) {
- const aiVector3D normals = ai_mesh->mAnimMeshes[i]->mNormals[tri_index];
- const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
- const aiVector3D tangent = ai_mesh->mAnimMeshes[i]->mTangents[tri_index];
- const Vector3 godot_tangent = Vector3(tangent.x, tangent.y, tangent.z);
- const aiVector3D bitangent = ai_mesh->mAnimMeshes[i]->mBitangents[tri_index];
- const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z);
- float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f;
- Color plane_tangent = Color(tangent.x, tangent.y, tangent.z, d);
- w[index] = plane_tangent;
+ attach_new_node(state,
+ recursive_state.new_node,
+ recursive_state.assimp_node,
+ recursive_state.parent_node,
+ recursive_state.node_name,
+ recursive_state.node_transform);
}
-void EditorSceneImporterAssimp::_set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture) {
- ERR_FAIL_COND(map_mode == NULL);
- aiTextureMapMode tex_mode = aiTextureMapMode::aiTextureMapMode_Wrap;
- //for (size_t i = 0; i < 3; i++) {
- tex_mode = map_mode[0];
- //}
- int32_t flags = Texture::FLAGS_DEFAULT;
- if (tex_mode == aiTextureMapMode_Wrap) {
- //Default
- } else if (tex_mode == aiTextureMapMode_Clamp) {
- flags = flags & ~Texture::FLAG_REPEAT;
- } else if (tex_mode == aiTextureMapMode_Mirror) {
- flags = flags | Texture::FLAG_MIRRORED_REPEAT;
+/**
+ * Create camera for the scene
+ */
+void EditorSceneImporterAssimp::create_camera(ImportState &state, RecursiveState &recursive_state) {
+ aiCamera *ai_camera = state.assimp_scene->mCameras[state.camera_cache[recursive_state.node_name]];
+ ERR_FAIL_COND(!ai_camera);
+
+ Camera *camera = memnew(Camera);
+
+ float near = ai_camera->mClipPlaneNear;
+ if (Math::is_equal_approx(near, 0.0f)) {
+ near = 0.1f;
}
- texture->set_flags(flags);
-}
+ camera->set_perspective(Math::rad2deg(ai_camera->mHorizontalFOV) * 2.0f, near, ai_camera->mClipPlaneFar);
-void EditorSceneImporterAssimp::_find_texture_path(const String &r_p_path, String &r_path, bool &r_found) {
+ Vector3 pos = Vector3(ai_camera->mPosition.x, ai_camera->mPosition.y, ai_camera->mPosition.z);
+ Vector3 look_at = Vector3(ai_camera->mLookAt.y, ai_camera->mLookAt.x, ai_camera->mLookAt.z).normalized();
+ Vector3 up = Vector3(ai_camera->mUp.x, ai_camera->mUp.y, ai_camera->mUp.z);
- _Directory dir;
+ Transform xform;
+ xform.set_look_at(pos, look_at, up);
- List<String> exts;
- ImageLoader::get_recognized_extensions(&exts);
+ recursive_state.new_node = camera;
- Vector<String> split_path = r_path.get_basename().split("*");
- if (split_path.size() == 2) {
- r_found = true;
- return;
- }
+ attach_new_node(state,
+ recursive_state.new_node,
+ recursive_state.assimp_node,
+ recursive_state.parent_node,
+ recursive_state.node_name,
+ recursive_state.node_transform);
+}
- if (dir.file_exists(r_p_path.get_base_dir() + r_path.get_file())) {
- r_path = r_p_path.get_base_dir() + r_path.get_file();
- r_found = true;
- return;
- }
+/**
+ * Create Bone
+ * Create a bone in the scene
+ */
+void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState &recursive_state) {
+ // for each armature node we must make a new skeleton but ensure it
+ // has a bone in the child to ensure we don't make too many
+ // the reason you must do this is because a skeleton exists per mesh?
+ // and duplicate bone names are very bad for determining what is going on.
+ aiBone *parent_bone_assimp = get_bone_by_name(state.assimp_scene, recursive_state.assimp_node->mParent->mName);
- for (int32_t i = 0; i < exts.size(); i++) {
- if (r_found) {
- return;
- }
- if (r_found == false) {
- _find_texture_path(r_p_path, dir, r_path, r_found, "." + exts[i]);
+ // set to true when you want to use skeleton reference from cache.
+ bool do_not_create_armature = false;
+
+ // prevent more than one skeleton existing per mesh
+ // * multiple root bones have this
+ // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node
+ for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ if (key_value_pair->value() == recursive_state.parent_node) {
+ // apply the skeleton for this mesh
+ recursive_state.skeleton = key_value_pair->key();
+
+ // force this off
+ do_not_create_armature = true;
}
}
-}
-void EditorSceneImporterAssimp::_find_texture_path(const String &p_path, _Directory &dir, String &path, bool &found, String extension) {
- String name = path.get_basename() + extension;
- if (dir.file_exists(name)) {
- found = true;
- path = name;
- return;
- }
- String name_ignore_sub_directory = p_path.get_base_dir().plus_file(path.get_file().get_basename()) + extension;
- if (dir.file_exists(name_ignore_sub_directory)) {
- found = true;
- path = name_ignore_sub_directory;
- return;
- }
+ // check if parent was a bone
+ // if parent was not a bone this is the first bone.
+ // therefore parent is the 'armature'?
+ // also for multi root bone support make sure we don't already have the skeleton cached.
+ // if we do we must merge them - as this is all godot supports right now.
+ if (!parent_bone_assimp && recursive_state.skeleton == NULL && !do_not_create_armature) {
+ // create new skeleton on the root.
+ recursive_state.skeleton = memnew(Skeleton);
- String name_find_texture_sub_directory = p_path.get_base_dir() + "/textures/" + path.get_file().get_basename() + extension;
- if (dir.file_exists(name_find_texture_sub_directory)) {
- found = true;
- path = name_find_texture_sub_directory;
- return;
- }
- String name_find_texture_upper_sub_directory = p_path.get_base_dir() + "/Textures/" + path.get_file().get_basename() + extension;
- if (dir.file_exists(name_find_texture_upper_sub_directory)) {
- found = true;
- path = name_find_texture_upper_sub_directory;
- return;
- }
- String name_find_texture_outside_sub_directory = p_path.get_base_dir() + "/../textures/" + path.get_file().get_basename() + extension;
- if (dir.file_exists(name_find_texture_outside_sub_directory)) {
- found = true;
- path = name_find_texture_outside_sub_directory;
- return;
- }
+ ERR_FAIL_COND(state.root == NULL);
+ ERR_FAIL_COND(recursive_state.skeleton == NULL);
- String name_find_upper_texture_outside_sub_directory = p_path.get_base_dir() + "/../Textures/" + path.get_file().get_basename() + extension;
- if (dir.file_exists(name_find_upper_texture_outside_sub_directory)) {
- found = true;
- path = name_find_upper_texture_outside_sub_directory;
- return;
- }
-}
+ print_verbose("Parent armature node is called " + recursive_state.parent_node->get_name());
+ // store root node for this skeleton / used in animation playback and bone detection.
-String EditorSceneImporterAssimp::_assimp_get_string(const aiString p_string) const {
- //convert an assimp String to a Godot String
- String name;
- name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
- if (name.find(":") != -1) {
- String replaced_name = name.split(":")[1];
- print_verbose("Replacing " + name + " containing : with " + replaced_name);
- name = replaced_name;
+ state.armature_skeletons.insert(recursive_state.skeleton, Object::cast_to<Spatial>(recursive_state.parent_node));
+
+ //skeleton->set_use_bones_in_world_transform(true);
+ print_verbose("Created new FBX skeleton for armature node");
}
- name = name.replace(".", ""); //can break things, specially bone names
+ ERR_FAIL_COND_MSG(recursive_state.skeleton == NULL, "Mesh has invalid armature detection - report this");
- return name;
-}
+ // this transform is a bone
+ recursive_state.skeleton->add_bone(recursive_state.node_name);
+
+ //ERR_FAIL_COND(recursive_state.skeleton->get_name() == "");
+ print_verbose("Bone added to lookup: " + AssimpUtils::get_assimp_string(recursive_state.bone->mName));
+ print_verbose("Skeleton attached to: " + recursive_state.skeleton->get_name());
+ // make sure to write the bone lookup inverse so we can retrieve the mesh for this bone later
+ state.bone_to_skeleton_lookup.insert(recursive_state.bone, recursive_state.skeleton);
-String EditorSceneImporterAssimp::_assimp_anim_string_to_string(const aiString p_string) const {
+ Transform xform = AssimpUtils::assimp_matrix_transform(recursive_state.bone->mOffsetMatrix);
+ recursive_state.skeleton->set_bone_rest(recursive_state.skeleton->get_bone_count() - 1, xform.affine_inverse());
- String name;
- name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
- if (name.find(":") != -1) {
- String replaced_name = name.split(":")[1];
- print_verbose("Replacing " + name + " containing : with " + replaced_name);
- name = replaced_name;
+ // get parent node of assimp node
+ const aiNode *parent_node_assimp = recursive_state.assimp_node->mParent;
+
+ // ensure we have a parent
+ if (parent_node_assimp != NULL) {
+ int parent_bone_id = recursive_state.skeleton->find_bone(AssimpUtils::get_assimp_string(parent_node_assimp->mName));
+ int current_bone_id = recursive_state.skeleton->find_bone(recursive_state.node_name);
+ print_verbose("Parent bone id " + itos(parent_bone_id) + " current bone id" + itos(current_bone_id));
+ print_verbose("Bone debug: " + AssimpUtils::get_assimp_string(parent_node_assimp->mName));
+ recursive_state.skeleton->set_bone_parent(current_bone_id, parent_bone_id);
}
- return name;
}
-String EditorSceneImporterAssimp::_assimp_raw_string_to_string(const aiString p_string) const {
- String name;
- name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
- return name;
-}
+/**
+ * Generate node
+ * Recursive call to iterate over all nodes
+ */
+void EditorSceneImporterAssimp::_generate_node(
+ ImportState &state,
+ Skeleton *skeleton,
+ const aiNode *assimp_node, Node *parent_node) {
+
+ // sanity check
+ ERR_FAIL_COND(state.root == NULL);
+ ERR_FAIL_COND(state.assimp_scene == NULL);
+ ERR_FAIL_COND(assimp_node == NULL);
+ ERR_FAIL_COND(parent_node == NULL);
-Ref<Animation> EditorSceneImporterAssimp::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- return Ref<Animation>();
-}
+ Spatial *new_node = NULL;
+ String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
+ Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
-const Transform EditorSceneImporterAssimp::_assimp_matrix_transform(const aiMatrix4x4 p_matrix) {
- aiMatrix4x4 matrix = p_matrix;
- Transform xform;
- //xform.set(matrix.a1, matrix.b1, matrix.c1, matrix.a2, matrix.b2, matrix.c2, matrix.a3, matrix.b3, matrix.c3, matrix.a4, matrix.b4, matrix.c4);
- xform.set(matrix.a1, matrix.a2, matrix.a3, matrix.b1, matrix.b2, matrix.b3, matrix.c1, matrix.c2, matrix.c3, matrix.a4, matrix.b4, matrix.c4);
- return xform;
-}
+ // can safely return null - is this node a bone?
+ aiBone *bone = get_bone_by_name(state.assimp_scene, assimp_node->mName);
+
+ // out arguments helper - for pushing state down into creation functions
+ RecursiveState recursive_state(node_transform, skeleton, new_node, node_name, assimp_node, parent_node, bone);
+
+ // Creation code
+ if (state.light_cache.has(node_name)) {
+ create_light(state, recursive_state);
+ } else if (state.camera_cache.has(node_name)) {
+ create_camera(state, recursive_state);
+ } else if (bone != NULL) {
+ create_bone(state, recursive_state);
+ } else {
+ //generic node
+ recursive_state.new_node = memnew(Spatial);
+ attach_new_node(state,
+ recursive_state.new_node,
+ recursive_state.assimp_node,
+ recursive_state.parent_node,
+ recursive_state.node_name,
+ recursive_state.node_transform);
+ }
+
+ // recurse into all child elements
+ for (size_t i = 0; i < recursive_state.assimp_node->mNumChildren; i++) {
+ _generate_node(state, recursive_state.skeleton, recursive_state.assimp_node->mChildren[i],
+ recursive_state.new_node != NULL ? recursive_state.new_node : recursive_state.parent_node);
+ }
+} \ No newline at end of file
diff --git a/modules/assimp/editor_scene_importer_assimp.h b/modules/assimp/editor_scene_importer_assimp.h
index 598845236e..787376c9af 100644
--- a/modules/assimp/editor_scene_importer_assimp.h
+++ b/modules/assimp/editor_scene_importer_assimp.h
@@ -44,60 +44,31 @@
#include "scene/resources/animation.h"
#include "scene/resources/surface_tool.h"
-#include "assimp/DefaultLogger.hpp"
-#include "assimp/LogStream.hpp"
-#include "assimp/Logger.hpp"
-#include "assimp/matrix4x4.h"
-#include "assimp/scene.h"
-#include "assimp/types.h"
+#include <assimp/matrix4x4.h>
+#include <assimp/scene.h>
+#include <assimp/types.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/LogStream.hpp>
+#include <assimp/Logger.hpp>
+
+#include "import_state.h"
+#include "import_utils.h"
+
+using namespace AssimpImporter;
class AssimpStream : public Assimp::LogStream {
public:
// Constructor
- AssimpStream();
+ AssimpStream() {}
// Destructor
- ~AssimpStream();
+ ~AssimpStream() {}
// Write something using your own functionality
- void write(const char *message);
+ void write(const char *message) {
+ print_verbose(String("Open Asset Import: ") + String(message).strip_edges());
+ }
};
-#define AI_MATKEY_FBX_MAYA_BASE_COLOR_FACTOR "$raw.Maya|baseColor", 0, 0
-#define AI_MATKEY_FBX_MAYA_METALNESS_FACTOR "$raw.Maya|metalness", 0, 0
-#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_FACTOR "$raw.Maya|diffuseRoughness", 0, 0
-
-#define AI_MATKEY_FBX_MAYA_METALNESS_TEXTURE "$raw.Maya|metalness|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_METALNESS_UV_XFORM "$raw.Maya|metalness|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_TEXTURE "$raw.Maya|diffuseRoughness|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_UV_XFORM "$raw.Maya|diffuseRoughness|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_BASE_COLOR_TEXTURE "$raw.Maya|baseColor|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_BASE_COLOR_UV_XFORM "$raw.Maya|baseColor|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_NORMAL_TEXTURE "$raw.Maya|normalCamera|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo", aiTextureType_UNKNOWN, 0
-
-#define AI_MATKEY_FBX_NORMAL_TEXTURE "$raw.Maya|normalCamera|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo", aiTextureType_UNKNOWN, 0
-
-#define AI_MATKEY_FBX_MAYA_STINGRAY_DISPLACEMENT_SCALING_FACTOR "$raw.Maya|displacementscaling", 0, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_BASE_COLOR_FACTOR "$raw.Maya|base_color", 0, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_FACTOR "$raw.Maya|emissive", 0, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_FACTOR "$raw.Maya|metallic", 0, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_FACTOR "$raw.Maya|roughness", 0, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_INTENSITY_FACTOR "$raw.Maya|emissive_intensity", 0, 0
-
-#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_TEXTURE "$raw.Maya|TEX_normal_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_UV_XFORM "$raw.Maya|TEX_normal_map|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_TEXTURE "$raw.Maya|TEX_color_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_UV_XFORM "$raw.Maya|TEX_color_map|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_TEXTURE "$raw.Maya|TEX_metallic_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_UV_XFORM "$raw.Maya|TEX_metallic_map|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_TEXTURE "$raw.Maya|TEX_roughness_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_UV_XFORM "$raw.Maya|TEX_roughness_map|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_TEXTURE "$raw.Maya|TEX_emissive_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_UV_XFORM "$raw.Maya|TEX_emissive_map|uvtrafo", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_TEXTURE "$raw.Maya|TEX_ao_map|file", aiTextureType_UNKNOWN, 0
-#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_UV_XFORM "$raw.Maya|TEX_ao_map|uvtrafo", aiTextureType_UNKNOWN, 0
-
class EditorSceneImporterAssimp : public EditorSceneImporter {
private:
GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter);
@@ -112,59 +83,6 @@ private:
};
};
- struct AssetImportFbx {
- enum ETimeMode {
- TIME_MODE_DEFAULT = 0,
- TIME_MODE_120 = 1,
- TIME_MODE_100 = 2,
- TIME_MODE_60 = 3,
- TIME_MODE_50 = 4,
- TIME_MODE_48 = 5,
- TIME_MODE_30 = 6,
- TIME_MODE_30_DROP = 7,
- TIME_MODE_NTSC_DROP_FRAME = 8,
- TIME_MODE_NTSC_FULL_FRAME = 9,
- TIME_MODE_PAL = 10,
- TIME_MODE_CINEMA = 11,
- TIME_MODE_1000 = 12,
- TIME_MODE_CINEMA_ND = 13,
- TIME_MODE_CUSTOM = 14,
- TIME_MODE_TIME_MODE_COUNT = 15
- };
- enum UpAxis {
- UP_VECTOR_AXIS_X = 1,
- UP_VECTOR_AXIS_Y = 2,
- UP_VECTOR_AXIS_Z = 3
- };
- enum FrontAxis {
- FRONT_PARITY_EVEN = 1,
- FRONT_PARITY_ODD = 2,
- };
-
- enum CoordAxis {
- COORD_RIGHT = 0,
- COORD_LEFT = 1
- };
- };
-
- struct ImportState {
-
- String path;
- const aiScene *assimp_scene;
- uint32_t max_bone_weights;
- Spatial *root;
- Map<String, Ref<Mesh> > mesh_cache;
- Map<int, Ref<Material> > material_cache;
- Map<String, int> light_cache;
- Map<String, int> camera_cache;
- Vector<Skeleton *> skeletons;
- Map<String, int> bone_owners; //maps bones to skeleton index owned by
- Map<String, Node *> node_map;
- Map<MeshInstance *, Skeleton *> mesh_skeletons;
- bool fbx; //for some reason assimp does some things different for FBX
- AnimationPlayer *animation_player;
- };
-
struct BoneInfo {
uint32_t bone;
float weight;
@@ -177,31 +95,32 @@ private:
const aiNode *node;
};
- const Transform _assimp_matrix_transform(const aiMatrix4x4 p_matrix);
- String _assimp_get_string(const aiString p_string) const;
- Transform _get_global_assimp_node_transform(const aiNode *p_current_node);
-
void _calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w);
void _set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture);
- void _find_texture_path(const String &p_path, String &path, bool &r_found);
- void _find_texture_path(const String &p_path, _Directory &dir, String &path, bool &found, String extension);
-
- Ref<Texture> _load_texture(ImportState &state, String p_path);
- Ref<Material> _generate_material_from_index(ImportState &state, int p_index, bool p_double_sided);
- Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, Skeleton *p_skeleton = NULL, bool p_double_sided_material = false);
- void _generate_node(ImportState &state, const aiNode *p_assimp_node, Node *p_parent);
- void _generate_bone_groups(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<String, Transform> &bind_xforms);
- void _fill_node_relationships(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, int p_skeleton_id, Skeleton *p_skeleton, const String &p_parent_name, int &holecount, const Vector<SkeletonHole> &p_holes, const Map<String, Transform> &bind_xforms);
- void _generate_skeletons(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, const Map<String, Transform> &bind_xforms);
+ Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, const aiNode *assimp_node, Skeleton *p_skeleton = NULL);
+
+ // utility for node creation
+ void attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform);
+ // simple object creation functions
+ void create_light(ImportState &state, RecursiveState &recursive_state);
+ void create_camera(ImportState &state, RecursiveState &recursive_state);
+ void create_bone(ImportState &state, RecursiveState &recursive_state);
+ // non recursive - linear so must not use recursive arguments
+ void create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform);
+
+ // recursive node generator
+ void _generate_node(ImportState &state, Skeleton *skeleton, const aiNode *assimp_node, Node *parent_node);
+ // runs after _generate_node as it must then use pre-created godot skeleton.
+ void generate_mesh_phase_from_skeletal_mesh(ImportState &state);
void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name);
void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps);
- Spatial *_generate_scene(const String &p_path, const aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
+ Spatial *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
- String _assimp_anim_string_to_string(const aiString p_string) const;
- String _assimp_raw_string_to_string(const aiString p_string) const;
+ String _assimp_anim_string_to_string(const aiString &p_string) const;
+ String _assimp_raw_string_to_string(const aiString &p_string) const;
float _get_fbx_fps(int32_t time_mode, const aiScene *p_scene);
template <class T>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
@@ -228,7 +147,7 @@ public:
virtual void get_extensions(List<String> *r_extensions) const;
virtual uint32_t get_import_flags() const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path);
};
#endif
#endif
diff --git a/modules/assimp/godot_update_assimp.sh b/modules/assimp/godot_update_assimp.sh
index dcf1e6d4a2..ff8ff59e97 100644..100755
--- a/modules/assimp/godot_update_assimp.sh
+++ b/modules/assimp/godot_update_assimp.sh
@@ -254,8 +254,9 @@ rm -rf contrib/irrXML
rm -rf contrib/Open3DGC
rm -rf contrib/openddlparser
rm -rf contrib/poly2tri
-rm -rf contrib/rapidjson
+#rm -rf contrib/rapidjson
rm -rf contrib/unzip
rm -rf contrib/zip
rm -rf contrib/stb_image
rm .travis*
+
diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h
new file mode 100644
index 0000000000..56d89ffea7
--- /dev/null
+++ b/modules/assimp/import_state.h
@@ -0,0 +1,115 @@
+/*************************************************************************/
+/* import_state.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 EDITOR_SCENE_IMPORT_STATE_H
+#define EDITOR_SCENE_IMPORT_STATE_H
+
+#include "core/bind/core_bind.h"
+#include "core/io/resource_importer.h"
+#include "core/vector.h"
+#include "editor/import/resource_importer_scene.h"
+#include "editor/project_settings_editor.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/skeleton.h"
+#include "scene/3d/spatial.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/animation.h"
+#include "scene/resources/surface_tool.h"
+
+#include <assimp/matrix4x4.h>
+#include <assimp/scene.h>
+#include <assimp/types.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/LogStream.hpp>
+#include <assimp/Logger.hpp>
+
+namespace AssimpImporter {
+/** Import state is for global scene import data
+ * This makes the code simpler and contains useful lookups.
+ */
+struct ImportState {
+
+ String path;
+ const aiScene *assimp_scene;
+ uint32_t max_bone_weights;
+
+ Spatial *root;
+ Map<String, Ref<Mesh> > mesh_cache;
+ Map<int, Ref<Material> > material_cache;
+ Map<String, int> light_cache;
+ Map<String, int> camera_cache;
+ //Vector<Skeleton *> skeletons;
+ Map<Skeleton *, const Spatial *> armature_skeletons; // maps skeletons based on their armature nodes.
+ Map<const aiBone *, Skeleton *> bone_to_skeleton_lookup; // maps bones back into their skeleton
+ // very useful for when you need to ask assimp for the bone mesh
+ Map<String, Node *> node_map;
+ Map<const aiNode *, const Node *> assimp_node_map;
+ Map<String, Ref<Image> > path_to_image_cache;
+ bool fbx; //for some reason assimp does some things different for FBX
+ AnimationPlayer *animation_player;
+};
+
+struct AssimpImageData {
+ Ref<Image> raw_image;
+ Ref<ImageTexture> texture;
+ aiTextureMapMode map_mode[2];
+};
+
+/** Recursive state is used to push state into functions instead of specifying them
+ * This makes the code easier to handle too and add extra arguments without breaking things
+ */
+struct RecursiveState {
+ RecursiveState(
+ Transform &_node_transform,
+ Skeleton *_skeleton,
+ Spatial *_new_node,
+ const String &_node_name,
+ const aiNode *_assimp_node,
+ Node *_parent_node,
+ const aiBone *_bone) :
+ node_transform(_node_transform),
+ skeleton(_skeleton),
+ new_node(_new_node),
+ node_name(_node_name),
+ assimp_node(_assimp_node),
+ parent_node(_parent_node),
+ bone(_bone) {}
+
+ Transform &node_transform;
+ Skeleton *skeleton;
+ Spatial *new_node;
+ const String &node_name;
+ const aiNode *assimp_node;
+ Node *parent_node;
+ const aiBone *bone;
+};
+} // namespace AssimpImporter
+
+#endif // EDITOR_SCENE_IMPORT_STATE_H
diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h
new file mode 100644
index 0000000000..4be76ade0f
--- /dev/null
+++ b/modules/assimp/import_utils.h
@@ -0,0 +1,448 @@
+/*************************************************************************/
+/* import_utils.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 IMPORT_UTILS_IMPORTER_ASSIMP_H
+#define IMPORT_UTILS_IMPORTER_ASSIMP_H
+
+#include "core/io/image_loader.h"
+#include "import_state.h"
+
+#include <assimp/SceneCombiner.h>
+#include <assimp/cexport.h>
+#include <assimp/cimport.h>
+#include <assimp/matrix4x4.h>
+#include <assimp/pbrmaterial.h>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/LogStream.hpp>
+#include <assimp/Logger.hpp>
+#include <string>
+
+using namespace AssimpImporter;
+
+#define AI_PROPERTIES aiTextureType_UNKNOWN, 0
+#define AI_NULL 0, 0
+#define AI_MATKEY_FBX_MAYA_BASE_COLOR_FACTOR "$raw.Maya|baseColor"
+#define AI_MATKEY_FBX_MAYA_METALNESS_FACTOR "$raw.Maya|metalness"
+#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_FACTOR "$raw.Maya|diffuseRoughness"
+
+#define AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE "$raw.Maya|emissionColor|file"
+#define AI_MATKEY_FBX_MAYA_EMISSIVE_FACTOR "$raw.Maya|emission"
+#define AI_MATKEY_FBX_MAYA_METALNESS_TEXTURE "$raw.Maya|metalness|file"
+#define AI_MATKEY_FBX_MAYA_METALNESS_UV_XFORM "$raw.Maya|metalness|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_TEXTURE "$raw.Maya|diffuseRoughness|file"
+#define AI_MATKEY_FBX_MAYA_DIFFUSE_ROUGHNESS_UV_XFORM "$raw.Maya|diffuseRoughness|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_BASE_COLOR_TEXTURE "$raw.Maya|baseColor|file"
+#define AI_MATKEY_FBX_MAYA_BASE_COLOR_UV_XFORM "$raw.Maya|baseColor|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_NORMAL_TEXTURE "$raw.Maya|normalCamera|file"
+#define AI_MATKEY_FBX_MAYA_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo"
+
+#define AI_MATKEY_FBX_NORMAL_TEXTURE "$raw.Maya|normalCamera|file"
+#define AI_MATKEY_FBX_NORMAL_UV_XFORM "$raw.Maya|normalCamera|uvtrafo"
+
+#define AI_MATKEY_FBX_MAYA_STINGRAY_DISPLACEMENT_SCALING_FACTOR "$raw.Maya|displacementscaling"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_BASE_COLOR_FACTOR "$raw.Maya|base_color"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_FACTOR "$raw.Maya|emissive"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_FACTOR "$raw.Maya|metallic"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_FACTOR "$raw.Maya|roughness"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_INTENSITY_FACTOR "$raw.Maya|emissive_intensity"
+
+#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_TEXTURE "$raw.Maya|TEX_normal_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_NORMAL_UV_XFORM "$raw.Maya|TEX_normal_map|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_TEXTURE "$raw.Maya|TEX_color_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_COLOR_UV_XFORM "$raw.Maya|TEX_color_map|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_TEXTURE "$raw.Maya|TEX_metallic_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_METALLIC_UV_XFORM "$raw.Maya|TEX_metallic_map|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_TEXTURE "$raw.Maya|TEX_roughness_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_ROUGHNESS_UV_XFORM "$raw.Maya|TEX_roughness_map|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_TEXTURE "$raw.Maya|TEX_emissive_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_EMISSIVE_UV_XFORM "$raw.Maya|TEX_emissive_map|uvtrafo"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_TEXTURE "$raw.Maya|TEX_ao_map|file"
+#define AI_MATKEY_FBX_MAYA_STINGRAY_AO_UV_XFORM "$raw.Maya|TEX_ao_map|uvtrafo"
+
+/**
+ * Assimp Utils
+ * Conversion tools / glue code to convert from assimp to godot
+*/
+class AssimpUtils {
+public:
+ /**
+ * calculate tangents for mesh data from assimp data
+ */
+ static void calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w) {
+ const aiVector3D normals = ai_mesh->mAnimMeshes[i]->mNormals[tri_index];
+ const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
+ const aiVector3D tangent = ai_mesh->mAnimMeshes[i]->mTangents[tri_index];
+ const Vector3 godot_tangent = Vector3(tangent.x, tangent.y, tangent.z);
+ const aiVector3D bitangent = ai_mesh->mAnimMeshes[i]->mBitangents[tri_index];
+ const Vector3 godot_bitangent = Vector3(bitangent.x, bitangent.y, bitangent.z);
+ float d = godot_normal.cross(godot_tangent).dot(godot_bitangent) > 0.0f ? 1.0f : -1.0f;
+ Color plane_tangent = Color(tangent.x, tangent.y, tangent.z, d);
+ w[index] = plane_tangent;
+ }
+
+ struct AssetImportFbx {
+ enum ETimeMode {
+ TIME_MODE_DEFAULT = 0,
+ TIME_MODE_120 = 1,
+ TIME_MODE_100 = 2,
+ TIME_MODE_60 = 3,
+ TIME_MODE_50 = 4,
+ TIME_MODE_48 = 5,
+ TIME_MODE_30 = 6,
+ TIME_MODE_30_DROP = 7,
+ TIME_MODE_NTSC_DROP_FRAME = 8,
+ TIME_MODE_NTSC_FULL_FRAME = 9,
+ TIME_MODE_PAL = 10,
+ TIME_MODE_CINEMA = 11,
+ TIME_MODE_1000 = 12,
+ TIME_MODE_CINEMA_ND = 13,
+ TIME_MODE_CUSTOM = 14,
+ TIME_MODE_TIME_MODE_COUNT = 15
+ };
+ enum UpAxis {
+ UP_VECTOR_AXIS_X = 1,
+ UP_VECTOR_AXIS_Y = 2,
+ UP_VECTOR_AXIS_Z = 3
+ };
+ enum FrontAxis {
+ FRONT_PARITY_EVEN = 1,
+ FRONT_PARITY_ODD = 2,
+ };
+
+ enum CoordAxis {
+ COORD_RIGHT = 0,
+ COORD_LEFT = 1
+ };
+ };
+
+ /** Get assimp string
+ * automatically filters the string data
+ */
+ static String get_assimp_string(const aiString &p_string) {
+ //convert an assimp String to a Godot String
+ String name;
+ name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
+ if (name.find(":") != -1) {
+ String replaced_name = name.split(":")[1];
+ print_verbose("Replacing " + name + " containing : with " + replaced_name);
+ name = replaced_name;
+ }
+
+ return name;
+ }
+
+ static String get_anim_string_from_assimp(const aiString &p_string) {
+
+ String name;
+ name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
+ if (name.find(":") != -1) {
+ String replaced_name = name.split(":")[1];
+ print_verbose("Replacing " + name + " containing : with " + replaced_name);
+ name = replaced_name;
+ }
+ return name;
+ }
+
+ /**
+ * No filter logic get_raw_string_from_assimp
+ * This just convers the aiString to a parsed utf8 string
+ * Without removing special chars etc
+ */
+ static String get_raw_string_from_assimp(const aiString &p_string) {
+ String name;
+ name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
+ return name;
+ }
+
+ static Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+ return Ref<Animation>();
+ }
+
+ /**
+ * Converts aiMatrix4x4 to godot Transform
+ */
+ static const Transform assimp_matrix_transform(const aiMatrix4x4 p_matrix) {
+ aiMatrix4x4 matrix = p_matrix;
+ Transform xform;
+ xform.set(matrix.a1, matrix.a2, matrix.a3, matrix.b1, matrix.b2, matrix.b3, matrix.c1, matrix.c2, matrix.c3, matrix.a4, matrix.b4, matrix.c4);
+ return xform;
+ }
+
+ /** Get fbx fps for time mode meta data
+ */
+ static float get_fbx_fps(int32_t time_mode, const aiScene *p_scene) {
+ switch (time_mode) {
+ case AssetImportFbx::TIME_MODE_DEFAULT: return 24; //hack
+ case AssetImportFbx::TIME_MODE_120: return 120;
+ case AssetImportFbx::TIME_MODE_100: return 100;
+ case AssetImportFbx::TIME_MODE_60: return 60;
+ case AssetImportFbx::TIME_MODE_50: return 50;
+ case AssetImportFbx::TIME_MODE_48: return 48;
+ case AssetImportFbx::TIME_MODE_30: return 30;
+ case AssetImportFbx::TIME_MODE_30_DROP: return 30;
+ case AssetImportFbx::TIME_MODE_NTSC_DROP_FRAME: return 29.9700262f;
+ case AssetImportFbx::TIME_MODE_NTSC_FULL_FRAME: return 29.9700262f;
+ case AssetImportFbx::TIME_MODE_PAL: return 25;
+ case AssetImportFbx::TIME_MODE_CINEMA: return 24;
+ case AssetImportFbx::TIME_MODE_1000: return 1000;
+ case AssetImportFbx::TIME_MODE_CINEMA_ND: return 23.976f;
+ case AssetImportFbx::TIME_MODE_CUSTOM:
+ int32_t frame_rate = -1;
+ p_scene->mMetaData->Get("FrameRate", frame_rate);
+ return frame_rate;
+ }
+ return 0;
+ }
+
+ /**
+ * Get global transform for the current node - so we can use world space rather than
+ * local space coordinates
+ * useful if you need global - although recommend using local wherever possible over global
+ * as you could break fbx scaling :)
+ */
+ static Transform _get_global_assimp_node_transform(const aiNode *p_current_node) {
+ aiNode const *current_node = p_current_node;
+ Transform xform;
+ while (current_node != NULL) {
+ xform = assimp_matrix_transform(current_node->mTransformation) * xform;
+ current_node = current_node->mParent;
+ }
+ return xform;
+ }
+
+ /**
+ * Find hardcoded textures from assimp which could be in many different directories
+ */
+ static void find_texture_path(const String &p_path, _Directory &dir, String &path, bool &found, String extension) {
+ Vector<String> paths;
+ paths.push_back(path.get_basename() + extension);
+ paths.push_back(path + extension);
+ paths.push_back(path);
+ paths.push_back(p_path.get_base_dir().plus_file(path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file(path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file(path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("textures/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("Textures/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../Textures/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../textures/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("texture/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("Texture/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../Texture/" + path.get_file()));
+ paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file().get_basename() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file() + extension));
+ paths.push_back(p_path.get_base_dir().plus_file("../texture/" + path.get_file()));
+ for (int i = 0; i < paths.size(); i++) {
+ if (dir.file_exists(paths[i])) {
+ found = true;
+ path = paths[i];
+ return;
+ }
+ }
+ }
+
+ /** find the texture path for the supplied fbx path inside godot
+ * very simple lookup for subfolders etc for a texture which may or may not be in a directory
+ */
+ static void find_texture_path(const String &r_p_path, String &r_path, bool &r_found) {
+ _Directory dir;
+
+ List<String> exts;
+ ImageLoader::get_recognized_extensions(&exts);
+
+ Vector<String> split_path = r_path.get_basename().split("*");
+ if (split_path.size() == 2) {
+ r_found = true;
+ return;
+ }
+
+ if (dir.file_exists(r_p_path.get_base_dir() + r_path.get_file())) {
+ r_path = r_p_path.get_base_dir() + r_path.get_file();
+ r_found = true;
+ return;
+ }
+
+ for (int32_t i = 0; i < exts.size(); i++) {
+ if (r_found) {
+ return;
+ }
+ if (r_found == false) {
+ find_texture_path(r_p_path, dir, r_path, r_found, "." + exts[i]);
+ }
+ }
+ }
+
+ /**
+ * set_texture_mapping_mode
+ * Helper to check the mapping mode of the texture (repeat, clamp and mirror)
+ */
+ static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) {
+ ERR_FAIL_COND(texture.is_null());
+ ERR_FAIL_COND(map_mode == NULL);
+ aiTextureMapMode tex_mode = aiTextureMapMode::aiTextureMapMode_Wrap;
+
+ tex_mode = map_mode[0];
+
+ int32_t flags = Texture::FLAGS_DEFAULT;
+ if (tex_mode == aiTextureMapMode_Wrap) {
+ //Default
+ } else if (tex_mode == aiTextureMapMode_Clamp) {
+ flags = flags & ~Texture::FLAG_REPEAT;
+ } else if (tex_mode == aiTextureMapMode_Mirror) {
+ flags = flags | Texture::FLAG_MIRRORED_REPEAT;
+ }
+ texture->set_flags(flags);
+ }
+
+ /**
+ * Load or load from cache image :)
+ */
+ static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path) {
+
+ Map<String, Ref<Image> >::Element *match = state.path_to_image_cache.find(p_path);
+
+ // if our cache contains this image then don't bother
+ if (match) {
+ return match->get();
+ }
+
+ Vector<String> split_path = p_path.get_basename().split("*");
+ if (split_path.size() == 2) {
+ size_t texture_idx = split_path[1].to_int();
+ ERR_FAIL_COND_V(texture_idx >= p_scene->mNumTextures, Ref<Image>());
+ aiTexture *tex = p_scene->mTextures[texture_idx];
+ String filename = AssimpUtils::get_raw_string_from_assimp(tex->mFilename);
+ filename = filename.get_file();
+ print_verbose("Open Asset Import: Loading embedded texture " + filename);
+ if (tex->mHeight == 0) {
+ if (tex->CheckFormat("png")) {
+ Ref<Image> img = Image::_png_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
+ ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
+ state.path_to_image_cache.insert(p_path, img);
+ return img;
+ } else if (tex->CheckFormat("jpg")) {
+ Ref<Image> img = Image::_jpg_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
+ ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
+ state.path_to_image_cache.insert(p_path, img);
+ return img;
+ } else if (tex->CheckFormat("dds")) {
+ ERR_EXPLAIN("Open Asset Import: Embedded dds not implemented");
+ ERR_FAIL_COND_V(true, Ref<Image>());
+ }
+ } else {
+ Ref<Image> img;
+ img.instance();
+ PoolByteArray arr;
+ uint32_t size = tex->mWidth * tex->mHeight;
+ arr.resize(size);
+ memcpy(arr.write().ptr(), tex->pcData, size);
+ ERR_FAIL_COND_V(arr.size() % 4 != 0, Ref<Image>());
+ //ARGB8888 to RGBA8888
+ for (int32_t i = 0; i < arr.size() / 4; i++) {
+ arr.write().ptr()[(4 * i) + 3] = arr[(4 * i) + 0];
+ arr.write().ptr()[(4 * i) + 0] = arr[(4 * i) + 1];
+ arr.write().ptr()[(4 * i) + 1] = arr[(4 * i) + 2];
+ arr.write().ptr()[(4 * i) + 2] = arr[(4 * i) + 3];
+ }
+ img->create(tex->mWidth, tex->mHeight, true, Image::FORMAT_RGBA8, arr);
+ ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
+ state.path_to_image_cache.insert(p_path, img);
+ return img;
+ }
+ return Ref<Image>();
+ } else {
+ Ref<Texture> texture = ResourceLoader::load(p_path);
+ Ref<Image> image = texture->get_data();
+ state.path_to_image_cache.insert(p_path, image);
+ return image;
+ }
+
+ return Ref<Image>();
+ }
+
+ /* create texture from assimp data, if found in path */
+ static bool CreateAssimpTexture(
+ AssimpImporter::ImportState &state,
+ aiString texture_path,
+ String &filename,
+ String &path,
+ AssimpImageData &image_state) {
+ filename = get_raw_string_from_assimp(texture_path);
+ path = state.path.get_base_dir().plus_file(filename.replace("\\", "/"));
+ bool found = false;
+ find_texture_path(state.path, path, found);
+ if (found) {
+ image_state.raw_image = AssimpUtils::load_image(state, state.assimp_scene, path);
+ if (image_state.raw_image.is_valid()) {
+ image_state.texture.instance();
+ image_state.texture->create_from_image(image_state.raw_image);
+ image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ /** GetAssimpTexture
+ * Designed to retrieve textures for you
+ */
+ static bool GetAssimpTexture(
+ AssimpImporter::ImportState &state,
+ aiMaterial *ai_material,
+ aiTextureType texture_type,
+ String &filename,
+ String &path,
+ AssimpImageData &image_state) {
+ aiString ai_filename = aiString();
+ if (AI_SUCCESS == ai_material->GetTexture(texture_type, 0, &ai_filename, NULL, NULL, NULL, NULL, image_state.map_mode)) {
+ return CreateAssimpTexture(state, ai_filename, filename, path, image_state);
+ }
+
+ return false;
+ }
+};
+
+#endif // IMPORT_UTILS_IMPORTER_ASSIMP_H
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index a7e8dec11e..8708430257 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) {
@@ -66,139 +63,137 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
ERR_FAIL_V(ERR_UNAVAILABLE);
}
- if (err == OK) {
- // Image data (might be indexed)
- PoolVector<uint8_t> data;
- int data_len = 0;
+ // Image data (might be indexed)
+ PoolVector<uint8_t> data;
+ int data_len = 0;
- if (bits_per_pixel <= 8) { // indexed
- data_len = width * height;
- } else { // color
- data_len = width * height * 4;
- }
- ERR_FAIL_COND_V(data_len == 0, ERR_BUG);
- err = data.resize(data_len);
-
- PoolVector<uint8_t>::Write data_w = data.write();
- uint8_t *write_buffer = data_w.ptr();
-
- const uint32_t width_bytes = width * bits_per_pixel / 8;
- const uint32_t line_width = (width_bytes + 3) & ~3;
-
- // The actual data traversal is determined by
- // the data width in case of 8/4/1 bit images
- const uint32_t w = bits_per_pixel >= 24 ? width : width_bytes;
- const uint8_t *line = p_buffer + (line_width * (height - 1));
-
- for (unsigned int i = 0; i < height; i++) {
- const uint8_t *line_ptr = line;
-
- for (unsigned int j = 0; j < w; j++) {
- switch (bits_per_pixel) {
- case 1: {
- uint8_t color_index = *line_ptr;
-
- write_buffer[index + 0] = (color_index >> 7) & 1;
- write_buffer[index + 1] = (color_index >> 6) & 1;
- write_buffer[index + 2] = (color_index >> 5) & 1;
- write_buffer[index + 3] = (color_index >> 4) & 1;
- write_buffer[index + 4] = (color_index >> 3) & 1;
- write_buffer[index + 5] = (color_index >> 2) & 1;
- write_buffer[index + 6] = (color_index >> 1) & 1;
- write_buffer[index + 7] = (color_index >> 0) & 1;
-
- index += 8;
- line_ptr += 1;
- } break;
- case 4: {
- uint8_t color_index = *line_ptr;
-
- write_buffer[index + 0] = (color_index >> 4) & 0x0f;
- write_buffer[index + 1] = color_index & 0x0f;
-
- index += 2;
- line_ptr += 1;
- } break;
- case 8: {
- uint8_t color_index = *line_ptr;
-
- write_buffer[index] = color_index;
-
- index += 1;
- line_ptr += 1;
- } break;
- case 24: {
- uint32_t color = *((uint32_t *)line_ptr);
-
- write_buffer[index + 2] = color & 0xff;
- write_buffer[index + 1] = (color >> 8) & 0xff;
- write_buffer[index + 0] = (color >> 16) & 0xff;
- write_buffer[index + 3] = 0xff;
-
- index += 4;
- line_ptr += 3;
- } break;
- case 32: {
- uint32_t color = *((uint32_t *)line_ptr);
-
- write_buffer[index + 2] = color & 0xff;
- write_buffer[index + 1] = (color >> 8) & 0xff;
- write_buffer[index + 0] = (color >> 16) & 0xff;
- write_buffer[index + 3] = color >> 24;
-
- index += 4;
- line_ptr += 4;
- } break;
- }
+ if (bits_per_pixel <= 8) { // indexed
+ data_len = width * height;
+ } else { // color
+ data_len = width * height * 4;
+ }
+ ERR_FAIL_COND_V(data_len == 0, ERR_BUG);
+ err = data.resize(data_len);
+
+ PoolVector<uint8_t>::Write data_w = data.write();
+ uint8_t *write_buffer = data_w.ptr();
+
+ const uint32_t width_bytes = width * bits_per_pixel / 8;
+ const uint32_t line_width = (width_bytes + 3) & ~3;
+
+ // The actual data traversal is determined by
+ // the data width in case of 8/4/1 bit images
+ const uint32_t w = bits_per_pixel >= 24 ? width : width_bytes;
+ const uint8_t *line = p_buffer + (line_width * (height - 1));
+
+ for (uint64_t i = 0; i < height; i++) {
+ const uint8_t *line_ptr = line;
+
+ for (unsigned int j = 0; j < w; j++) {
+ switch (bits_per_pixel) {
+ case 1: {
+ uint8_t color_index = *line_ptr;
+
+ write_buffer[index + 0] = (color_index >> 7) & 1;
+ write_buffer[index + 1] = (color_index >> 6) & 1;
+ write_buffer[index + 2] = (color_index >> 5) & 1;
+ write_buffer[index + 3] = (color_index >> 4) & 1;
+ write_buffer[index + 4] = (color_index >> 3) & 1;
+ write_buffer[index + 5] = (color_index >> 2) & 1;
+ write_buffer[index + 6] = (color_index >> 1) & 1;
+ write_buffer[index + 7] = (color_index >> 0) & 1;
+
+ index += 8;
+ line_ptr += 1;
+ } break;
+ case 4: {
+ uint8_t color_index = *line_ptr;
+
+ write_buffer[index + 0] = (color_index >> 4) & 0x0f;
+ write_buffer[index + 1] = color_index & 0x0f;
+
+ index += 2;
+ line_ptr += 1;
+ } break;
+ case 8: {
+ uint8_t color_index = *line_ptr;
+
+ write_buffer[index] = color_index;
+
+ index += 1;
+ line_ptr += 1;
+ } break;
+ case 24: {
+ uint32_t color = *((uint32_t *)line_ptr);
+
+ write_buffer[index + 2] = color & 0xff;
+ write_buffer[index + 1] = (color >> 8) & 0xff;
+ write_buffer[index + 0] = (color >> 16) & 0xff;
+ write_buffer[index + 3] = 0xff;
+
+ index += 4;
+ line_ptr += 3;
+ } break;
+ case 32: {
+ uint32_t color = *((uint32_t *)line_ptr);
+
+ write_buffer[index + 2] = color & 0xff;
+ write_buffer[index + 1] = (color >> 8) & 0xff;
+ write_buffer[index + 0] = (color >> 16) & 0xff;
+ write_buffer[index + 3] = color >> 24;
+
+ index += 4;
+ line_ptr += 4;
+ } break;
}
- line -= line_width;
}
+ line -= line_width;
+ }
- if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels
+ if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels
- p_image->create(width, height, 0, Image::FORMAT_RGBA8, data);
+ p_image->create(width, height, 0, Image::FORMAT_RGBA8, data);
- } else { // data is in indexed format, extend it
+ } else { // data is in indexed format, extend it
- // Palette data
- PoolVector<uint8_t> palette_data;
- palette_data.resize(color_table_size * 4);
+ // Palette data
+ PoolVector<uint8_t> palette_data;
+ palette_data.resize(color_table_size * 4);
- PoolVector<uint8_t>::Write palette_data_w = palette_data.write();
- uint8_t *pal = palette_data_w.ptr();
+ PoolVector<uint8_t>::Write palette_data_w = palette_data.write();
+ uint8_t *pal = palette_data_w.ptr();
- const uint8_t *cb = p_color_buffer;
+ const uint8_t *cb = p_color_buffer;
- for (unsigned int i = 0; i < color_table_size; ++i) {
- uint32_t color = *((uint32_t *)cb);
+ for (unsigned int i = 0; i < color_table_size; ++i) {
+ uint32_t color = *((uint32_t *)cb);
- pal[i * 4 + 0] = (color >> 16) & 0xff;
- pal[i * 4 + 1] = (color >> 8) & 0xff;
- pal[i * 4 + 2] = (color)&0xff;
- pal[i * 4 + 3] = 0xff;
+ pal[i * 4 + 0] = (color >> 16) & 0xff;
+ pal[i * 4 + 1] = (color >> 8) & 0xff;
+ pal[i * 4 + 2] = (color)&0xff;
+ pal[i * 4 + 3] = 0xff;
- cb += 4;
- }
- // Extend palette to image
- PoolVector<uint8_t> extended_data;
- extended_data.resize(data.size() * 4);
+ cb += 4;
+ }
+ // Extend palette to image
+ PoolVector<uint8_t> extended_data;
+ extended_data.resize(data.size() * 4);
- PoolVector<uint8_t>::Write ex_w = extended_data.write();
- uint8_t *dest = ex_w.ptr();
+ PoolVector<uint8_t>::Write ex_w = extended_data.write();
+ uint8_t *dest = ex_w.ptr();
- const int num_pixels = width * height;
+ const int num_pixels = width * height;
- for (int i = 0; i < num_pixels; i++) {
- dest[0] = pal[write_buffer[i] * 4 + 0];
- dest[1] = pal[write_buffer[i] * 4 + 1];
- dest[2] = pal[write_buffer[i] * 4 + 2];
- dest[3] = pal[write_buffer[i] * 4 + 3];
+ for (int i = 0; i < num_pixels; i++) {
+ dest[0] = pal[write_buffer[i] * 4 + 0];
+ dest[1] = pal[write_buffer[i] * 4 + 1];
+ dest[2] = pal[write_buffer[i] * 4 + 2];
+ dest[3] = pal[write_buffer[i] * 4 + 3];
- dest += 4;
- }
- p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data);
+ dest += 4;
}
+ p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data);
}
}
return err;
@@ -238,11 +233,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
+ String bmp_path = f->get_path();
+ f->close();
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Compressed BMP files are not supported: " + bmp_path + ".");
+ } break;
}
// Don't rely on sizeof(bmp_file_header) as structure padding
// adds 2 bytes offset leading to misaligned color table reading
@@ -257,8 +257,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/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 038001996d..e01928191a 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -1548,8 +1548,7 @@ void BulletPhysicsServer::free(RID p_rid) {
bulletdelete(space);
} else {
- ERR_EXPLAIN("Invalid ID");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid ID.");
}
}
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index bc7fd52cf6..97b9a81f77 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -83,8 +83,7 @@ void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param,
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value);
break;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -102,8 +101,7 @@ real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_para
case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
return coneConstraint->getRelaxationFactor();
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 0d2c46c579..4aae87c220 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -174,8 +174,7 @@ void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DO
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint = p_value;
break;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -216,8 +215,7 @@ real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6
case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
@@ -255,8 +253,7 @@ void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOF
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value;
break;
default:
- ERR_EXPLAIN("This flag " + itos(p_flag) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The flag " + itos(p_flag) + " is deprecated.");
break;
}
}
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index b7e1e1a4c2..4d26e729db 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -117,8 +117,7 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t
hingeConstraint->setMaxMotorImpulse(p_value);
break;
default:
- ERR_EXPLAIN("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
break;
}
}
@@ -143,8 +142,7 @@ real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const
case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
return hingeConstraint->getMaxMotorImpulse();
default:
- ERR_EXPLAIN("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index c9c4d1af7e..8d404e7f04 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -85,8 +85,7 @@ real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
return p2pConstraint->m_setting.m_impulseClamp;
default:
- ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 2c9bdb8b0b..f63148092f 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -305,7 +305,7 @@ public:
void reload_axis_lock();
/// Doc:
- /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
+ /// https://web.archive.org/web/20180404091446/http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
void set_continuous_collision_detection(bool p_enable);
bool is_continuous_collision_detection_enabled() const;
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index f15bcec914..85f47c3bbb 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -505,8 +505,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
}
} else {
- ERR_EXPLAIN("Expected PoolRealArray or float Image.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Expected PoolRealArray or float Image.");
}
ERR_FAIL_COND(l_width <= 0);
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 738b415d16..d2b16b0fd1 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -582,6 +582,8 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
world_mem = malloc(sizeof(btDiscreteDynamicsWorld));
}
+ ERR_FAIL_COND_MSG(!world_mem, "Out of memory.");
+
if (p_create_soft_world) {
collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
} else {
@@ -1230,7 +1232,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
ERR_FAIL_COND_V(shape_idx < 0 || shape_idx >= cs->getNumChildShapes(), false);
if (cs->getChildShape(shape_idx)->isConvex()) {
- if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(shape_idx)), otherObject, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
+ if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(shape_idx)), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
penetration = true;
}
@@ -1241,7 +1243,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
}
}
} else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape
- if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
+ if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
penetration = true;
}
@@ -1257,7 +1259,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
return penetration;
}
-bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) {
+bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) {
// Initialize GJK input
btGjkPairDetector::ClosestPointInput gjk_input;
@@ -1275,6 +1277,7 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt
if (r_recover_result) {
if (result.m_distance < r_recover_result->penetration_distance) {
r_recover_result->hasPenetration = true;
+ r_recover_result->local_shape_most_recovered = p_shapeId_A;
r_recover_result->other_collision_object = p_objectB;
r_recover_result->other_compound_shape_index = p_shapeId_B;
r_recover_result->penetration_distance = result.m_distance;
@@ -1310,6 +1313,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
if (r_recover_result) {
if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) {
r_recover_result->hasPenetration = true;
+ r_recover_result->local_shape_most_recovered = p_shapeId_A;
r_recover_result->other_collision_object = p_objectB;
r_recover_result->other_compound_shape_index = p_shapeId_B;
r_recover_result->penetration_distance = contactPointResult.m_penetration_distance;
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index eb4a065e54..ecf8a2db9d 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -208,7 +208,7 @@ private:
bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
/// This is an API that recover a kinematic object from penetration
/// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions
- bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
+ bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
/// This is an API that recover a kinematic object from penetration
/// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm
bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index fd0d36eddf..5a76f32977 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -114,7 +114,7 @@ void CSGBrush::_regen_face_aabbs() {
faces.write[i].aabb.position = faces[i].vertices[0];
faces.write[i].aabb.expand_to(faces[i].vertices[1]);
faces.write[i].aabb.expand_to(faces[i].vertices[2]);
- faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision erros
+ faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision errors
}
}
@@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
//check if edge and poly share a vertex, of so, assign it to segment_idx
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < 2; j++) {
- if (Math::is_zero_approx(segment[j].distance_to(points[i].point))) {
+ if (segment[j] == points[i].point) {
segment_idx[j] = i;
inserted_points.push_back(i);
break;
@@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
- if (Math::is_zero_approx(closest.distance_to(segment[j]))) {
+ if (closest == segment[j]) {
//point rest of this edge
res = closest;
found = true;
@@ -439,7 +439,7 @@ void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, Mes
//transform A points to 2D
- if (Math::is_zero_approx(segment[0].distance_to(segment[1])))
+ if (segment[0] == segment[1])
return; //too small
_clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
@@ -461,10 +461,10 @@ void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map
{
//check if either is a degenerate
- if (Math::is_zero_approx(va[0].distance_to(va[1])) || Math::is_zero_approx(va[0].distance_to(va[2])) || Math::is_zero_approx(va[1].distance_to(va[2])))
+ if (va[0] == va[1] || va[0] == va[2] || va[1] == va[2])
return;
- if (Math::is_zero_approx(vb[0].distance_to(vb[1])) || Math::is_zero_approx(vb[0].distance_to(vb[2])) || Math::is_zero_approx(vb[1].distance_to(vb[2])))
+ if (vb[0] == vb[1] || vb[0] == vb[2] || vb[1] == vb[2])
return;
}
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index e6bfa5525d..0d26943af6 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -377,7 +377,7 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
break;
}
- p_gizmo->add_mesh(mesh, false, RID(), solid_material);
+ p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), solid_material);
}
if (Object::cast_to<CSGSphere>(cs)) {
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/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/SCsub b/modules/cvtt/SCsub
index 142af0c800..746b23ca28 100644
--- a/modules/cvtt/SCsub
+++ b/modules/cvtt/SCsub
@@ -6,19 +6,18 @@ Import('env_modules')
env_cvtt = env_modules.Clone()
# Thirdparty source files
-if env['builtin_squish']:
- thirdparty_dir = "#thirdparty/cvtt/"
- thirdparty_sources = [
- "ConvectionKernels.cpp"
- ]
+thirdparty_dir = "#thirdparty/cvtt/"
+thirdparty_sources = [
+ "ConvectionKernels.cpp"
+]
- thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
- env_cvtt.Prepend(CPPPATH=[thirdparty_dir])
+env_cvtt.Prepend(CPPPATH=[thirdparty_dir])
- env_thirdparty = env_cvtt.Clone()
- env_thirdparty.disable_warnings()
- env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
+env_thirdparty = env_cvtt.Clone()
+env_thirdparty.disable_warnings()
+env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
# Godot source files
env_cvtt.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 4628bd9a5b..0220dcae4a 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -108,8 +108,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
if (r_error)
*r_error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN("Unable to open DDS texture file: " + p_path);
- ERR_FAIL_COND_V(err != OK, RES());
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open DDS texture file: " + p_path + ".");
uint32_t magic = f->get_32();
uint32_t hsize = f->get_32();
@@ -128,8 +127,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
if (magic != DDS_MAGIC || hsize != 124 || !(flags & DDSD_PIXELFORMAT) || !(flags & DDSD_CAPS)) {
- ERR_EXPLAIN("Invalid or Unsupported DDS texture file: " + p_path);
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Invalid or unsupported DDS texture file: " + p_path + ".");
}
/* uint32_t format_size = */ f->get_32();
@@ -218,9 +216,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
} else {
printf("unrecognized fourcc %x format_flags: %x - rgbbits %i - red_mask %x green mask %x blue mask %x alpha mask %x\n", format_fourcc, format_flags, format_rgb_bits, format_red_mask, format_green_mask, format_blue_mask, format_alpha_mask);
- ERR_EXPLAIN("Unrecognized or Unsupported color layout in DDS: " + p_path);
-
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unrecognized or unsupported color layout in DDS: " + p_path + ".");
}
if (!(flags & DDSD_MIPMAPCOUNT))
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index a5a356ced2..44f69ca261 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -543,10 +543,7 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
if (target_peer != 0) {
E = peer_map.find(ABS(target_peer));
- if (!E) {
- ERR_EXPLAIN("Invalid Target Peer: " + itos(target_peer));
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer: " + itos(target_peer) + ".");
}
ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 8, packet_flags);
@@ -794,11 +791,7 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
ERR_FAIL_COND(p_channel < -1 || p_channel >= channel_count);
-
- if (p_channel == SYSCH_CONFIG) {
- ERR_EXPLAIN("Channel " + itos(SYSCH_CONFIG) + " is reserved");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, "Channel " + itos(SYSCH_CONFIG) + " is reserved.");
transfer_channel = p_channel;
}
diff --git a/modules/etc/SCsub b/modules/etc/SCsub
index 532b97b006..1742d3534f 100644
--- a/modules/etc/SCsub
+++ b/modules/etc/SCsub
@@ -29,10 +29,6 @@ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_etc.Prepend(CPPPATH=[thirdparty_dir])
-# upstream uses c++11
-if not env.msvc:
- env_etc.Append(CXXFLAGS="-std=c++11")
-
env_thirdparty = env_etc.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index ff925480b8..dd61d816d4 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -56,17 +56,14 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
if (r_error)
*r_error = ERR_FILE_CORRUPT;
- ERR_EXPLAIN("Unable to open PKM texture file: " + p_path);
- ERR_FAIL_COND_V(err != OK, RES());
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open PKM texture file: " + p_path + ".");
// big endian
f->set_endian_swap(true);
ETC1Header h;
- ERR_EXPLAIN("Invalid or Unsupported PKM texture file: " + p_path);
f->get_buffer((uint8_t *)&h.tag, sizeof(h.tag));
- if (strncmp(h.tag, "PKM 10", sizeof(h.tag)))
- ERR_FAIL_V(RES());
+ ERR_FAIL_COND_V_MSG(strncmp(h.tag, "PKM 10", sizeof(h.tag)), RES(), "Invalid or unsupported PKM texture file: " + p_path + ".");
h.format = f->get_16();
h.texWidth = f->get_16();
diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp
index 64e2c362b2..bd6eb575d0 100644
--- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp
+++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp
@@ -245,8 +245,7 @@ extern "C" {
void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) {
// If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin
- ERR_EXPLAINC("GDNative ARVR interfaces build for Godot 3.0 are not supported");
- ERR_FAIL_COND((p_interface->version.major == 0) || (p_interface->version.major > 10));
+ ERR_FAIL_COND_MSG((p_interface->version.major == 0) || (p_interface->version.major > 10), "GDNative ARVR interfaces build for Godot 3.0 are not supported.");
Ref<ARVRInterfaceGDNative> new_interface;
new_interface.instance();
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..dc735546e3 100644
--- a/modules/gdnative/doc_classes/NativeScript.xml
+++ b/modules/gdnative/doc_classes/NativeScript.xml
@@ -42,7 +42,7 @@
</description>
</method>
<method name="new" qualifiers="vararg">
- <return type="Object">
+ <return type="Variant">
</return>
<description>
Constructs a new object of the base type with a script of this type already attached.
@@ -53,7 +53,7 @@
<members>
<member name="class_name" type="String" setter="set_class_name" getter="get_class_name" default="&quot;&quot;">
</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="&quot;&quot;">
</member>
diff --git a/modules/gdnative/doc_classes/PluginScript.xml b/modules/gdnative/doc_classes/PluginScript.xml
index b07122bbdf..33b5f02bd4 100644
--- a/modules/gdnative/doc_classes/PluginScript.xml
+++ b/modules/gdnative/doc_classes/PluginScript.xml
@@ -8,7 +8,7 @@
</tutorials>
<methods>
<method name="new" qualifiers="vararg">
- <return type="Object">
+ <return type="Variant">
</return>
<description>
Returns a new instance of the script.
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 4eb9a2a0a3..783ad4e147 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -268,8 +268,7 @@ void GDNative::_bind_methods() {
}
void GDNative::set_library(Ref<GDNativeLibrary> p_library) {
- ERR_EXPLAIN("Tried to change library of GDNative when it is already set");
- ERR_FAIL_COND(library.is_valid());
+ ERR_FAIL_COND_MSG(library.is_valid(), "Tried to change library of GDNative when it is already set.");
library = p_library;
}
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 1ef8e9f900..e97a75cca8 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -327,6 +327,15 @@ godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_b
return res;
}
+godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep) {
+ const Array *self = (const Array *)p_self;
+ godot_array res;
+ Array *val = (Array *)&res;
+ memnew_placement(val, Array);
+ *val = self->slice(p_begin, p_end, p_step, p_deep);
+ return res;
+}
+
godot_variant GDAPI godot_array_max(const godot_array *p_self) {
const Array *self = (const Array *)p_self;
godot_variant v;
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 913c57eb56..9086121940 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -186,6 +186,20 @@ godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_
return self->ends_with(*string);
}
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->count(*what, p_from, p_to);
+}
+
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->countn(*what, p_from, p_to);
+}
+
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what) {
const String *self = (const String *)p_self;
String *what = (String *)&p_what;
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index a2ac61b35e..d82f2c692d 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -77,6 +77,14 @@ godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self) {
return self->is_normalized();
}
+godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ *((Vector2 *)&dest) = self->direction_to(*to);
+ return dest;
+}
+
godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
const Vector2 *self = (const Vector2 *)p_self;
const Vector2 *to = (const Vector2 *)p_to;
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index 894683ab38..15a8ef9a2e 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -182,6 +182,14 @@ godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self) {
return dest;
}
+godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_to) {
+ godot_vector3 dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *to = (const Vector3 *)p_to;
+ *((Vector3 *)&dest) = self->direction_to(*to);
+ return dest;
+}
+
godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
const Vector3 *self = (const Vector3 *)p_self;
const Vector3 *b = (const Vector3 *)p_b;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 6c12ee6534..55ba4ecc1e 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -44,6 +44,53 @@
["const godot_vector2 *", "p_to"],
["const godot_real", "p_delta"]
]
+ },
+ {
+ "name": "godot_string_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_string_countn",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector3_direction_to",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_direction_to",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_array_slice",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_array *", "p_self"],
+ ["const godot_int", "p_begin"],
+ ["const godot_int", "p_end"],
+ ["const godot_int", "p_step"],
+ ["const godot_bool", "p_deep"]
+ ]
}
]
},
@@ -6512,24 +6559,24 @@
"name": "godot_net_bind_stream_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_stream_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_stream_peer *", "p_interface"]
]
},
{
"name": "godot_net_bind_packet_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_packet_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_packet_peer *", "p_interface"]
]
},
{
"name": "godot_net_bind_multiplayer_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_multiplayer_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_multiplayer_peer *", "p_interface"]
]
}
]
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 7ab0e01108..20c1a2233c 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -185,7 +185,7 @@ def _build_gdnative_api_struct_source(api):
'extern const godot_gdnative_core_' + ('{0}_{1}_api_struct api_{0}_{1}'.format(core['version']['major'], core['version']['minor'])) + ' = {',
'\tGDNATIVE_' + core['type'] + ',',
'\t{' + str(core['version']['major']) + ', ' + str(core['version']['minor']) + '},',
- '\t' + ('NULL' if not core['next'] else ('(const godot_gdnative_api_struct *)& api_{0}_{1}'.format(core['version']['major'], core['version']['minor']))) + ','
+ '\t' + ('NULL' if not core['next'] else ('(const godot_gdnative_api_struct *)& api_{0}_{1}'.format(core['next']['version']['major'], core['next']['version']['minor']))) + ','
]
for funcdef in core['api']:
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index e2a69b1635..5d272a6cdc 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -66,10 +66,18 @@ void GDNativeLibraryEditor::_update_tree() {
tree->clear();
TreeItem *root = tree->create_item();
- for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+ PopupMenu *filter_list = filter->get_popup();
+ String text = "";
+ for (int i = 0; i < filter_list->get_item_count(); i++) {
- if (showing_platform != E->key() && showing_platform != "All")
+ if (!filter_list->is_item_checked(i)) {
continue;
+ }
+ Map<String, NativePlatformConfig>::Element *E = platforms.find(filter_list->get_item_metadata(i));
+ if (!text.empty()) {
+ text += ", ";
+ }
+ text += E->get().name;
TreeItem *platform = tree->create_item(root);
platform->set_text(0, E->get().name);
@@ -119,6 +127,7 @@ void GDNativeLibraryEditor::_update_tree() {
platform->set_collapsed(collapsed_items.find(E->get().name) != NULL);
}
+ filter->set_text(text);
}
void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
@@ -162,9 +171,10 @@ void GDNativeLibraryEditor::_on_dependencies_selected(const PoolStringArray &fil
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files);
}
-void GDNativeLibraryEditor::_on_filter_selected(int id) {
+void GDNativeLibraryEditor::_on_filter_selected(int index) {
- showing_platform = filter->get_item_metadata(id);
+ PopupMenu *filter_list = filter->get_popup();
+ filter_list->set_item_checked(index, !filter_list->is_item_checked(index));
_update_tree();
}
@@ -265,8 +275,6 @@ void GDNativeLibraryEditor::_translate_to_config_file() {
GDNativeLibraryEditor::GDNativeLibraryEditor() {
- showing_platform = "All";
-
{ // Define platforms
NativePlatformConfig platform_windows;
platform_windows.name = "Windows";
@@ -336,20 +344,21 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
Label *label = memnew(Label);
label->set_text(TTR("Platform:"));
hbox->add_child(label);
- filter = memnew(OptionButton);
- hbox->add_child(filter);
+ filter = memnew(MenuButton);
filter->set_h_size_flags(SIZE_EXPAND_FILL);
+ filter->set_text_align(filter->ALIGN_LEFT);
+ hbox->add_child(filter);
+ PopupMenu *filter_list = filter->get_popup();
+ filter_list->set_hide_on_checkable_item_selection(false);
int idx = 0;
- filter->add_item(TTR("All"), idx);
- filter->set_item_metadata(idx, "All");
- idx += 1;
for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
- filter->add_item(E->get().name, idx);
- filter->set_item_metadata(idx, E->key());
+ filter_list->add_check_item(E->get().name, idx);
+ filter_list->set_item_metadata(idx, E->key());
+ filter_list->set_item_checked(idx, true);
idx += 1;
}
- filter->connect("item_selected", this, "_on_filter_selected");
+ filter_list->connect("index_pressed", this, "_on_filter_selected");
tree = memnew(Tree);
container->add_child(tree);
@@ -387,11 +396,9 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
void GDNativeLibraryEditorPlugin::edit(Object *p_node) {
- if (Object::cast_to<GDNativeLibrary>(p_node)) {
- library_editor->edit(Object::cast_to<GDNativeLibrary>(p_node));
- library_editor->show();
- } else
- library_editor->hide();
+ Ref<GDNativeLibrary> new_library = Object::cast_to<GDNativeLibrary>(p_node);
+ if (new_library.is_valid())
+ library_editor->edit(new_library);
}
bool GDNativeLibraryEditorPlugin::handles(Object *p_node) const {
diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h
index e7d50ba29f..8c1449f55a 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.h
+++ b/modules/gdnative/gdnative_library_editor_plugin.h
@@ -61,7 +61,7 @@ class GDNativeLibraryEditor : public Control {
};
Tree *tree;
- OptionButton *filter;
+ MenuButton *filter;
EditorFileDialog *file_dialog;
ConfirmationDialog *new_architecture_dialog;
LineEdit *new_architecture_input;
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index 10ef8a73d2..2e3ce58033 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -132,6 +132,8 @@ void GDAPI godot_array_destroy(godot_array *p_self);
godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep);
+godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_delta, const godot_bool p_deep);
+
godot_variant GDAPI godot_array_max(const godot_array *p_self);
godot_variant GDAPI godot_array_min(const godot_array *p_self);
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index f045ac9d58..7500d70f20 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -102,6 +102,8 @@ godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self,
godot_array GDAPI godot_string_bigrams(const godot_string *p_self);
godot_string GDAPI godot_string_chr(wchar_t p_character);
godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string);
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what);
godot_int GDAPI godot_string_find_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 7a5ae6afa9..15a6c80887 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -71,6 +71,8 @@ godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self);
godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self);
+godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 70ec6422ac..ee7d029028 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -106,6 +106,8 @@ godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self);
godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self);
+godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index f3b9f7fb31..8a05b6cfa3 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -56,7 +56,7 @@ typedef enum {
GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease)
GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- GODOT_PROPERTY_HINT_SPRITE_FRAME,
+ GODOT_PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -64,9 +64,9 @@ typedef enum {
GODOT_PROPERTY_HINT_LAYERS_3D_RENDER,
GODOT_PROPERTY_HINT_LAYERS_3D_PHYSICS,
GODOT_PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
- GODOT_PROPERTY_HINT_DIR, ///< a directort path must be passed
+ GODOT_PROPERTY_HINT_DIR, ///< a directory path must be passed
GODOT_PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
- GODOT_PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed
+ GODOT_PROPERTY_HINT_GLOBAL_DIR, ///< a directory path must be passed
GODOT_PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type
GODOT_PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines
GODOT_PROPERTY_HINT_PLACEHOLDER_TEXT, ///< used to set a placeholder text for string properties
@@ -98,8 +98,8 @@ typedef enum {
GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
GODOT_PROPERTY_USAGE_CATEGORY = 256,
- GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
- GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
+ GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, // FIXME: Obsolete: drop whenever we can break compat
+ GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index 863999d6d4..979e47f7b9 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -104,11 +104,7 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to register method on non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to register method on non-existent class.");
NativeScriptDesc::Method method;
method.method = p_method;
@@ -123,11 +119,7 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to register method on non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to register method on non-existent class.");
NativeScriptDesc::Property property;
property.default_value = *(Variant *)&p_attr->default_value;
@@ -148,11 +140,7 @@ void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const cha
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to register method on non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to register method on non-existent class.");
List<PropertyInfo> args;
Vector<Variant> default_args;
@@ -213,17 +201,10 @@ void GDAPI godot_nativescript_set_method_argument_information(void *p_gdnative_h
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to add argument information for a method on a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to add argument information for a method on a non-existent class.");
Map<StringName, NativeScriptDesc::Method>::Element *method = E->get().methods.find(p_function_name);
- if (!method) {
- ERR_EXPLAIN("Attempted to add argument information to non-existent method!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!method, "Attempted to add argument information to non-existent method.");
MethodInfo *method_information = &method->get().info;
@@ -247,11 +228,7 @@ void GDAPI godot_nativescript_set_class_documentation(void *p_gdnative_handle, c
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to add documentation to a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to add documentation to a non-existent class.");
E->get().documentation = *(String *)&p_documentation;
}
@@ -260,17 +237,10 @@ void GDAPI godot_nativescript_set_method_documentation(void *p_gdnative_handle,
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to add documentation to a method on a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to add documentation to a method on a non-existent class.");
Map<StringName, NativeScriptDesc::Method>::Element *method = E->get().methods.find(p_function_name);
- if (!method) {
- ERR_EXPLAIN("Attempted to add documentatino to non-existent method!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!method, "Attempted to add documentation to non-existent method.");
method->get().documentation = *(String *)&p_documentation;
}
@@ -279,17 +249,10 @@ void GDAPI godot_nativescript_set_property_documentation(void *p_gdnative_handle
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to add documentation to a property on a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to add documentation to a property on a non-existent class.");
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element property = E->get().properties.find(p_path);
- if (!property) {
- ERR_EXPLAIN("Attempted to add documentation to non-existent property!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!property, "Attempted to add documentation to non-existent property.");
property.get().documentation = *(String *)&p_documentation;
}
@@ -298,17 +261,10 @@ void GDAPI godot_nativescript_set_signal_documentation(void *p_gdnative_handle,
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to add documentation to a signal on a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to add documentation to a signal on a non-existent class.");
Map<StringName, NativeScriptDesc::Signal>::Element *signal = E->get().signals_.find(p_signal_name);
- if (!signal) {
- ERR_EXPLAIN("Attempted to add documentation to non-existent signal!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!signal, "Attempted to add documentation to non-existent signal.");
signal->get().documentation = *(String *)&p_documentation;
}
@@ -325,11 +281,7 @@ void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
-
- if (!E) {
- ERR_EXPLAIN("Attempted to set type tag on a non-existent class!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!E, "Attempted to set type tag on a non-existent class.");
E->get().type_tag = p_type_tag;
}
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index f30c9da4c1..7c313c983f 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -79,7 +79,7 @@ void NativeScript::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "script_class_name"), "set_script_class_name", "get_script_class_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "script_class_icon_path", PROPERTY_HINT_FILE), "set_script_class_icon_path", "get_script_class_icon_path");
- ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &NativeScript::_new, MethodInfo(Variant::OBJECT, "new"));
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &NativeScript::_new, MethodInfo("new"));
}
#define NSL NativeScriptLanguage::get_singleton()
@@ -402,10 +402,7 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
String NativeScript::get_class_documentation() const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data) {
- ERR_EXPLAIN("Attempt to get class documentation on invalid NativeScript");
- ERR_FAIL_V("");
- }
+ ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get class documentation on invalid NativeScript.");
return script_data->documentation;
}
@@ -413,10 +410,7 @@ String NativeScript::get_class_documentation() const {
String NativeScript::get_method_documentation(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data) {
- ERR_EXPLAIN("Attempt to get method documentation on invalid NativeScript");
- ERR_FAIL_V("");
- }
+ ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get method documentation on invalid NativeScript.");
while (script_data) {
@@ -429,17 +423,13 @@ String NativeScript::get_method_documentation(const StringName &p_method) const
script_data = script_data->base_data;
}
- ERR_EXPLAIN("Attempt to get method documentation for non-existent method");
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Attempt to get method documentation for non-existent method.");
}
String NativeScript::get_signal_documentation(const StringName &p_signal_name) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data) {
- ERR_EXPLAIN("Attempt to get signal documentation on invalid NativeScript");
- ERR_FAIL_V("");
- }
+ ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get signal documentation on invalid NativeScript.");
while (script_data) {
@@ -452,17 +442,13 @@ String NativeScript::get_signal_documentation(const StringName &p_signal_name) c
script_data = script_data->base_data;
}
- ERR_EXPLAIN("Attempt to get signal documentation for non-existent signal");
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Attempt to get signal documentation for non-existent signal.");
}
String NativeScript::get_property_documentation(const StringName &p_path) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data) {
- ERR_EXPLAIN("Attempt to get property documentation on invalid NativeScript");
- ERR_FAIL_V("");
- }
+ ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get property documentation on invalid NativeScript.");
while (script_data) {
@@ -475,8 +461,7 @@ String NativeScript::get_property_documentation(const StringName &p_path) const
script_data = script_data->base_data;
}
- ERR_EXPLAIN("Attempt to get property documentation for non-existent signal");
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Attempt to get property documentation for non-existent signal.");
}
Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
@@ -655,10 +640,7 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
Variant res = *(Variant *)&result;
godot_variant_destroy(&result);
- if (res.get_type() != Variant::ARRAY) {
- ERR_EXPLAIN("_get_property_list must return an array of dictionaries");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(res.get_type() != Variant::ARRAY, "_get_property_list must return an array of dictionaries.");
Array arr = res;
for (int i = 0; i < arr.size(); i++) {
@@ -780,8 +762,7 @@ String NativeScriptInstance::to_string(bool *r_valid) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
- ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
if (r_valid)
*r_valid = true;
@@ -1344,10 +1325,7 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) {
void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_object) {
ERR_FAIL_INDEX_V(p_idx, binding_functions.size(), NULL);
- if (!binding_functions[p_idx].first) {
- ERR_EXPLAIN("Tried to get binding data for a nativescript binding that does not exist");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!binding_functions[p_idx].first, NULL, "Tried to get binding data for a nativescript binding that does not exist.");
Vector<void *> *binding_data = (Vector<void *> *)p_object->get_script_instance_binding(lang_idx);
@@ -1499,8 +1477,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
#endif
// See if this library was "registered" already.
const String &lib_path = lib->get_current_library_path();
- ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform");
- ERR_FAIL_COND(lib_path.length() == 0);
+ ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform.");
Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
if (!E) {
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index 9de073fc8e..22898a73ce 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -200,7 +200,7 @@ void PluginScriptLanguage::get_recognized_extensions(List<String> *p_extensions)
}
void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
- // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ // TODO: provide this statically in `godot_pluginscript_language_desc` ?
if (_desc.get_public_functions) {
Array functions;
_desc.get_public_functions(_data, (godot_array *)&functions);
@@ -212,7 +212,7 @@ void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c
}
void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
- // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ // TODO: provide this statically in `godot_pluginscript_language_desc` ?
if (_desc.get_public_constants) {
Dictionary constants;
_desc.get_public_constants(_data, (godot_dictionary *)&constants);
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index 3ecb29404a..94d38e1be1 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -35,16 +35,14 @@
#include "pluginscript_script.h"
#ifdef DEBUG_ENABLED
-#define __ASSERT_SCRIPT_REASON "Cannot retrieve pluginscript class for this script, is you code correct ?"
-#define ASSERT_SCRIPT_VALID() \
- { \
- ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
- ERR_FAIL_COND(!can_instance()); \
+#define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?"
+#define ASSERT_SCRIPT_VALID() \
+ { \
+ ERR_FAIL_COND_MSG(!can_instance(), __ASSERT_SCRIPT_REASON); \
}
-#define ASSERT_SCRIPT_VALID_V(ret) \
- { \
- ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
- ERR_FAIL_COND_V(!can_instance(), ret); \
+#define ASSERT_SCRIPT_VALID_V(ret) \
+ { \
+ ERR_FAIL_COND_V_MSG(!can_instance(), ret, __ASSERT_SCRIPT_REASON); \
}
#else
#define ASSERT_SCRIPT_VALID()
@@ -52,7 +50,7 @@
#endif
void PluginScript::_bind_methods() {
- ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &PluginScript::_new, MethodInfo(Variant::OBJECT, "new"));
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &PluginScript::_new, MethodInfo("new"));
}
PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Variant::CallError &r_error) {
@@ -197,8 +195,7 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) {
// if (ScriptDebugger::get_singleton()) {
// _language->debug_break_parse(get_path(), 0, msg);
// }
- ERR_EXPLAIN(msg);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, msg);
}
}
@@ -272,8 +269,7 @@ Error PluginScript::reload(bool p_keep_state) {
_ref_base_parent = res;
} else {
String name = *(StringName *)&manifest.name;
- ERR_EXPLAIN(_path + ": Script '" + name + "' has an invalid parent '" + *base_name + "'.");
- ERR_FAIL_V(ERR_PARSE_ERROR);
+ ERR_FAIL_V_MSG(ERR_PARSE_ERROR, _path + ": Script '" + name + "' has an invalid parent '" + *base_name + "'.");
}
}
}
@@ -420,8 +416,7 @@ Error PluginScript::load_source_code(const String &p_path) {
String s;
if (s.parse_utf8((const char *)w.ptr())) {
- ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
- ERR_FAIL_V(ERR_INVALID_DATA);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
_source = s;
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
index b7ab887e11..3b46f33afb 100644
--- a/modules/gdnative/pluginscript/register_types.cpp
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -114,6 +114,8 @@ void unregister_pluginscript_types() {
for (List<PluginScriptLanguage *>::Element *e = pluginscript_languages.front(); e; e = e->next()) {
PluginScriptLanguage *language = e->get();
ScriptServer::unregister_language(language);
+ ResourceLoader::remove_resource_format_loader(language->get_resource_loader());
+ ResourceSaver::remove_resource_format_saver(language->get_resource_saver());
memdelete(language);
}
}
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index be131c5402..212ff51b80 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -149,7 +149,7 @@ void VideoStreamPlaybackGDNative::update(float p_delta) {
if (mix_callback) {
if (pcm_write_idx >= 0) {
// Previous remains
- int mixed = mix_callback(mix_udata, pcm, samples_decoded);
+ int mixed = mix_callback(mix_udata, pcm + pcm_write_idx * num_channels, samples_decoded);
if (mixed == samples_decoded) {
pcm_write_idx = -1;
} else {
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 6904154953..74e653ce43 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -8,4 +8,12 @@ env_gdscript = env_modules.Clone()
env_gdscript.add_source_files(env.modules_sources, "*.cpp")
if env['tools']:
- env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp")
+ env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp")
+
+ # Those two modules are required for the language server protocol
+ if env['module_jsonrpc_enabled'] and env['module_websocket_enabled']:
+ env_gdscript.add_source_files(env.modules_sources, "./language_server/*.cpp")
+ else:
+ # Using a define in the disabled case, to avoid having an extra define
+ # in regular builds where all modules are enabled.
+ env_gdscript.Append(CPPDEFINES=['GDSCRIPT_NO_LSP'])
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 3870a5ea7d..4efa90fd86 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -322,6 +322,7 @@
<description>
The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it.
[b]e[/b] has an approximate value of 2.71828.
+ For exponents to other bases use the method [method pow].
[codeblock]
a = exp(2) # Approximately 7.39
[/codeblock]
@@ -345,45 +346,47 @@
<method name="fmod">
<return type="float">
</return>
- <argument index="0" name="x" type="float">
+ <argument index="0" name="a" type="float">
</argument>
- <argument index="1" name="y" type="float">
+ <argument index="1" name="b" type="float">
</argument>
<description>
- Returns the floating-point remainder of [code]x/y[/code].
+ Returns the floating-point remainder of [code]a/b[/code], keeping the sign of [code]a[/code].
[codeblock]
# Remainder is 1.5
var remainder = fmod(7, 5.5)
[/codeblock]
+ For the integer remainder operation, use the % operator.
</description>
</method>
<method name="fposmod">
<return type="float">
</return>
- <argument index="0" name="x" type="float">
+ <argument index="0" name="a" type="float">
</argument>
- <argument index="1" name="y" type="float">
+ <argument index="1" name="b" type="float">
</argument>
<description>
- Returns the floating-point remainder of [code]x/y[/code] that wraps equally in positive and negative.
+ Returns the floating-point modulus of [code]a/b[/code] that wraps equally in positive and negative.
[codeblock]
- var i = -10
- while i &lt; 0:
- prints(i, fposmod(i, 10))
+ var i = -6
+ while i &lt; 5:
+ prints(i, fposmod(i, 3))
i += 1
[/codeblock]
Produces:
[codeblock]
- -10 10
- -9 1
- -8 2
- -7 3
- -6 4
- -5 5
- -4 6
- -3 7
- -2 8
- -1 9
+ -6 0
+ -5 1
+ -4 2
+ -3 0
+ -2 1
+ -1 2
+ 0 0
+ 1 1
+ 2 2
+ 3 0
+ 4 1
[/codeblock]
</description>
</method>
@@ -571,6 +574,29 @@
[/codeblock]
</description>
</method>
+ <method name="lerp_angle">
+ <return type="float">
+ </return>
+ <argument index="0" name="from" type="float">
+ </argument>
+ <argument index="1" name="to" type="float">
+ </argument>
+ <argument index="2" name="weight" type="float">
+ </argument>
+ <description>
+ Linearly interpolates between two angles (in radians) by a normalized value.
+ Similar to [method lerp] but interpolate correctly when the angles wrap around [constant @GDScript.TAU].
+ [codeblock]
+ extends Sprite
+ var elapsed = 0.0
+ func _process(delta):
+ var min_angle = deg2rad(0.0)
+ var max_angle = deg2rad(90.0)
+ rotation = lerp_angle(min_angle, max_angle, elapsed)
+ elapsed += delta
+ [/codeblock]
+ </description>
+ </method>
<method name="linear2db">
<return type="float">
</return>
@@ -697,12 +723,43 @@
Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis).
</description>
</method>
+ <method name="posmod">
+ <return type="int">
+ </return>
+ <argument index="0" name="a" type="int">
+ </argument>
+ <argument index="1" name="b" type="int">
+ </argument>
+ <description>
+ Returns the integer modulus of [code]a/b[/code] that wraps equally in positive and negative.
+ [codeblock]
+ var i = -6
+ while i &lt; 5:
+ prints(i, posmod(i, 3))
+ i += 1
+ [/codeblock]
+ Produces:
+ [codeblock]
+ -6 0
+ -5 1
+ -4 2
+ -3 0
+ -2 1
+ -1 2
+ 0 0
+ 1 1
+ 2 2
+ 3 0
+ 4 1
+ [/codeblock]
+ </description>
+ </method>
<method name="pow">
<return type="float">
</return>
- <argument index="0" name="x" type="float">
+ <argument index="0" name="base" type="float">
</argument>
- <argument index="1" name="y" type="float">
+ <argument index="1" name="exp" type="float">
</argument>
<description>
Returns the result of [code]x[/code] raised to the power of [code]y[/code].
@@ -1039,7 +1096,7 @@
<argument index="0" name="step" type="float">
</argument>
<description>
- Returns the position of the first non-zero digit, after the decimal point.
+ Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation.
[codeblock]
# n is 0
n = step_decimals(5)
@@ -1058,7 +1115,11 @@
<argument index="1" name="step" type="float">
</argument>
<description>
- Snaps float value [code]s[/code] to a given [code]step[/code].
+ Snaps float value [code]s[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals.
+ [codeblock]
+ stepify(100, 32) # Returns 96
+ stepify(3.14159, 0.01) # Returns 3.14
+ [/codeblock]
</description>
</method>
<method name="str" qualifiers="vararg">
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index d606a41fab..6f43361914 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -19,7 +19,7 @@
</description>
</method>
<method name="new" qualifiers="vararg">
- <return type="Object">
+ <return type="Variant">
</return>
<description>
Returns a new instance of the script.
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index bc28f7009e..c8ec80c101 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -67,10 +67,7 @@ void GDScriptNativeClass::_bind_methods() {
Variant GDScriptNativeClass::_new() {
Object *o = instance();
- if (!o) {
- ERR_EXPLAIN("Class type: '" + String(name) + "' is not instantiable.");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable.");
Reference *ref = Object::cast_to<Reference>(o);
if (ref) {
@@ -102,7 +99,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
#endif
instance->owner->set_script_instance(instance);
- /* STEP 2, INITIALIZE AND CONSRTUCT */
+ /* STEP 2, INITIALIZE AND CONSTRUCT */
#ifndef NO_THREADS
GDScriptLanguage::singleton->lock->lock();
@@ -158,8 +155,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallErro
} else {
owner = memnew(Reference); //by default, no base means use reference
}
- ERR_EXPLAIN("Can't inherit from a virtual class");
- ERR_FAIL_COND_V(!owner, Variant());
+ ERR_FAIL_COND_V_MSG(!owner, Variant(), "Can't inherit from a virtual class.");
Reference *r = Object::cast_to<Reference>(owner);
if (r) {
@@ -326,8 +322,7 @@ ScriptInstance *GDScript::instance_create(Object *p_this) {
if (ScriptDebugger::get_singleton()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
}
- ERR_EXPLAIN("Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type '" + p_this->get_class() + "'" + ".");
}
}
@@ -648,10 +643,7 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method);
if (E) {
- if (!E->get()->is_static()) {
- ERR_EXPLAIN("Can't call non-static function: '" + String(p_method) + "' in script.");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(!E->get()->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script.");
return E->get()->call(NULL, p_args, p_argcount, r_error);
}
@@ -718,7 +710,7 @@ void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
void GDScript::_bind_methods() {
- ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo(Variant::OBJECT, "new"));
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new"));
ClassDB::bind_method(D_METHOD("get_as_byte_code"), &GDScript::get_as_byte_code);
}
@@ -826,8 +818,7 @@ Error GDScript::load_source_code(const String &p_path) {
String s;
if (s.parse_utf8((const char *)w.ptr())) {
- ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
- ERR_FAIL_V(ERR_INVALID_DATA);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
source = s;
@@ -1079,11 +1070,8 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err);
if (err.error == Variant::CallError::CALL_OK) {
- if (ret.get_type() != Variant::ARRAY) {
+ ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
- ERR_EXPLAIN("Wrong type for _get_property list, must be an array of dictionaries.");
- ERR_FAIL();
- }
Array arr = ret;
for (int i = 0; i < arr.size(); i++) {
@@ -1243,8 +1231,7 @@ String GDScriptInstance::to_string(bool *r_valid) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
- ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
if (r_valid)
*r_valid = true;
@@ -2057,8 +2044,7 @@ String GDScriptWarning::get_message() const {
} break;
case WARNING_MAX: break; // Can't happen, but silences warning
}
- ERR_EXPLAIN("Invalid GDScript warning code: " + get_name_from_code(code));
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Invalid GDScript warning code: " + get_name_from_code(code) + ".");
#undef CHECK_SYMBOLS
}
@@ -2110,8 +2096,7 @@ GDScriptWarning::Code GDScriptWarning::get_code_from_name(const String &p_name)
}
}
- ERR_EXPLAIN("Invalid GDScript warning name: " + p_name);
- ERR_FAIL_V(WARNING_MAX);
+ ERR_FAIL_V_MSG(WARNING_MAX, "Invalid GDScript warning name: " + p_name);
}
#endif // DEBUG_ENABLED
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 4c976bd2e0..dea2225e91 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1241,8 +1241,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
default: {
- ERR_EXPLAIN("Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression.");
- ERR_FAIL_V(0); //unreachable code
+ ERR_FAIL_V_MSG(0, "Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression."); //unreachable code
} break;
}
@@ -1255,8 +1254,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//TYPE_TYPE,
default: {
- ERR_EXPLAIN("Bug in bytecode compiler, unexpected node in parse tree while parsing expression.");
- ERR_FAIL_V(-1); //unreachable code
+ ERR_FAIL_V_MSG(-1, "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); //unreachable code
} break;
}
}
@@ -1522,8 +1520,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
if (ret2 < 0)
return ERR_PARSE_ERROR;
+ int message_ret = 0;
+ if (as->message) {
+ message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
+ if (message_ret < 0)
+ return ERR_PARSE_ERROR;
+ }
+
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
codegen.opcodes.push_back(ret2);
+ codegen.opcodes.push_back(message_ret);
#endif
} break;
case GDScriptParser::Node::TYPE_BREAKPOINT: {
@@ -2066,7 +2072,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
}
instance->owner->set_script_instance(instance);
- /* STEP 2, INITIALIZE AND CONSRTUCT */
+ /* STEP 2, INITIALIZE AND CONSTRUCT */
Variant::CallError ce;
p_script->initializer->call(instance, NULL, 0, ce);
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 78a1bfc99b..9b3bf8ad5b 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;
}
}
@@ -219,7 +223,7 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const
_debug_parse_err_line = p_line;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false);
+ ScriptDebugger::get_singleton()->debug(this, false, true);
return true;
} else {
return false;
@@ -233,7 +237,8 @@ bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue)
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, p_allow_continue);
+ bool is_error_breakpoint = p_error != "Breakpoint";
+ ScriptDebugger::get_singleton()->debug(this, p_allow_continue, is_error_breakpoint);
return true;
} else {
return false;
@@ -382,8 +387,6 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_line >= 0)
- return "";
return "";
}
@@ -632,7 +635,7 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
- ERR_EXPLAIN("Uninitialized completion. Please report a bug.");
+ ERR_PRINT("Uninitialized completion. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: {
ci.type.kind = GDScriptParser::DataType::BUILTIN;
@@ -1934,9 +1937,18 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
Ref<GDScript> script = base_type.script_type;
if (script.is_valid()) {
if (!_static && !p_only_functions) {
- for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
- ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER);
- r_result.insert(option.display, option);
+ if (p_context.base && p_context.base->get_script_instance()) {
+ List<PropertyInfo> members;
+ p_context.base->get_script_instance()->get_property_list(&members);
+ for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
+ ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER);
+ r_result.insert(option.display, option);
+ }
+ } else {
+ for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) {
+ ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER);
+ r_result.insert(option.display, option);
+ }
}
}
if (!p_only_functions) {
@@ -2824,6 +2836,16 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS);
options.insert(option.display, option);
}
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ String s = E->get().name;
+ if (!s.begins_with("autoload/")) {
+ continue;
+ }
+ ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CLASS);
+ options.insert(option.display, option);
+ }
}
List<StringName> native_classes;
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index d5e74c07c9..bdeea9cef3 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -86,8 +86,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
o = o->_owner;
}
- ERR_EXPLAIN("GDScriptCompiler bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "GDScriptCompiler bug.");
} break;
case ADDR_TYPE_LOCAL_CONSTANT: {
#ifdef DEBUG_ENABLED
@@ -128,8 +127,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
} break;
}
- ERR_EXPLAIN("Bad Code! (Addressing Mode)");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Bad code! (unknown addressing mode).");
return NULL;
}
@@ -433,6 +431,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
profile.frame_call_count++;
}
bool exit_ok = false;
+ bool yielded = false;
#endif
#ifdef DEBUG_ENABLED
@@ -1325,6 +1324,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
exit_ok = true;
+ yielded = true;
#endif
OPCODE_BREAK;
}
@@ -1475,20 +1475,25 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSERT) {
- CHECK_SPACE(2);
+ CHECK_SPACE(3);
#ifdef DEBUG_ENABLED
GET_VARIANT_PTR(test, 1);
+ GET_VARIANT_PTR(message, 2);
bool result = test->booleanize();
if (!result) {
-
- err_text = "Assertion failed.";
+ const String &message_str = *message;
+ if (message_str.empty()) {
+ err_text = "Assertion failed.";
+ } else {
+ err_text = "Assertion failed: " + message_str;
+ }
OPCODE_BREAK;
}
#endif
- ip += 2;
+ ip += 3;
}
DISPATCH_OPCODE;
@@ -1591,8 +1596,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GDScriptLanguage::get_singleton()->script_frame_time += time_taken - function_call_time;
}
- bool yielded = retvalue.is_ref() && Object::cast_to<GDScriptFunctionState>(retvalue);
-
// Check if this is the last time the function is resuming from yield
// Will be true if never yielded as well
// When it's the last resume it will postpone the exit from stack,
@@ -1784,20 +1787,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 +1815,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 {
@@ -1882,8 +1837,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
ERR_FAIL_COND_V(!function, Variant());
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());
+ ERR_FAIL_V_MSG(Variant(), "Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
#else
return Variant();
#endif
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index 0736f3d010..97790e00bb 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -58,6 +58,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"sqrt",
"fmod",
"fposmod",
+ "posmod",
"floor",
"ceil",
"round",
@@ -75,6 +76,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"step_decimals",
"stepify",
"lerp",
+ "lerp_angle",
"inverse_lerp",
"range_lerp",
"smoothstep",
@@ -104,6 +106,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"typeof",
"type_exists",
"char",
+ "ord",
"str",
"print",
"printt",
@@ -243,6 +246,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_NUM(1);
r_ret = Math::fposmod((double)*p_args[0], (double)*p_args[1]);
} break;
+ case MATH_POSMOD: {
+ VALIDATE_ARG_COUNT(2);
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ r_ret = Math::posmod((int)*p_args[0], (int)*p_args[1]);
+ } break;
case MATH_FLOOR: {
VALIDATE_ARG_COUNT(1);
VALIDATE_ARG_NUM(0);
@@ -341,8 +350,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_COUNT(1);
VALIDATE_ARG_NUM(0);
r_ret = Math::step_decimals((double)*p_args[0]);
- ERR_EXPLAIN("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly.");
} break;
case MATH_STEP_DECIMALS: {
VALIDATE_ARG_COUNT(1);
@@ -376,6 +384,13 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
}
} break;
+ case MATH_LERP_ANGLE: {
+ VALIDATE_ARG_COUNT(3);
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ r_ret = Math::lerp_angle((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
+ } break;
case MATH_INVERSE_LERP: {
VALIDATE_ARG_COUNT(3);
VALIDATE_ARG_NUM(0);
@@ -651,6 +666,33 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
CharType result[2] = { *p_args[0], 0 };
r_ret = String(result);
} break;
+ case TEXT_ORD: {
+
+ VALIDATE_ARG_COUNT(1);
+
+ if (p_args[0]->get_type() != Variant::STRING) {
+
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::STRING;
+ r_ret = Variant();
+ return;
+ }
+
+ String str = p_args[0]->operator String();
+
+ if (str.length() != 1) {
+
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::STRING;
+ r_ret = RTR("Expected a string of length 1 (a character).");
+ return;
+ }
+
+ r_ret = str.get(0);
+
+ } break;
case TEXT_STR: {
if (p_arg_count < 1) {
r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -1456,6 +1498,7 @@ bool GDScriptFunctions::is_deterministic(Function p_func) {
case MATH_SQRT:
case MATH_FMOD:
case MATH_FPOSMOD:
+ case MATH_POSMOD:
case MATH_FLOOR:
case MATH_CEIL:
case MATH_ROUND:
@@ -1492,6 +1535,7 @@ bool GDScriptFunctions::is_deterministic(Function p_func) {
case TYPE_OF:
case TYPE_EXISTS:
case TEXT_CHAR:
+ case TEXT_ORD:
case TEXT_STR:
case COLOR8:
case LEN:
@@ -1568,15 +1612,20 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_FMOD: {
- MethodInfo mi("fmod", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y"));
+ MethodInfo mi("fmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
case MATH_FPOSMOD: {
- MethodInfo mi("fposmod", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y"));
+ MethodInfo mi("fposmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
+ case MATH_POSMOD: {
+ MethodInfo mi("posmod", PropertyInfo(Variant::INT, "a"), PropertyInfo(Variant::INT, "b"));
+ mi.return_val.type = Variant::INT;
+ return mi;
+ } break;
case MATH_FLOOR: {
MethodInfo mi("floor", PropertyInfo(Variant::REAL, "s"));
mi.return_val.type = Variant::REAL;
@@ -1603,7 +1652,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_POW: {
- MethodInfo mi("pow", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y"));
+ MethodInfo mi("pow", PropertyInfo(Variant::REAL, "base"), PropertyInfo(Variant::REAL, "exp"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
@@ -1663,6 +1712,11 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
+ case MATH_LERP_ANGLE: {
+ MethodInfo mi("lerp_angle", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
+ mi.return_val.type = Variant::REAL;
+ return mi;
+ } break;
case MATH_INVERSE_LERP: {
MethodInfo mi("inverse_lerp", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
mi.return_val.type = Variant::REAL;
@@ -1824,6 +1878,13 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
+ case TEXT_ORD: {
+
+ MethodInfo mi("ord", PropertyInfo(Variant::STRING, "char"));
+ mi.return_val.type = Variant::INT;
+ return mi;
+
+ } break;
case TEXT_STR: {
MethodInfo mi("str");
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index 6ad70f2eb4..9ea5dd46cf 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -49,6 +49,7 @@ public:
MATH_SQRT,
MATH_FMOD,
MATH_FPOSMOD,
+ MATH_POSMOD,
MATH_FLOOR,
MATH_CEIL,
MATH_ROUND,
@@ -66,6 +67,7 @@ public:
MATH_STEP_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
+ MATH_LERP_ANGLE,
MATH_INVERSE_LERP,
MATH_RANGE_LERP,
MATH_SMOOTHSTEP,
@@ -95,6 +97,7 @@ public:
TYPE_OF,
TYPE_EXISTS,
TEXT_CHAR,
+ TEXT_ORD,
TEXT_STR,
TEXT_PRINT,
TEXT_PRINT_TABBED,
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 80da606967..967b0c83ae 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -252,6 +252,16 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
}
+ // Check that the next token is not TK_CURSOR and if it is, the offset should be incremented.
+ int next_valid_offset = 1;
+ if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_CURSOR) {
+ next_valid_offset++;
+ // There is a chunk of the identifier that also needs to be ignored (not always there!)
+ if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_IDENTIFIER) {
+ next_valid_offset++;
+ }
+ }
+
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
//subexpression ()
tokenizer->advance();
@@ -504,7 +514,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Ref<GDScript> gds = res;
if (gds.is_valid() && !gds->is_valid()) {
- _set_error("Could not fully preload the script, possible cyclic reference or compilation error. Use 'load()' instead if a cyclic reference is intended.");
+ _set_error("Couldn't fully preload the script, possible cyclic reference or compilation error. Use \"load()\" instead if a cyclic reference is intended.");
return NULL;
}
@@ -518,7 +528,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_YIELD) {
if (!current_function) {
- _set_error("yield() can only be used inside function blocks.");
+ _set_error("\"yield()\" can only be used inside function blocks.");
return NULL;
}
@@ -526,7 +536,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after 'yield'");
+ _set_error("Expected \"(\" after \"yield\".");
return NULL;
}
@@ -552,7 +562,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
yield->arguments.push_back(object);
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
- _set_error("Expected ',' after first argument of 'yield'");
+ _set_error("Expected \",\" after the first argument of \"yield\".");
return NULL;
}
@@ -578,7 +588,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
yield->arguments.push_back(signal);
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' after second argument of 'yield'");
+ _set_error("Expected \")\" after the second argument of \"yield\".");
return NULL;
}
@@ -592,7 +602,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_SELF) {
if (p_static) {
- _set_error("'self'' not allowed in static function or constant expression");
+ _set_error("\"self\" isn't allowed in a static function or constant expression.");
return NULL;
}
//constant defined by tokenizer
@@ -613,7 +623,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (identifier == StringName()) {
- _set_error("Built-in type constant or static function expected after '.'");
+ _set_error("Built-in type constant or static function expected after \".\".");
return NULL;
}
if (!Variant::has_constant(bi_type, identifier)) {
@@ -668,7 +678,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = cn;
}
- } else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
+ } else if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
//function or constructor
@@ -898,6 +908,10 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_IS && tokenizer->get_token(1) == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
// 'is' operator with built-in type
+ if (!expr) {
+ _set_error("Expected identifier before 'is' operator");
+ return NULL;
+ }
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OperatorNode::OP_IS_BUILTIN;
op->arguments.push_back(expr);
@@ -1136,10 +1150,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
return NULL; //nothing
}
- if (!expr) {
- ERR_EXPLAIN("GDScriptParser bug, couldn't figure out what expression is...");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!expr, NULL, "GDScriptParser bug, couldn't figure out what expression is.");
/******************/
/* Parse Indexing */
@@ -1196,7 +1207,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (_get_completable_identifier(COMPLETION_INDEX, identifier)) {
if (identifier == StringName()) {
- identifier = "@temp"; //so it parses allright
+ identifier = "@temp"; //so it parses alright
}
completion_node = op;
@@ -1388,9 +1399,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
unary = true;
break;
case OperatorNode::OP_NEG:
- priority = 1;
- unary = true;
- break;
case OperatorNode::OP_POS:
priority = 1;
unary = true;
@@ -1766,8 +1774,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
cn->value = v;
cn->datatype = _type_from_variant(v);
return cn;
-
- } else if (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && last_not_constant == 0) {
}
return op; //don't reduce yet
@@ -2211,6 +2217,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())
@@ -2221,7 +2229,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) {
@@ -2236,12 +2244,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));
@@ -2259,6 +2275,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;
@@ -2274,6 +2292,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) {
@@ -2293,7 +2316,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// static type check if possible
if (pattern_type.has_type && to_match_type.has_type) {
if (!_is_type_compatible(to_match_type, pattern_type) && !_is_type_compatible(pattern_type, to_match_type)) {
- _set_error("Pattern type (" + pattern_type.to_string() + ") is not compatible with the type of the value to match (" + to_match_type.to_string() + ").",
+ _set_error("The pattern type (" + pattern_type.to_string() + ") isn't compatible with the type of the value to match (" + to_match_type.to_string() + ").",
p_pattern->line);
return;
}
@@ -2745,24 +2768,24 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
case GDScriptTokenizer::TK_CF_PASS: {
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF) {
- _set_error("Expected ';' or <NewLine>.");
+ _set_error("Expected \";\" or a line break.");
return;
}
_mark_line_as_safe(tokenizer->get_token_line());
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) {
- // Ignore semicolon after 'pass'
+ // Ignore semicolon after 'pass'.
tokenizer->advance();
}
} break;
case GDScriptTokenizer::TK_PR_VAR: {
- //variale declaration and (eventual) initialization
+ // Variable declaration and (eventual) initialization.
tokenizer->advance();
int var_line = tokenizer->get_token_line();
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("Expected identifier for local variable name.");
+ _set_error("Expected an identifier for the local variable name.");
return;
}
StringName n = tokenizer->get_token_literal();
@@ -2770,7 +2793,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
if (current_function) {
for (int i = 0; i < current_function->arguments.size(); i++) {
if (n == current_function->arguments[i]) {
- _set_error("Variable '" + String(n) + "' already defined in the scope (at line: " + itos(current_function->line) + ").");
+ _set_error("Variable \"" + String(n) + "\" already defined in the scope (at line " + itos(current_function->line) + ").");
return;
}
}
@@ -2778,7 +2801,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
BlockNode *check_block = p_block;
while (check_block) {
if (check_block->variables.has(n)) {
- _set_error("Variable '" + String(n) + "' already defined in the scope (at line: " + itos(check_block->variables[n]->line) + ").");
+ _set_error("Variable \"" + String(n) + "\" already defined in the scope (at line " + itos(check_block->variables[n]->line) + ").");
return;
}
check_block = check_block->parent_block;
@@ -2800,7 +2823,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
#endif
tokenizer->advance();
} else if (!_parse_type(lv->datatype)) {
- _set_error("Expected type for variable.");
+ _set_error("Expected a type for the variable.");
return;
}
}
@@ -2820,15 +2843,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
assigned = subexpr;
} else {
- ConstantNode *c = alloc_node<ConstantNode>();
- if (lv->datatype.has_type && lv->datatype.kind == DataType::BUILTIN) {
- Variant::CallError err;
- c->value = Variant::construct(lv->datatype.builtin_type, NULL, 0, err);
- } else {
- c->value = Variant();
- }
- c->line = var_line;
- assigned = c;
+ assigned = _get_default_value_for_type(lv->datatype, var_line);
}
lv->assign = assigned;
//must be added later, to avoid self-referencing.
@@ -2849,7 +2864,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
lv->assign = assigned;
if (!_end_statement()) {
- _set_error("Expected end of statement (var)");
+ _set_error("Expected end of statement (\"var\").");
return;
}
@@ -2878,7 +2893,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_if->body);
if (!_enter_indent_block(cf_if->body)) {
- _set_error("Expected indented block after 'if'");
+ _set_error("Expected an indented block after \"if\".");
p_block->end_line = tokenizer->get_token_line();
return;
}
@@ -2908,7 +2923,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
if (tab_level.back()->get() > indent_level) {
- _set_error("Invalid indent");
+ _set_error("Invalid indentation.");
return;
}
@@ -2939,7 +2954,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_if->body);
if (!_enter_indent_block(cf_if->body)) {
- _set_error("Expected indented block after 'elif'");
+ _set_error("Expected an indented block after \"elif\".");
p_block->end_line = tokenizer->get_token_line();
return;
}
@@ -2955,7 +2970,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELSE) {
if (tab_level.back()->get() > indent_level) {
- _set_error("Invalid indent");
+ _set_error("Invalid indentation.");
return;
}
@@ -2965,7 +2980,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_if->body_else);
if (!_enter_indent_block(cf_if->body_else)) {
- _set_error("Expected indented block after 'else'");
+ _set_error("Expected an indented block after \"else\".");
p_block->end_line = tokenizer->get_token_line();
return;
}
@@ -3010,7 +3025,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_while->body);
if (!_enter_indent_block(cf_while->body)) {
- _set_error("Expected indented block after 'while'");
+ _set_error("Expected an indented block after \"while\".");
p_block->end_line = tokenizer->get_token_line();
return;
}
@@ -3029,7 +3044,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("identifier expected after 'for'");
+ _set_error("Identifier expected after \"for\".");
}
IdentifierNode *id = alloc_node<IdentifierNode>();
@@ -3038,7 +3053,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_IN) {
- _set_error("'in' expected after identifier");
+ _set_error("\"in\" expected after identifier.");
return;
}
@@ -3128,7 +3143,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->sub_blocks.push_back(cf_for->body);
if (!_enter_indent_block(cf_for->body)) {
- _set_error("Expected indented block after 'for'");
+ _set_error("Expected indented block after \"for\".");
p_block->end_line = tokenizer->get_token_line();
return;
}
@@ -3155,23 +3170,25 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} break;
case GDScriptTokenizer::TK_CF_CONTINUE: {
+ _mark_line_as_safe(tokenizer->get_token_line());
tokenizer->advance();
ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>();
cf_continue->cf_type = ControlFlowNode::CF_CONTINUE;
p_block->statements.push_back(cf_continue);
if (!_end_statement()) {
- _set_error("Expected end of statement (continue)");
+ _set_error("Expected end of statement (\"continue\").");
return;
}
} break;
case GDScriptTokenizer::TK_CF_BREAK: {
+ _mark_line_as_safe(tokenizer->get_token_line());
tokenizer->advance();
ControlFlowNode *cf_break = alloc_node<ControlFlowNode>();
cf_break->cf_type = ControlFlowNode::CF_BREAK;
p_block->statements.push_back(cf_break);
if (!_end_statement()) {
- _set_error("Expected end of statement (break)");
+ _set_error("Expected end of statement (\"break\").");
return;
}
} break;
@@ -3225,7 +3242,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
match_node->val_to_match = val_to_match;
if (!_enter_indent_block()) {
- _set_error("Expected indented pattern matching block after 'match'");
+ _set_error("Expected indented pattern matching block after \"match\".");
return;
}
@@ -3252,19 +3269,40 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
case GDScriptTokenizer::TK_PR_ASSERT: {
tokenizer->advance();
- Node *condition = _parse_and_reduce_expression(p_block, p_static);
- if (!condition) {
- if (_recover_from_completion()) {
- break;
- }
+
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after assert");
return;
}
+
+ tokenizer->advance();
+
+ Vector<Node *> args;
+ const bool result = _parse_arguments(p_block, args, p_static);
+ if (!result) {
+ return;
+ }
+
+ if (args.empty() || args.size() > 2) {
+ _set_error("Wrong number of arguments, expected 1 or 2");
+ return;
+ }
+
AssertNode *an = alloc_node<AssertNode>();
- an->condition = condition;
+ an->condition = _reduce_expression(args[0], p_static);
+
+ if (args.size() == 2) {
+ an->message = _reduce_expression(args[1], p_static);
+ } else {
+ ConstantNode *message_node = alloc_node<ConstantNode>();
+ message_node->value = String();
+ an->message = message_node;
+ }
+
p_block->statements.push_back(an);
if (!_end_statement()) {
- _set_error("Expected end of statement after assert.");
+ _set_error("Expected end of statement after \"assert\".");
return;
}
} break;
@@ -3275,7 +3313,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
p_block->statements.push_back(bn);
if (!_end_statement()) {
- _set_error("Expected end of statement after breakpoint.");
+ _set_error("Expected end of statement after \"breakpoint\".");
return;
}
} break;
@@ -3307,7 +3345,7 @@ bool GDScriptParser::_parse_newline() {
int current_indent = tab_level.back()->get();
if (indent > current_indent) {
- _set_error("Unexpected indent.");
+ _set_error("Unexpected indentation.");
return false;
}
@@ -3317,7 +3355,7 @@ bool GDScriptParser::_parse_newline() {
//exit block
if (tab_level.size() == 1) {
- _set_error("Invalid indent. BUG?");
+ _set_error("Invalid indentation. Bug?");
return false;
}
@@ -3344,13 +3382,13 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
if (p_class->extends_used) {
- _set_error("'extends' already used for this class.");
+ _set_error("\"extends\" can only be present once per script.");
return;
}
- if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty() || p_class->classname_used) {
+ if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty()) {
- _set_error("'extends' must be used before anything else.");
+ _set_error("\"extends\" must be used before anything else.");
return;
}
@@ -3370,7 +3408,7 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
Variant constant = tokenizer->get_token_constant();
if (constant.get_type() != Variant::STRING) {
- _set_error("'extends' constant must be a string.");
+ _set_error("\"extends\" constant must be a string.");
return;
}
@@ -3405,7 +3443,7 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
default: {
- _set_error("Invalid 'extends' syntax, expected string constant (path) and/or identifier (parent class).");
+ _set_error("Invalid \"extends\" syntax, expected string constant (path) and/or identifier (parent class).");
return;
}
}
@@ -3465,28 +3503,29 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (error_set)
return;
if (!_end_statement()) {
- _set_error("Expected end of statement after extends");
+ _set_error("Expected end of statement after \"extends\".");
return;
}
} break;
case GDScriptTokenizer::TK_PR_CLASS_NAME: {
+ _mark_line_as_safe(tokenizer->get_token_line());
if (p_class->owner) {
- _set_error("'class_name' is only valid for the main class namespace.");
+ _set_error("\"class_name\" is only valid for the main class namespace.");
return;
}
if (self_path.begins_with("res://") && self_path.find("::") != -1) {
- _set_error("'class_name' not allowed in built-in scripts.");
+ _set_error("\"class_name\" isn't allowed in built-in scripts.");
return;
}
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
- _set_error("'class_name' syntax: 'class_name <UniqueName>'");
+ _set_error("\"class_name\" syntax: \"class_name <UniqueName>\"");
return;
}
if (p_class->classname_used) {
- _set_error("'class_name' already used for this class.");
+ _set_error("\"class_name\" can only be present once per script.");
return;
}
@@ -3495,12 +3534,21 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->name = tokenizer->get_token_identifier(1);
if (self_path != String() && ScriptServer::is_global_class(p_class->name) && ScriptServer::get_global_class_path(p_class->name) != self_path) {
- _set_error("Unique global class '" + p_class->name + "' already exists at path: " + ScriptServer::get_global_class_path(p_class->name));
+ _set_error("Unique global class \"" + p_class->name + "\" already exists at path: " + ScriptServer::get_global_class_path(p_class->name));
return;
}
if (ClassDB::class_exists(p_class->name)) {
- _set_error("Class '" + p_class->name + "' shadows a native class.");
+ _set_error("The class \"" + p_class->name + "\" shadows a native class.");
+ return;
+ }
+
+ if (p_class->classname_used && ProjectSettings::get_singleton()->has_setting("autoload/" + p_class->name)) {
+ const String autoload_path = ProjectSettings::get_singleton()->get_setting("autoload/" + p_class->name);
+ if (autoload_path.begins_with("*")) {
+ // It's a singleton, and not just a regular AutoLoad script.
+ _set_error("The class \"" + p_class->name + "\" conflicts with the AutoLoad singleton of the same name, and is therefore redundant. Remove the class_name declaration to fix this error.");
+ }
return;
}
@@ -3527,12 +3575,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
} else {
- _set_error("Optional parameter after 'class_name' must be a string constant file path to an icon.");
+ _set_error("The optional parameter after \"class_name\" must be a string constant file path to an icon.");
return;
}
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
- _set_error("Class icon must be separated by a comma.");
+ _set_error("The class icon must be separated by a comma.");
return;
}
@@ -3541,7 +3589,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (p_class->tool) {
- _set_error("tool used more than once");
+ _set_error("The \"tool\" keyword can only be present once per script.");
return;
}
@@ -3556,7 +3604,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
- _set_error("'class' syntax: 'class <Name>:' or 'class <Name> extends <BaseClass>:'");
+ _set_error("\"class\" syntax: \"class <Name>:\" or \"class <Name> extends <BaseClass>:\"");
return;
}
name = tokenizer->get_token_identifier(1);
@@ -3564,23 +3612,23 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
// Check if name is shadowing something else
if (ClassDB::class_exists(name) || ClassDB::class_exists("_" + name.operator String())) {
- _set_error("Class '" + String(name) + "' shadows a native class.");
+ _set_error("The class \"" + String(name) + "\" shadows a native class.");
return;
}
if (ScriptServer::is_global_class(name)) {
- _set_error("Can't override name of unique global class '" + name + "' already exists at path: " + ScriptServer::get_global_class_path(p_class->name));
+ _set_error("Can't override name of the unique global class \"" + name + "\". It already exists at: " + ScriptServer::get_global_class_path(p_class->name));
return;
}
ClassNode *outer_class = p_class;
while (outer_class) {
for (int i = 0; i < outer_class->subclasses.size(); i++) {
if (outer_class->subclasses[i]->name == name) {
- _set_error("Another class named '" + String(name) + "' already exists in this scope (at line " + itos(outer_class->subclasses[i]->line) + ").");
+ _set_error("Another class named \"" + String(name) + "\" already exists in this scope (at line " + itos(outer_class->subclasses[i]->line) + ").");
return;
}
}
if (outer_class->constant_expressions.has(name)) {
- _set_error("A constant named '" + String(name) + "' already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
+ _set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
return;
}
@@ -3624,7 +3672,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- _set_error("Expected 'func'.");
+ _set_error("Expected \"func\".");
return;
}
@@ -3648,18 +3696,18 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (name == StringName()) {
- _set_error("Expected identifier after 'func' (syntax: 'func <identifier>([arguments]):' ).");
+ _set_error("Expected an identifier after \"func\" (syntax: \"func <identifier>([arguments]):\").");
return;
}
for (int i = 0; i < p_class->functions.size(); i++) {
if (p_class->functions[i]->name == name) {
- _set_error("Function '" + String(name) + "' already exists in this class (at line: " + itos(p_class->functions[i]->line) + ").");
+ _set_error("The function \"" + String(name) + "\" already exists in this class (at line " + itos(p_class->functions[i]->line) + ").");
}
}
for (int i = 0; i < p_class->static_functions.size(); i++) {
if (p_class->static_functions[i]->name == name) {
- _set_error("Function '" + String(name) + "' already exists in this class (at line: " + itos(p_class->static_functions[i]->line) + ").");
+ _set_error("The function \"" + String(name) + "\" already exists in this class (at line " + itos(p_class->static_functions[i]->line) + ").");
}
}
@@ -3681,7 +3729,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after identifier (syntax: 'func <identifier>([arguments]):' ).");
+ _set_error("Expected \"(\" after the identifier (syntax: \"func <identifier>([arguments]):\" ).");
return;
}
@@ -3713,7 +3761,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("Expected identifier for argument.");
+ _set_error("Expected an identifier for an argument.");
return;
}
@@ -3731,7 +3779,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
argtype.infer_type = true;
tokenizer->advance();
} else if (!_parse_type(argtype)) {
- _set_error("Expected type for argument.");
+ _set_error("Expected a type for an argument.");
return;
}
}
@@ -3780,7 +3828,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ',' or ')'.");
+ _set_error("Expected \",\" or \")\".");
return;
}
@@ -3809,7 +3857,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (name == "_init") {
if (_static) {
- _set_error("Constructor cannot be static.");
+ _set_error("The constructor cannot be static.");
return;
}
@@ -3826,7 +3874,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
- _set_error("expected '(' for parent constructor arguments.");
+ _set_error("Expected \"(\" for parent constructor arguments.");
return;
}
tokenizer->advance();
@@ -3846,7 +3894,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ',' or ')'.");
+ _set_error("Expected \",\" or \")\".");
return;
}
@@ -3871,7 +3919,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) {
if (!_parse_type(return_type, true)) {
- _set_error("Expected return type for function.");
+ _set_error("Expected a return type for the function.");
return;
}
}
@@ -3901,7 +3949,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal()) {
- _set_error("Expected identifier after 'signal'.");
+ _set_error("Expected an identifier after \"signal\".");
return;
}
@@ -3925,7 +3973,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("Expected identifier in signal argument.");
+ _set_error("Expected an identifier in a \"signal\" argument.");
return;
}
@@ -3939,7 +3987,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
tokenizer->advance();
} else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ',' or ')' after signal parameter identifier.");
+ _set_error("Expected \",\" or \")\" after a \"signal\" parameter identifier.");
return;
}
}
@@ -3948,7 +3996,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->_signals.push_back(sig);
if (!_end_statement()) {
- _set_error("Expected end of statement (signal)");
+ _set_error("Expected end of statement (\"signal\").");
return;
}
} break;
@@ -4003,12 +4051,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- ERR_EXPLAIN("Exporting bit flags hint requires string constants.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("Exporting bit flags hint requires string constants.");
break;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
- _set_error("Expected ',' in bit flags hint.");
+ _set_error("Expected \",\" in the bit flags hint.");
return;
}
@@ -4020,7 +4067,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
current_export = PropertyInfo();
- _set_error("Expected a string constant in named bit flags hint.");
+ _set_error("Expected a string constant in the named bit flags hint.");
return;
}
@@ -4038,7 +4085,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
- _set_error("Expected ')' or ',' in named bit flags hint.");
+ _set_error("Expected \")\" or \",\" in the named bit flags hint.");
return;
}
tokenizer->advance();
@@ -4051,7 +4098,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in layers 2D render hint.");
+ _set_error("Expected \")\" in the layers 2D render hint.");
return;
}
current_export.hint = PROPERTY_HINT_LAYERS_2D_RENDER;
@@ -4062,7 +4109,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in layers 2D physics hint.");
+ _set_error("Expected \")\" in the layers 2D physics hint.");
return;
}
current_export.hint = PROPERTY_HINT_LAYERS_2D_PHYSICS;
@@ -4073,7 +4120,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in layers 3D render hint.");
+ _set_error("Expected \")\" in the layers 3D render hint.");
return;
}
current_export.hint = PROPERTY_HINT_LAYERS_3D_RENDER;
@@ -4084,7 +4131,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in layers 3D physics hint.");
+ _set_error("Expected \")\" in the layers 3D physics hint.");
return;
}
current_export.hint = PROPERTY_HINT_LAYERS_3D_PHYSICS;
@@ -4100,7 +4147,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
current_export = PropertyInfo();
- _set_error("Expected a string constant in enumeration hint.");
+ _set_error("Expected a string constant in the enumeration hint.");
return;
}
@@ -4118,7 +4165,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
- _set_error("Expected ')' or ',' in enumeration hint.");
+ _set_error("Expected \")\" or \",\" in the enumeration hint.");
return;
}
@@ -4136,7 +4183,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint = PROPERTY_HINT_EXP_EASING;
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in hint.");
+ _set_error("Expected \")\" in the hint.");
return;
}
break;
@@ -4151,7 +4198,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
- _set_error("Expected ')' or ',' in exponential range hint.");
+ _set_error("Expected \")\" or \",\" in the exponential range hint.");
return;
}
tokenizer->advance();
@@ -4167,7 +4214,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
current_export = PropertyInfo();
- _set_error("Expected a range in numeric hint.");
+ _set_error("Expected a range in the numeric hint.");
return;
}
@@ -4182,7 +4229,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
- _set_error("Expected ',' or ')' in numeric range hint.");
+ _set_error("Expected \",\" or \")\" in the numeric range hint.");
return;
}
@@ -4197,7 +4244,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
current_export = PropertyInfo();
- _set_error("Expected a number as upper bound in numeric range hint.");
+ _set_error("Expected a number as upper bound in the numeric range hint.");
return;
}
@@ -4210,7 +4257,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
- _set_error("Expected ',' or ')' in numeric range hint.");
+ _set_error("Expected \",\" or \")\" in the numeric range hint.");
return;
}
@@ -4224,7 +4271,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
current_export = PropertyInfo();
- _set_error("Expected a number as step in numeric range hint.");
+ _set_error("Expected a number as step in the numeric range hint.");
return;
}
@@ -4243,7 +4290,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
current_export = PropertyInfo();
- _set_error("Expected a string constant in enumeration hint.");
+ _set_error("Expected a string constant in the enumeration hint.");
return;
}
@@ -4260,7 +4307,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
- _set_error("Expected ')' or ',' in enumeration hint.");
+ _set_error("Expected \")\" or \",\" in the enumeration hint.");
return;
}
tokenizer->advance();
@@ -4280,7 +4327,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) {
- _set_error("Expected 'GLOBAL' after comma in directory hint.");
+ _set_error("Expected \"GLOBAL\" after comma in the directory hint.");
return;
}
if (!p_class->tool) {
@@ -4291,11 +4338,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in hint.");
+ _set_error("Expected \")\" in the hint.");
return;
}
} else {
- _set_error("Expected ')' or ',' in hint.");
+ _set_error("Expected \")\" or \",\" in the hint.");
return;
}
break;
@@ -4324,7 +4371,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA)
tokenizer->advance();
else {
- _set_error("Expected ')' or ',' in hint.");
+ _set_error("Expected \")\" or \",\" in the hint.");
return;
}
}
@@ -4332,9 +4379,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE)
- _set_error("Expected string constant with filter");
+ _set_error("Expected string constant with filter.");
else
- _set_error("Expected 'GLOBAL' or string constant with filter");
+ _set_error("Expected \"GLOBAL\" or string constant with filter.");
return;
}
current_export.hint_string = tokenizer->get_token_constant();
@@ -4342,7 +4389,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in hint.");
+ _set_error("Expected \")\" in the hint.");
return;
}
break;
@@ -4353,7 +4400,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint = PROPERTY_HINT_MULTILINE_TEXT;
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- _set_error("Expected ')' in hint.");
+ _set_error("Expected \")\" in the hint.");
return;
}
break;
@@ -4364,7 +4411,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) {
current_export = PropertyInfo();
- _set_error("Color type hint expects RGB or RGBA as hints");
+ _set_error("Color type hint expects RGB or RGBA as hints.");
return;
}
@@ -4375,7 +4422,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//none
} else {
current_export = PropertyInfo();
- _set_error("Color type hint expects RGB or RGBA as hints");
+ _set_error("Color type hint expects RGB or RGBA as hints.");
return;
}
tokenizer->advance();
@@ -4384,7 +4431,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
default: {
current_export = PropertyInfo();
- _set_error("Type '" + Variant::get_type_name(type) + "' can't take hints.");
+ _set_error("Type \"" + Variant::get_type_name(type) + "\" can't take hints.");
return;
} break;
}
@@ -4422,7 +4469,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} else {
current_export = PropertyInfo();
- _set_error("Export hint not a resource type.");
+ _set_error("The export hint isn't a resource type.");
}
} else if (constant.get_type() == Variant::DICTIONARY) {
// Enumeration
@@ -4436,7 +4483,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
} else {
current_export = PropertyInfo();
- _set_error("Expected 'FLAGS' after comma.");
+ _set_error("Expected \"FLAGS\" after comma.");
}
}
@@ -4473,7 +4520,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
current_export = PropertyInfo();
- _set_error("Expected ')' or ',' after export hint.");
+ _set_error("Expected \")\" or \",\" after the export hint.");
return;
}
@@ -4493,7 +4540,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) {
current_export = PropertyInfo();
- _set_error("Expected 'var', 'onready', 'remote', 'master', 'puppet', 'sync', 'remotesync', 'mastersync', 'puppetsync'.");
+ _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"sync\", \"remotesync\", \"mastersync\", \"puppetsync\".");
return;
}
@@ -4504,7 +4551,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
return;
}
@@ -4516,13 +4563,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (current_export.type) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
return;
}
} else {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
}
@@ -4536,13 +4583,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (current_export.type) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
return;
}
} else {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
}
@@ -4561,13 +4608,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (current_export.type) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
return;
}
} else {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
}
@@ -4582,9 +4629,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
if (current_export.type)
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
else
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
@@ -4597,9 +4644,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
if (current_export.type)
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
else
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
@@ -4612,9 +4659,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
if (current_export.type)
- _set_error("Expected 'var'.");
+ _set_error("Expected \"var\".");
else
- _set_error("Expected 'var' or 'func'.");
+ _set_error("Expected \"var\" or \"func\".");
return;
}
@@ -4637,7 +4684,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("Expected identifier for member variable name.");
+ _set_error("Expected an identifier for the member variable name.");
return;
}
@@ -4653,14 +4700,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#endif
if (current_class->constant_expressions.has(member.identifier)) {
- _set_error("A constant named '" + String(member.identifier) + "' already exists in this class (at line: " +
+ _set_error("A constant named \"" + String(member.identifier) + "\" already exists in this class (at line: " +
itos(current_class->constant_expressions[member.identifier].expression->line) + ").");
return;
}
for (int i = 0; i < current_class->variables.size(); i++) {
if (current_class->variables[i].identifier == member.identifier) {
- _set_error("Variable '" + String(member.identifier) + "' already exists in this class (at line: " +
+ _set_error("Variable \"" + String(member.identifier) + "\" already exists in this class (at line: " +
itos(current_class->variables[i].line) + ").");
return;
}
@@ -4668,7 +4715,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
for (int i = 0; i < current_class->subclasses.size(); i++) {
if (current_class->subclasses[i]->name == member.identifier) {
- _set_error("A class named '" + String(member.identifier) + "' already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
+ _set_error("A class named \"" + String(member.identifier) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
return;
}
}
@@ -4698,7 +4745,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#endif
tokenizer->advance();
} else if (!_parse_type(member.data_type)) {
- _set_error("Expected type for class variable.");
+ _set_error("Expected a type for the class variable.");
return;
}
}
@@ -4726,7 +4773,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
IdentifierNode *id = static_cast<IdentifierNode *>(op->arguments[1]);
if (id->name == "get_node") {
- _set_error("Use 'onready var " + String(member.identifier) + " = get_node(..)' instead");
+ _set_error("Use \"onready var " + String(member.identifier) + " = get_node(...)\" instead.");
return;
}
}
@@ -4754,7 +4801,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
Object *obj = cn->value;
Resource *res = Object::cast_to<Resource>(obj);
if (res == NULL) {
- _set_error("Exported constant not a type or resource.");
+ _set_error("The exported constant isn't a type or resource.");
return;
}
member._export.hint = PROPERTY_HINT_RESOURCE_TYPE;
@@ -4772,7 +4819,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
const Variant *args = &cn->value;
cn->value = Variant::construct(member._export.type, &args, 1, err);
} else {
- _set_error("Cannot convert the provided value to the export type.");
+ _set_error("Can't convert the provided value to the export type.");
return;
}
}
@@ -4811,35 +4858,29 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- Variant::Type initial_type = member.data_type.has_type ? member.data_type.builtin_type : member._export.type;
-
- if (initial_type != Variant::NIL && initial_type != Variant::OBJECT) {
- IdentifierNode *id = alloc_node<IdentifierNode>();
- id->name = member.identifier;
+ Node *expr;
- Node *expr;
+ if (member.data_type.has_type) {
+ expr = _get_default_value_for_type(member.data_type);
+ } else {
+ DataType exported_type;
+ exported_type.has_type = true;
+ exported_type.kind = DataType::BUILTIN;
+ exported_type.builtin_type = member._export.type;
+ expr = _get_default_value_for_type(exported_type);
+ }
- // Make sure arrays and dictionaries are not shared
- if (initial_type == Variant::ARRAY) {
- expr = alloc_node<ArrayNode>();
- } else if (initial_type == Variant::DICTIONARY) {
- expr = alloc_node<DictionaryNode>();
- } else {
- ConstantNode *cn = alloc_node<ConstantNode>();
- Variant::CallError ce2;
- cn->value = Variant::construct(initial_type, NULL, 0, ce2);
- expr = cn;
- }
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name = member.identifier;
- OperatorNode *op = alloc_node<OperatorNode>();
- op->op = OperatorNode::OP_INIT_ASSIGN;
- op->arguments.push_back(id);
- op->arguments.push_back(expr);
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OperatorNode::OP_INIT_ASSIGN;
+ op->arguments.push_back(id);
+ op->arguments.push_back(expr);
- p_class->initializer->statements.push_back(op);
+ p_class->initializer->statements.push_back(op);
- member.initial_assignment = op;
- }
+ member.initial_assignment = op;
}
if (autoexport && member.data_type.has_type) {
@@ -4870,7 +4911,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
//just comma means using only getter
if (!tokenizer->is_token_literal()) {
- _set_error("Expected identifier for setter function after 'setget'.");
+ _set_error("Expected an identifier for the setter function after \"setget\".");
}
member.setter = tokenizer->get_token_literal();
@@ -4883,7 +4924,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal()) {
- _set_error("Expected identifier for getter function after ','.");
+ _set_error("Expected an identifier for the getter function after \",\".");
}
member.getter = tokenizer->get_token_literal();
@@ -4894,7 +4935,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->variables.push_back(member);
if (!_end_statement()) {
- _set_error("Expected end of statement (continue)");
+ _set_error("Expected end of statement (\"continue\").");
return;
}
} break;
@@ -4906,7 +4947,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal(0, true)) {
- _set_error("Expected name (identifier) for constant.");
+ _set_error("Expected an identifier for the constant.");
return;
}
@@ -4914,14 +4955,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
int line = tokenizer->get_token_line();
if (current_class->constant_expressions.has(const_id)) {
- _set_error("Constant '" + String(const_id) + "' already exists in this class (at line: " +
+ _set_error("Constant \"" + String(const_id) + "\" already exists in this class (at line " +
itos(current_class->constant_expressions[const_id].expression->line) + ").");
return;
}
for (int i = 0; i < current_class->variables.size(); i++) {
if (current_class->variables[i].identifier == const_id) {
- _set_error("A variable named '" + String(const_id) + "' already exists in this class (at line: " +
+ _set_error("A variable named \"" + String(const_id) + "\" already exists in this class (at line " +
itos(current_class->variables[i].line) + ").");
return;
}
@@ -4929,7 +4970,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
for (int i = 0; i < current_class->subclasses.size(); i++) {
if (current_class->subclasses[i]->name == const_id) {
- _set_error("A class named '" + String(const_id) + "' already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
+ _set_error("A class named \"" + String(const_id) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
return;
}
}
@@ -4944,13 +4985,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#endif
tokenizer->advance();
} else if (!_parse_type(constant.type)) {
- _set_error("Expected type for class constant.");
+ _set_error("Expected a type for the class constant.");
return;
}
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) {
- _set_error("Constant expects assignment.");
+ _set_error("Constants must be assigned immediately.");
return;
}
@@ -4965,7 +5006,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (subexpr->type != Node::TYPE_CONSTANT) {
- _set_error("Expected constant expression", line);
+ _set_error("Expected a constant expression.", line);
return;
}
subexpr->line = line;
@@ -4974,7 +5015,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->constant_expressions.insert(const_id, constant);
if (!_end_statement()) {
- _set_error("Expected end of statement (constant)", line);
+ _set_error("Expected end of statement (constant).", line);
return;
}
@@ -4991,14 +5032,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
enum_name = tokenizer->get_token_literal();
if (current_class->constant_expressions.has(enum_name)) {
- _set_error("A constant named '" + String(enum_name) + "' already exists in this class (at line: " +
+ _set_error("A constant named \"" + String(enum_name) + "\" already exists in this class (at line " +
itos(current_class->constant_expressions[enum_name].expression->line) + ").");
return;
}
for (int i = 0; i < current_class->variables.size(); i++) {
if (current_class->variables[i].identifier == enum_name) {
- _set_error("A variable named '" + String(enum_name) + "' already exists in this class (at line: " +
+ _set_error("A variable named \"" + String(enum_name) + "\" already exists in this class (at line " +
itos(current_class->variables[i].line) + ").");
return;
}
@@ -5006,7 +5047,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
for (int i = 0; i < current_class->subclasses.size(); i++) {
if (current_class->subclasses[i]->name == enum_name) {
- _set_error("A class named '" + String(enum_name) + "' already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
+ _set_error("A class named \"" + String(enum_name) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
return;
}
}
@@ -5014,7 +5055,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CURLY_BRACKET_OPEN) {
- _set_error("Expected '{' in enum declaration");
+ _set_error("Expected \"{\" in the enum declaration.");
return;
}
tokenizer->advance();
@@ -5032,7 +5073,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
_set_error("Unexpected end of file.");
} else {
- _set_error(String("Unexpected ") + GDScriptTokenizer::get_token_name(tokenizer->get_token()) + ", expected identifier");
+ _set_error(String("Unexpected ") + GDScriptTokenizer::get_token_name(tokenizer->get_token()) + ", expected an identifier.");
}
return;
@@ -5055,14 +5096,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (subexpr->type != Node::TYPE_CONSTANT) {
- _set_error("Expected constant expression");
+ _set_error("Expected a constant expression.");
return;
}
enum_value_expr = static_cast<ConstantNode *>(subexpr);
if (enum_value_expr->value.get_type() != Variant::INT) {
- _set_error("Expected an int value for enum");
+ _set_error("Expected an integer value for \"enum\".");
return;
}
@@ -5078,7 +5119,7 @@ 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");
+ _set_error("Unexpected identifier.");
return;
}
@@ -5086,14 +5127,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
enum_dict[const_id] = enum_value_expr->value;
} else {
if (current_class->constant_expressions.has(const_id)) {
- _set_error("A constant named '" + String(const_id) + "' already exists in this class (at line: " +
+ _set_error("A constant named \"" + String(const_id) + "\" already exists in this class (at line " +
itos(current_class->constant_expressions[const_id].expression->line) + ").");
return;
}
for (int i = 0; i < current_class->variables.size(); i++) {
if (current_class->variables[i].identifier == const_id) {
- _set_error("A variable named '" + String(const_id) + "' already exists in this class (at line: " +
+ _set_error("A variable named \"" + String(const_id) + "\" already exists in this class (at line " +
itos(current_class->variables[i].line) + ").");
return;
}
@@ -5101,7 +5142,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
for (int i = 0; i < current_class->subclasses.size(); i++) {
if (current_class->subclasses[i]->name == const_id) {
- _set_error("A class named '" + String(const_id) + "' already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
+ _set_error("A class named \"" + String(const_id) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
return;
}
}
@@ -5128,7 +5169,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (!_end_statement()) {
- _set_error("Expected end of statement (enum)");
+ _set_error("Expected end of statement (\"enum\").");
return;
}
@@ -5174,19 +5215,19 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
String base = base_path;
if (base == "" || base.is_rel_path()) {
- _set_error("Could not resolve relative path for parent class: " + path, p_class->line);
+ _set_error("Couldn't resolve relative path for the parent class: " + path, p_class->line);
return;
}
path = base.plus_file(path).simplify_path();
}
script = ResourceLoader::load(path);
if (script.is_null()) {
- _set_error("Could not load base class: " + path, p_class->line);
+ _set_error("Couldn't load the base class: " + path, p_class->line);
return;
}
if (!script->is_valid()) {
- _set_error("Script not fully loaded (cyclic preload?): " + path, p_class->line);
+ _set_error("Script isn't fully loaded (cyclic preload?): " + path, p_class->line);
return;
}
@@ -5201,7 +5242,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
script = subclass;
} else {
- _set_error("Could not find subclass: " + sub, p_class->line);
+ _set_error("Couldn't find the subclass: " + sub, p_class->line);
return;
}
}
@@ -5223,10 +5264,35 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
if (ScriptServer::is_global_class(base)) {
base_script = ResourceLoader::load(ScriptServer::get_global_class_path(base));
if (!base_script.is_valid()) {
- _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic dependency).", p_class->line);
+ _set_error("The class \"" + base + "\" couldn't be fully loaded (script error or cyclic dependency).", p_class->line);
return;
}
p = NULL;
+ } else {
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ String s = E->get().name;
+ if (!s.begins_with("autoload/")) {
+ continue;
+ }
+ String name = s.get_slice("/", 1);
+ if (name == base) {
+ String singleton_path = ProjectSettings::get_singleton()->get(s);
+ if (singleton_path.begins_with("*")) {
+ singleton_path = singleton_path.right(1);
+ }
+ if (!singleton_path.begins_with("res://")) {
+ singleton_path = "res://" + singleton_path;
+ }
+ base_script = ResourceLoader::load(singleton_path);
+ if (!base_script.is_valid()) {
+ _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line);
+ return;
+ }
+ p = NULL;
+ }
+ }
}
while (p) {
@@ -5264,13 +5330,13 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
if (p->constant_expressions.has(base)) {
if (p->constant_expressions[base].expression->type != Node::TYPE_CONSTANT) {
- _set_error("Could not resolve constant '" + base + "'.", p_class->line);
+ _set_error("Couldn't resolve the constant \"" + base + "\".", p_class->line);
return;
}
const ConstantNode *cn = static_cast<const ConstantNode *>(p->constant_expressions[base].expression);
base_script = cn->value;
if (base_script.is_null()) {
- _set_error("Constant is not a class: " + base, p_class->line);
+ _set_error("Constant isn't a class: " + base, p_class->line);
return;
}
break;
@@ -5297,13 +5363,13 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
Ref<GDScript> new_base_class = base_script->get_constants()[subclass];
if (new_base_class.is_null()) {
- _set_error("Constant is not a class: " + ident, p_class->line);
+ _set_error("Constant isn't a class: " + ident, p_class->line);
return;
}
find_subclass = new_base_class;
} else {
- _set_error("Could not find subclass: " + ident, p_class->line);
+ _set_error("Couldn't find the subclass: " + ident, p_class->line);
return;
}
}
@@ -5314,13 +5380,13 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
if (p_class->extends_class.size() > 1) {
- _set_error("Invalid inheritance (unknown class + subclasses)", p_class->line);
+ _set_error("Invalid inheritance (unknown class + subclasses).", p_class->line);
return;
}
//if not found, try engine classes
if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {
- _set_error("Unknown class: '" + base + "'", p_class->line);
+ _set_error("Unknown class: \"" + base + "\"", p_class->line);
return;
}
@@ -5342,7 +5408,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
p_class->base_type.kind = DataType::NATIVE;
p_class->base_type.native_type = native;
} else {
- _set_error("Could not determine inheritance", p_class->line);
+ _set_error("Couldn't determine inheritance.", p_class->line);
return;
}
@@ -5487,7 +5553,7 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) {
switch (tokenizer->get_token()) {
case GDScriptTokenizer::TK_PERIOD: {
if (!can_index) {
- _set_error("Unexpected '.'.");
+ _set_error("Unexpected \".\".");
return false;
}
can_index = false;
@@ -5518,7 +5584,7 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) {
}
if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PERIOD) {
- _set_error("Expected subclass identifier.");
+ _set_error("Expected a subclass identifier.");
return false;
}
@@ -5556,7 +5622,7 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
Ref<GDScript> gds = script;
if (gds.is_valid()) {
if (!gds->is_valid()) {
- _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic dependency).", p_line);
+ _set_error("The class \"" + id + "\" couldn't be fully loaded (script error or cyclic dependency).", p_line);
return DataType();
}
result.kind = DataType::GDSCRIPT;
@@ -5565,15 +5631,55 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
result.kind = DataType::SCRIPT;
result.script_type = script;
} else {
- _set_error("Class '" + id + "' was found in global scope but its script could not be loaded.", p_line);
+ _set_error("The class \"" + id + "\" was found in global scope, but its script couldn't be loaded.", p_line);
return DataType();
}
}
name_part++;
continue;
- } else {
- p = current_class;
}
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+ String singleton_path;
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ String s = E->get().name;
+ if (!s.begins_with("autoload/")) {
+ continue;
+ }
+ String name = s.get_slice("/", 1);
+ if (name == id) {
+ singleton_path = ProjectSettings::get_singleton()->get(s);
+ if (singleton_path.begins_with("*")) {
+ singleton_path = singleton_path.right(1);
+ }
+ if (!singleton_path.begins_with("res://")) {
+ singleton_path = "res://" + singleton_path;
+ }
+ break;
+ }
+ }
+ if (!singleton_path.empty()) {
+ Ref<Script> script = ResourceLoader::load(singleton_path);
+ Ref<GDScript> gds = script;
+ if (gds.is_valid()) {
+ if (!gds->is_valid()) {
+ _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic inheritance).", p_line);
+ return DataType();
+ }
+ result.kind = DataType::GDSCRIPT;
+ result.script_type = gds;
+ } else if (script.is_valid()) {
+ result.kind = DataType::SCRIPT;
+ result.script_type = script;
+ } else {
+ _set_error("Couldn't fully load singleton script '" + id + "' (possible cyclic reference or parse error).", p_line);
+ return DataType();
+ }
+ name_part++;
+ continue;
+ }
+
+ p = current_class;
} else if (base_type.kind == DataType::CLASS) {
p = base_type.class_type;
}
@@ -5634,28 +5740,35 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
}
}
- // Still look for class constants in parent script
+ // Still look for class constants in parent scripts
if (!found && (base_type.kind == DataType::GDSCRIPT || base_type.kind == DataType::SCRIPT)) {
Ref<Script> scr = base_type.script_type;
ERR_FAIL_COND_V(scr.is_null(), result);
- Map<StringName, Variant> constants;
- scr->get_constants(&constants);
+ while (scr.is_valid()) {
+ Map<StringName, Variant> constants;
+ scr->get_constants(&constants);
- if (constants.has(id)) {
- Ref<GDScript> gds = constants[id];
+ if (constants.has(id)) {
+ Ref<GDScript> gds = constants[id];
- if (gds.is_valid()) {
- result.kind = DataType::GDSCRIPT;
- result.script_type = gds;
- found = true;
- } else {
- Ref<Script> scr2 = constants[id];
- if (scr2.is_valid()) {
- result.kind = DataType::SCRIPT;
- result.script_type = scr2;
+ if (gds.is_valid()) {
+ result.kind = DataType::GDSCRIPT;
+ result.script_type = gds;
found = true;
+ } else {
+ Ref<Script> scr2 = constants[id];
+ if (scr2.is_valid()) {
+ result.kind = DataType::SCRIPT;
+ result.script_type = scr2;
+ found = true;
+ }
}
}
+ if (found) {
+ break;
+ } else {
+ scr = scr->get_base_script();
+ }
}
}
@@ -5666,8 +5779,8 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
} else {
base = result.to_string();
}
- _set_error("Identifier '" + String(id) + "' is not a valid type (not a script or class), or could not be found on base '" +
- base + "'.",
+ _set_error("The identifier \"" + String(id) + "\" isn't a valid type (not a script or class), or couldn't be found on base \"" +
+ base + "\".",
p_line);
return DataType();
}
@@ -5745,7 +5858,7 @@ GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataTyp
switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
- ERR_EXPLAIN("Uninitialized datatype. Please report a bug.");
+ ERR_PRINT("Uninitialized datatype. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: {
result.kind = DataType::BUILTIN;
@@ -6047,6 +6160,31 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data
return false;
}
+GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType &p_type, int p_line) {
+ Node *result;
+
+ if (p_type.has_type && p_type.kind == DataType::BUILTIN && p_type.builtin_type != Variant::NIL && p_type.builtin_type != Variant::OBJECT) {
+ if (p_type.builtin_type == Variant::ARRAY) {
+ result = alloc_node<ArrayNode>();
+ } else if (p_type.builtin_type == Variant::DICTIONARY) {
+ result = alloc_node<DictionaryNode>();
+ } else {
+ ConstantNode *c = alloc_node<ConstantNode>();
+ Variant::CallError err;
+ c->value = Variant::construct(p_type.builtin_type, NULL, 0, err);
+ result = c;
+ }
+ } else {
+ ConstantNode *c = alloc_node<ConstantNode>();
+ c->value = Variant();
+ result = c;
+ }
+
+ result->line = p_line;
+
+ return result;
+}
+
GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
#ifdef DEBUG_ENABLED
if (p_node->get_datatype().has_type && p_node->type != Node::TYPE_ARRAY && p_node->type != Node::TYPE_DICTIONARY) {
@@ -6131,8 +6269,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
if (!valid) {
- _set_error("Invalid cast. Cannot convert from '" + source_type.to_string() +
- "' to '" + cn->cast_type.to_string() + "'.",
+ _set_error("Invalid cast. Cannot convert from \"" + source_type.to_string() +
+ "\" to \"" + cn->cast_type.to_string() + "\".",
cn->line);
return DataType();
}
@@ -6161,11 +6299,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
DataType signal_type = _reduce_node_type(op->arguments[1]);
// TODO: Check if signal exists when it's a constant
if (base_type.has_type && base_type.kind == DataType::BUILTIN && base_type.builtin_type != Variant::NIL && base_type.builtin_type != Variant::OBJECT) {
- _set_error("First argument of 'yield()' must be an object.", op->line);
+ _set_error("The first argument of \"yield()\" must be an object.", op->line);
return DataType();
}
if (signal_type.has_type && (signal_type.kind != DataType::BUILTIN || signal_type.builtin_type != Variant::STRING)) {
- _set_error("Second argument of 'yield()' must be a string.", op->line);
+ _set_error("The second argument of \"yield()\" must be a string.", op->line);
return DataType();
}
}
@@ -6185,15 +6323,15 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
if (check_types && type_type.has_type) {
if (!type_type.is_meta_type && (type_type.kind != DataType::NATIVE || !ClassDB::is_parent_class(type_type.native_type, "Script"))) {
- _set_error("Invalid 'is' test: right operand is not a type (not a native type nor a script).", op->line);
+ _set_error("Invalid \"is\" test: the right operand isn't a type (neither a native type nor a script).", op->line);
return DataType();
}
type_type.is_meta_type = false; // Test the actual type
if (!_is_type_compatible(type_type, value_type) && !_is_type_compatible(value_type, type_type)) {
if (op->op == OperatorNode::OP_IS) {
- _set_error("A value of type '" + value_type.to_string() + "' will never be an instance of '" + type_type.to_string() + "'.", op->line);
+ _set_error("A value of type \"" + value_type.to_string() + "\" will never be an instance of \"" + type_type.to_string() + "\".", op->line);
} else {
- _set_error("A value of type '" + value_type.to_string() + "' will never be of type '" + type_type.to_string() + "'.", op->line);
+ _set_error("A value of type \"" + value_type.to_string() + "\" will never be of type \"" + type_type.to_string() + "\".", op->line);
}
return DataType();
}
@@ -6221,8 +6359,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _get_operation_type(var_op, argument_type, argument_type, valid);
if (check_types && !valid) {
- _set_error("Invalid operand type ('" + argument_type.to_string() +
- "') to unary operator '" + Variant::get_operator_name(var_op) + "'.",
+ _set_error("Invalid operand type (\"" + argument_type.to_string() +
+ "\") to unary operator \"" + Variant::get_operator_name(var_op) + "\".",
op->line, op->column);
return DataType();
}
@@ -6266,8 +6404,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _get_operation_type(var_op, argument_a_type, argument_b_type, valid);
if (check_types && !valid) {
- _set_error("Invalid operand types ('" + argument_a_type.to_string() + "' and '" +
- argument_b_type.to_string() + "') to operator '" + Variant::get_operator_name(var_op) + "'.",
+ _set_error("Invalid operand types (\"" + argument_a_type.to_string() + "\" and \"" +
+ argument_b_type.to_string() + "\") to operator \"" + Variant::get_operator_name(var_op) + "\".",
op->line, op->column);
return DataType();
}
@@ -6282,7 +6420,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
// Ternary operators
case OperatorNode::OP_TERNARY_IF: {
if (op->arguments.size() != 3) {
- _set_error("Parser bug: ternary operation without 3 arguments");
+ _set_error("Parser bug: ternary operation without 3 arguments.");
ERR_FAIL_V(DataType());
}
@@ -6315,7 +6453,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case OperatorNode::OP_ASSIGN_BIT_XOR:
case OperatorNode::OP_INIT_ASSIGN: {
- _set_error("Assignment inside expression is not allowed (parser bug?).", op->line);
+ _set_error("Assignment inside an expression isn't allowed (parser bug?).", op->line);
return DataType();
} break;
@@ -6351,8 +6489,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
if (valid) {
result = _type_from_variant(res);
} else if (check_types) {
- _set_error("Can't get index '" + String(member_id->name.operator String()) + "' on base '" +
- base_type.to_string() + "'.",
+ _set_error("Can't get index \"" + String(member_id->name.operator String()) + "\" on base \"" +
+ base_type.to_string() + "\".",
op->line);
return DataType();
}
@@ -6444,7 +6582,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
}
if (error) {
- _set_error("Invalid index type (" + index_type.to_string() + ") for base '" + base_type.to_string() + "'.",
+ _set_error("Invalid index type (" + index_type.to_string() + ") for base \"" + base_type.to_string() + "\".",
op->line);
return DataType();
}
@@ -6477,8 +6615,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _type_from_variant(res);
node_type.is_constant = false;
} else if (check_types) {
- _set_error("Can't get index '" + String(cn->value) + "' on base '" +
- base_type.to_string() + "'.",
+ _set_error("Can't get index \"" + String(cn->value) + "\" on base \"" +
+ base_type.to_string() + "\".",
op->line);
return DataType();
}
@@ -6488,11 +6626,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
_mark_line_as_unsafe(op->line);
}
} else if (!for_completion && (index_type.kind != DataType::BUILTIN || index_type.builtin_type != Variant::STRING)) {
- _set_error("Only strings can be used as index in the base type '" + base_type.to_string() + "'.", op->line);
+ _set_error("Only strings can be used as an index in the base type \"" + base_type.to_string() + "\".", op->line);
return DataType();
}
}
- if (check_types && !node_type.has_type) {
+ if (check_types && !node_type.has_type && base_type.kind == DataType::BUILTIN) {
// Can infer indexing type for some variant types
DataType result;
result.has_type = true;
@@ -6505,7 +6643,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Variant::REAL:
case Variant::NODE_PATH:
case Variant::_RID: {
- _set_error("Can't index on a value of type '" + base_type.to_string() + "'.", op->line);
+ _set_error("Can't index on a value of type \"" + base_type.to_string() + "\".", op->line);
return DataType();
} break;
// Return int
@@ -6679,8 +6817,7 @@ bool GDScriptParser::_get_function_signature(DataType &p_base_type, const String
}
if (!ClassDB::class_exists(native)) {
if (!check_types) return false;
- ERR_EXPLAIN("Parser bug: Class '" + String(native) + "' not found.");
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "Parser bug: Class '" + String(native) + "' not found.");
}
MethodBind *method = ClassDB::get_method(native, p_function);
@@ -6904,7 +7041,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
if (check_types) {
if (!tmp.has_method(callee_name)) {
- _set_error("Method '" + callee_name + "' is not declared on base '" + base_type.to_string() + "'.", p_call->line);
+ _set_error("The method \"" + callee_name + "\" isn't declared on base \"" + base_type.to_string() + "\".", p_call->line);
return DataType();
}
@@ -6964,7 +7101,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
if (!valid) {
#ifdef DEBUG_ENABLED
if (p_call->arguments[0]->type == Node::TYPE_SELF) {
- _set_error("Method '" + callee_name + "' is not declared in the current class.", p_call->line);
+ _set_error("The method \"" + callee_name + "\" isn't declared in the current class.", p_call->line);
return DataType();
}
DataType tmp_type;
@@ -6989,7 +7126,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
}
if (check_types && !is_static && !is_initializer && base_type.is_meta_type) {
- _set_error("Non-static function '" + String(callee_name) + "' can only be called from an instance.", p_call->line);
+ _set_error("Non-static function \"" + String(callee_name) + "\" can only be called from an instance.", p_call->line);
return DataType();
}
@@ -7014,11 +7151,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
}
if (arg_count < arg_types.size() - default_args_count) {
- _set_error("Too few arguments for '" + callee_name + "()' call. Expected at least " + itos(arg_types.size() - default_args_count) + ".", p_call->line);
+ _set_error("Too few arguments for \"" + callee_name + "()\" call. Expected at least " + itos(arg_types.size() - default_args_count) + ".", p_call->line);
return return_type;
}
if (!is_vararg && arg_count > arg_types.size()) {
- _set_error("Too many arguments for '" + callee_name + "()' call. Expected at most " + itos(arg_types.size()) + ".", p_call->line);
+ _set_error("Too many arguments for \"" + callee_name + "()\" call. Expected at most " + itos(arg_types.size()) + ".", p_call->line);
return return_type;
}
@@ -7040,7 +7177,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
} else if (!_is_type_compatible(arg_types[i - arg_diff], par_type, true)) {
// Supertypes are acceptable for dynamic compliance
if (!_is_type_compatible(par_type, arg_types[i - arg_diff])) {
- _set_error("At '" + callee_name + "()' call, argument " + itos(i - arg_diff + 1) + ". Assigned type (" +
+ _set_error("At \"" + callee_name + "()\" call, argument " + itos(i - arg_diff + 1) + ". Assigned type (" +
par_type.to_string() + ") doesn't match the function argument's type (" +
arg_types[i - arg_diff].to_string() + ").",
p_call->line);
@@ -7188,8 +7325,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
if (!ClassDB::class_exists(native)) {
if (!check_types) return false;
- ERR_EXPLAIN("Parser bug: Class '" + String(native) + "' not found.");
- ERR_FAIL_V(false);
+ ERR_FAIL_V_MSG(false, "Parser bug: Class \"" + String(native) + "\" not found.");
}
bool valid = false;
@@ -7359,7 +7495,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
Ref<GDScript> gds = scr;
if (gds.is_valid()) {
if (!gds->is_valid()) {
- _set_error("Class '" + p_identifier + "' could not be fully loaded (script error or cyclic dependency).");
+ _set_error("The class \"" + p_identifier + "\" couldn't be fully loaded (script error or cyclic dependency).");
return DataType();
}
result.kind = DataType::GDSCRIPT;
@@ -7368,7 +7504,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
}
return result;
}
- _set_error("Class '" + p_identifier + "' was found in global scope but its script could not be loaded.");
+ _set_error("The class \"" + p_identifier + "\" was found in global scope, but its script couldn't be loaded.");
return DataType();
}
@@ -7411,7 +7547,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
Ref<GDScript> gds = singleton;
if (gds.is_valid()) {
if (!gds->is_valid()) {
- _set_error("Couldn't fully load singleton script '" + p_identifier + "' (possible cyclic reference or parse error).", p_line);
+ _set_error("Couldn't fully load the singleton script \"" + p_identifier + "\" (possible cyclic reference or parse error).", p_line);
return DataType();
}
result.kind = DataType::GDSCRIPT;
@@ -7423,7 +7559,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
}
// This means looking in the current class, which type is always known
- _set_error("Identifier '" + p_identifier.operator String() + "' is not declared in the current scope.", p_line);
+ _set_error("The identifier \"" + p_identifier.operator String() + "\" isn't declared in the current scope.", p_line);
}
#ifdef DEBUG_ENABLED
@@ -7455,7 +7591,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
DataType expr = _resolve_type(c.expression->get_datatype(), c.expression->line);
if (check_types && !_is_type_compatible(cont, expr)) {
- _set_error("Constant value type (" + expr.to_string() + ") is not compatible with declared type (" + cont.to_string() + ").",
+ _set_error("The constant value type (" + expr.to_string() + ") isn't compatible with declared type (" + cont.to_string() + ").",
c.expression->line);
return;
}
@@ -7466,7 +7602,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
DataType tmp;
if (_get_member_type(p_class->base_type, E->key(), tmp)) {
- _set_error("Member '" + String(E->key()) + "' already exists in parent class.", c.expression->line);
+ _set_error("The member \"" + String(E->key()) + "\" already exists in a parent class.", c.expression->line);
return;
}
}
@@ -7488,7 +7624,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
DataType tmp;
if (_get_member_type(p_class->base_type, v.identifier, tmp)) {
- _set_error("Member '" + String(v.identifier) + "' already exists in parent class.", v.line);
+ _set_error("The member \"" + String(v.identifier) + "\" already exists in a parent class.", v.line);
return;
}
@@ -7505,7 +7641,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
} else {
// Try with implicit conversion
if (v.data_type.kind != DataType::BUILTIN || !_is_type_compatible(v.data_type, expr_type, true)) {
- _set_error("Assigned expression type (" + expr_type.to_string() + ") doesn't match the variable's type (" +
+ _set_error("The assigned expression's type (" + expr_type.to_string() + ") doesn't match the variable's type (" +
v.data_type.to_string() + ").",
v.line);
return;
@@ -7534,7 +7670,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
if (v.data_type.infer_type) {
if (!expr_type.has_type) {
- _set_error("Assigned value does not have a set type, variable type cannot be inferred.", v.line);
+ _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", v.line);
return;
}
v.data_type = expr_type;
@@ -7546,7 +7682,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
if (v.data_type.has_type && v._export.type != Variant::NIL) {
DataType export_type = _type_from_property(v._export);
if (!_is_type_compatible(v.data_type, export_type, true)) {
- _set_error("Export hint type (" + export_type.to_string() + ") doesn't match the variable's type (" +
+ _set_error("The export hint's type (" + export_type.to_string() + ") doesn't match the variable's type (" +
v.data_type.to_string() + ").",
v.line);
return;
@@ -7565,15 +7701,15 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
if (setter->get_required_argument_count() != 1 &&
!(setter->get_required_argument_count() == 0 && setter->default_values.size() > 0)) {
- _set_error("Setter function needs to receive exactly 1 argument. See '" + setter->name +
- "()' definition at line " + itos(setter->line) + ".",
+ _set_error("The setter function needs to receive exactly 1 argument. See \"" + setter->name +
+ "()\" definition at line " + itos(setter->line) + ".",
v.line);
return;
}
if (!_is_type_compatible(v.data_type, setter->argument_types[0])) {
- _set_error("Setter argument type (" + setter->argument_types[0].to_string() +
- ") doesn't match the variable's type (" + v.data_type.to_string() + "). See '" +
- setter->name + "()' definition at line " + itos(setter->line) + ".",
+ _set_error("The setter argument's type (" + setter->argument_types[0].to_string() +
+ ") doesn't match the variable's type (" + v.data_type.to_string() + "). See \"" +
+ setter->name + "()\" definition at line " + itos(setter->line) + ".",
v.line);
return;
}
@@ -7584,15 +7720,15 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
FunctionNode *getter = p_class->functions[j];
if (getter->get_required_argument_count() != 0) {
- _set_error("Getter function can't receive arguments. See '" + getter->name +
- "()' definition at line " + itos(getter->line) + ".",
+ _set_error("The getter function can't receive arguments. See \"" + getter->name +
+ "()\" definition at line " + itos(getter->line) + ".",
v.line);
return;
}
if (!_is_type_compatible(v.data_type, getter->get_datatype())) {
- _set_error("Getter return type (" + getter->get_datatype().to_string() +
+ _set_error("The getter return type (" + getter->get_datatype().to_string() +
") doesn't match the variable's type (" + v.data_type.to_string() +
- "). See '" + getter->name + "()' definition at line " + itos(getter->line) + ".",
+ "). See \"" + getter->name + "()\" definition at line " + itos(getter->line) + ".",
v.line);
return;
}
@@ -7606,23 +7742,23 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
for (int j = 0; j < p_class->static_functions.size(); j++) {
if (v.setter == p_class->static_functions[j]->name) {
FunctionNode *setter = p_class->static_functions[j];
- _set_error("Setter can't be a static function. See '" + setter->name + "()' definition at line " + itos(setter->line) + ".", v.line);
+ _set_error("The setter can't be a static function. See \"" + setter->name + "()\" definition at line " + itos(setter->line) + ".", v.line);
return;
}
if (v.getter == p_class->static_functions[j]->name) {
FunctionNode *getter = p_class->static_functions[j];
- _set_error("Getter can't be a static function. See '" + getter->name + "()' definition at line " + itos(getter->line) + ".", v.line);
+ _set_error("The getter can't be a static function. See \"" + getter->name + "()\" definition at line " + itos(getter->line) + ".", v.line);
return;
}
}
if (!found_setter && v.setter != StringName()) {
- _set_error("Setter function is not defined.", v.line);
+ _set_error("The setter function isn't defined.", v.line);
return;
}
if (!found_getter && v.getter != StringName()) {
- _set_error("Getter function is not defined.", v.line);
+ _set_error("The getter function isn't defined.", v.line);
return;
}
}
@@ -7669,7 +7805,7 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) {
String arg_name = p_function->arguments[i];
_set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" +
- arg_name + "' (" + p_function->arguments[i] + ")",
+ arg_name + "' (" + p_function->arguments[i] + ").",
p_function->line);
}
}
@@ -7732,21 +7868,21 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
}
}
parent_signature += ")";
- _set_error("Function signature doesn't match the parent. Parent signature is: '" + parent_signature + "'.", p_function->line);
+ _set_error("The function signature doesn't match the parent. Parent signature is: \"" + parent_signature + "\".", p_function->line);
return;
}
}
#endif // DEBUG_ENABLED
} else {
if (p_function->return_type.has_type && (p_function->return_type.kind != DataType::BUILTIN || p_function->return_type.builtin_type != Variant::NIL)) {
- _set_error("Constructor cannot return a value.", p_function->line);
+ _set_error("The constructor can't return a value.", p_function->line);
return;
}
}
if (p_function->return_type.has_type && (p_function->return_type.kind != DataType::BUILTIN || p_function->return_type.builtin_type != Variant::NIL)) {
if (!p_function->body->has_return) {
- _set_error("Non-void function must return a value in all possible paths.", p_function->line);
+ _set_error("A non-void function must return a value in all possible paths.", p_function->line);
return;
}
}
@@ -7877,7 +8013,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
} else {
// Try implicit conversion
if (lv->datatype.kind != DataType::BUILTIN || !_is_type_compatible(lv->datatype, assign_type, true)) {
- _set_error("Assigned value type (" + assign_type.to_string() + ") doesn't match the variable's type (" +
+ _set_error("The assigned value type (" + assign_type.to_string() + ") doesn't match the variable's type (" +
lv->datatype.to_string() + ").",
lv->line);
return;
@@ -7909,7 +8045,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
if (lv->datatype.infer_type) {
if (!assign_type.has_type) {
- _set_error("Assigned value does not have a set type, variable type cannot be inferred.", lv->line);
+ _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", lv->line);
return;
}
lv->datatype = assign_type;
@@ -7960,7 +8096,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
}
if (lh_type.is_constant) {
- _set_error("Cannot assign a new value to a constant.", op->line);
+ _set_error("Can't assign a new value to a constant.", op->line);
return;
}
}
@@ -7979,8 +8115,8 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
rh_type = _get_operation_type(oper, lh_type, arg_type, valid);
if (check_types && !valid) {
- _set_error("Invalid operand types ('" + lh_type.to_string() + "' and '" + arg_type.to_string() +
- "') to assignment operator '" + Variant::get_operator_name(oper) + "'.",
+ _set_error("Invalid operand types (\"" + lh_type.to_string() + "\" and \"" + arg_type.to_string() +
+ "\") to assignment operator \"" + Variant::get_operator_name(oper) + "\".",
op->line);
return;
}
@@ -8008,7 +8144,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
} else {
// Try implicit conversion
if (lh_type.kind != DataType::BUILTIN || !_is_type_compatible(lh_type, rh_type, true)) {
- _set_error("Assigned value type (" + rh_type.to_string() + ") doesn't match the variable's type (" +
+ _set_error("The assigned value's type (" + rh_type.to_string() + ") doesn't match the variable's type (" +
lh_type.to_string() + ").",
op->line);
return;
@@ -8093,18 +8229,18 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
if (function_type.kind == DataType::BUILTIN && function_type.builtin_type == Variant::NIL) {
// Return void, should not have arguments
if (cf->arguments.size() > 0) {
- _set_error("Void function cannot return a value.", cf->line, cf->column);
+ _set_error("A void function cannot return a value.", cf->line, cf->column);
return;
}
} else {
// Return something, cannot be empty
if (cf->arguments.size() == 0) {
- _set_error("Non-void function must return a value.", cf->line, cf->column);
+ _set_error("A non-void function must return a value.", cf->line, cf->column);
return;
}
if (!_is_type_compatible(function_type, ret_type)) {
- _set_error("Returned value type (" + ret_type.to_string() + ") doesn't match the function return type (" +
+ _set_error("The returned value type (" + ret_type.to_string() + ") doesn't match the function return type (" +
function_type.to_string() + ").",
cf->line, cf->column);
return;
@@ -8241,6 +8377,10 @@ int GDScriptParser::get_error_column() const {
return error_column;
}
+bool GDScriptParser::has_error() const {
+ return error_set;
+}
+
Error GDScriptParser::_parse(const String &p_base_path) {
base_path = p_base_path;
@@ -8257,7 +8397,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_ERROR) {
error_set = false;
- _set_error("Parse Error: " + tokenizer->get_token_error());
+ _set_error("Parse error: " + tokenizer->get_token_error());
}
if (error_set && !for_completion) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 62d7bdb393..04ce9cf4c6 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -481,7 +481,12 @@ public:
struct AssertNode : public Node {
Node *condition;
- AssertNode() { type = TYPE_ASSERT; }
+ Node *message;
+ AssertNode() :
+ condition(0),
+ message(0) {
+ type = TYPE_ASSERT;
+ }
};
struct BreakpointNode : public Node {
@@ -610,6 +615,7 @@ private:
bool _get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const;
bool _get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type) const;
bool _is_type_compatible(const DataType &p_container, const DataType &p_expression, bool p_allow_implicit_conversion = false) const;
+ Node *_get_default_value_for_type(const DataType &p_type, int p_line = -1);
DataType _reduce_node_type(Node *p_node);
DataType _reduce_function_call_type(const OperatorNode *p_call);
@@ -632,6 +638,7 @@ private:
Error _parse(const String &p_base_path);
public:
+ bool has_error() const;
String get_error() const;
int get_error_line() const;
int get_error_column() const;
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 95715ab648..64b354bdb8 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -357,8 +357,7 @@ StringName GDScriptTokenizer::get_token_literal(int p_offset) const {
}
}
}
- ERR_EXPLAIN("Failed to get token literal");
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Failed to get token literal.");
}
static bool _is_text_char(CharType c) {
@@ -517,7 +516,22 @@ void GDScriptTokenizerText::_advance() {
INCPOS(1);
column = 1;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
@@ -555,9 +569,25 @@ void GDScriptTokenizerText::_advance() {
column = 1;
line++;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
+
_make_newline(i);
return;
@@ -1082,6 +1112,7 @@ void GDScriptTokenizerText::set_code(const String &p_code) {
ignore_warnings = false;
#endif // DEBUG_ENABLED
last_error = "";
+ file_indent_type = INDENT_NONE;
for (int i = 0; i < MAX_LOOKAHEAD + 1; i++)
_advance();
}
@@ -1187,10 +1218,8 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
ERR_FAIL_COND_V(p_buffer.size() < 24 || p_buffer[0] != 'G' || p_buffer[1] != 'D' || p_buffer[2] != 'S' || p_buffer[3] != 'C', ERR_INVALID_DATA);
int version = decode_uint32(&buf[4]);
- if (version > BYTECODE_VERSION) {
- ERR_EXPLAIN("Bytecode is too New! Please use a newer engine version.");
- ERR_FAIL_V(ERR_INVALID_DATA);
- }
+ ERR_FAIL_COND_V_MSG(version > BYTECODE_VERSION, ERR_INVALID_DATA, "Bytecode is too recent! Please use a newer engine version.");
+
int identifier_count = decode_uint32(&buf[8]);
int constant_count = decode_uint32(&buf[12]);
int line_count = decode_uint32(&buf[16]);
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 7b977ff67c..89d586b912 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -222,6 +222,12 @@ class GDScriptTokenizerText : public GDScriptTokenizer {
int tk_rb_pos;
String last_error;
bool error_flag;
+ enum {
+ INDENT_NONE,
+ INDENT_SPACES,
+ INDENT_TABS,
+ } file_indent_type;
+
#ifdef DEBUG_ENABLED
Vector<Pair<int, String> > warning_skips;
Set<String> warning_global_skips;
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
new file mode 100644
index 0000000000..6db8cb2c88
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -0,0 +1,759 @@
+/*************************************************************************/
+/* gdscript_extend_parser.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 "gdscript_extend_parser.h"
+#include "../gdscript.h"
+#include "core/io/json.h"
+#include "gdscript_language_protocol.h"
+#include "gdscript_workspace.h"
+
+void ExtendGDScriptParser::update_diagnostics() {
+
+ diagnostics.clear();
+
+ if (has_error()) {
+ lsp::Diagnostic diagnostic;
+ diagnostic.severity = lsp::DiagnosticSeverity::Error;
+ diagnostic.message = get_error();
+ diagnostic.source = "gdscript";
+ diagnostic.code = -1;
+ lsp::Range range;
+ lsp::Position pos;
+ int line = LINE_NUMBER_TO_INDEX(get_error_line());
+ const String &line_text = get_lines()[line];
+ pos.line = line;
+ pos.character = line_text.length() - line_text.strip_edges(true, false).length();
+ range.start = pos;
+ range.end = range.start;
+ range.end.character = line_text.strip_edges(false).length();
+ diagnostic.range = range;
+ diagnostics.push_back(diagnostic);
+ }
+
+ const List<GDScriptWarning> &warnings = get_warnings();
+ for (const List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) {
+ const GDScriptWarning &warning = E->get();
+ lsp::Diagnostic diagnostic;
+ diagnostic.severity = lsp::DiagnosticSeverity::Warning;
+ diagnostic.message = warning.get_message();
+ diagnostic.source = "gdscript";
+ diagnostic.code = warning.code;
+ lsp::Range range;
+ lsp::Position pos;
+ int line = LINE_NUMBER_TO_INDEX(warning.line);
+ const String &line_text = get_lines()[line];
+ pos.line = line;
+ pos.character = line_text.length() - line_text.strip_edges(true, false).length();
+ range.start = pos;
+ range.end = pos;
+ range.end.character = line_text.strip_edges(false).length();
+ diagnostic.range = range;
+ diagnostics.push_back(diagnostic);
+ }
+}
+
+void ExtendGDScriptParser::update_symbols() {
+
+ members.clear();
+
+ const GDScriptParser::Node *head = get_parse_tree();
+ if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
+
+ parse_class_symbol(gdclass, class_symbol);
+
+ for (int i = 0; i < class_symbol.children.size(); i++) {
+ const lsp::DocumentSymbol &symbol = class_symbol.children[i];
+ members.set(symbol.name, &symbol);
+
+ // cache level one inner classes
+ if (symbol.kind == lsp::SymbolKind::Class) {
+ ClassMembers inner_class;
+ for (int j = 0; j < symbol.children.size(); j++) {
+ const lsp::DocumentSymbol &s = symbol.children[j];
+ inner_class.set(s.name, &s);
+ }
+ inner_classes.set(symbol.name, inner_class);
+ }
+ }
+ }
+}
+
+void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol) {
+
+ const String uri = get_uri();
+
+ r_symbol.uri = uri;
+ r_symbol.script_path = path;
+ r_symbol.children.clear();
+ r_symbol.name = p_class->name;
+ if (r_symbol.name.empty())
+ r_symbol.name = path.get_file();
+ r_symbol.kind = lsp::SymbolKind::Class;
+ r_symbol.deprecated = false;
+ r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_class->line);
+ r_symbol.range.start.character = p_class->column;
+ r_symbol.range.end.line = LINE_NUMBER_TO_INDEX(p_class->end_line);
+ r_symbol.selectionRange.start.line = r_symbol.range.start.line;
+ r_symbol.detail = "class " + r_symbol.name;
+ bool is_root_class = &r_symbol == &class_symbol;
+ r_symbol.documentation = parse_documentation_as_markdown(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class);
+
+ for (int i = 0; i < p_class->variables.size(); ++i) {
+
+ const GDScriptParser::ClassNode::Member &m = p_class->variables[i];
+
+ lsp::DocumentSymbol symbol;
+ symbol.name = m.identifier;
+ symbol.kind = lsp::SymbolKind::Variable;
+ symbol.deprecated = false;
+ const int line = LINE_NUMBER_TO_INDEX(m.line);
+ symbol.range.start.line = line;
+ symbol.range.start.character = lines[line].length() - lines[line].strip_edges(true, false).length();
+ symbol.range.end.line = line;
+ symbol.range.end.character = lines[line].length();
+ symbol.selectionRange.start.line = symbol.range.start.line;
+ if (m._export.type != Variant::NIL) {
+ symbol.detail += "export ";
+ }
+ symbol.detail += "var " + m.identifier;
+ if (m.data_type.kind != GDScriptParser::DataType::UNRESOLVED) {
+ symbol.detail += ": " + m.data_type.to_string();
+ }
+ if (m.default_value.get_type() != Variant::NIL) {
+ symbol.detail += " = " + JSON::print(m.default_value);
+ }
+
+ symbol.documentation = parse_documentation_as_markdown(line);
+ symbol.uri = uri;
+ symbol.script_path = path;
+
+ r_symbol.children.push_back(symbol);
+ }
+
+ for (int i = 0; i < p_class->_signals.size(); ++i) {
+ const GDScriptParser::ClassNode::Signal &signal = p_class->_signals[i];
+
+ lsp::DocumentSymbol symbol;
+ symbol.name = signal.name;
+ symbol.kind = lsp::SymbolKind::Event;
+ symbol.deprecated = false;
+ const int line = LINE_NUMBER_TO_INDEX(signal.line);
+ symbol.range.start.line = line;
+ symbol.range.start.character = lines[line].length() - lines[line].strip_edges(true, false).length();
+ symbol.range.end.line = symbol.range.start.line;
+ symbol.range.end.character = lines[line].length();
+ symbol.selectionRange.start.line = symbol.range.start.line;
+ symbol.documentation = parse_documentation_as_markdown(line);
+ symbol.uri = uri;
+ symbol.script_path = path;
+ symbol.detail = "signal " + signal.name + "(";
+ for (int j = 0; j < signal.arguments.size(); j++) {
+ if (j > 0) {
+ symbol.detail += ", ";
+ }
+ symbol.detail += signal.arguments[j];
+ }
+ symbol.detail += ")";
+
+ r_symbol.children.push_back(symbol);
+ }
+
+ for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
+ lsp::DocumentSymbol symbol;
+ const GDScriptParser::ClassNode::Constant &c = E->value();
+ const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression);
+ ERR_FAIL_COND(!node);
+ symbol.name = E->key();
+ symbol.kind = lsp::SymbolKind::Constant;
+ symbol.deprecated = false;
+ const int line = LINE_NUMBER_TO_INDEX(E->get().expression->line);
+ symbol.range.start.line = line;
+ symbol.range.start.character = E->get().expression->column;
+ symbol.range.end.line = symbol.range.start.line;
+ symbol.range.end.character = lines[line].length();
+ symbol.selectionRange.start.line = symbol.range.start.line;
+ symbol.documentation = parse_documentation_as_markdown(line);
+ symbol.uri = uri;
+ symbol.script_path = path;
+
+ symbol.detail = "const " + symbol.name;
+ if (c.type.kind != GDScriptParser::DataType::UNRESOLVED) {
+ symbol.detail += ": " + c.type.to_string();
+ }
+
+ String value_text;
+ if (node->value.get_type() == Variant::OBJECT) {
+ RES res = node->value;
+ if (res.is_valid() && !res->get_path().empty()) {
+ value_text = "preload(\"" + res->get_path() + "\")";
+ if (symbol.documentation.empty()) {
+ if (Map<String, ExtendGDScriptParser *>::Element *S = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.find(res->get_path())) {
+ symbol.documentation = S->get()->class_symbol.documentation;
+ }
+ }
+ } else {
+ value_text = JSON::print(node->value);
+ }
+ } else {
+ value_text = JSON::print(node->value);
+ }
+ if (!value_text.empty()) {
+ symbol.detail += " = " + value_text;
+ }
+
+ r_symbol.children.push_back(symbol);
+ }
+
+ for (int i = 0; i < p_class->functions.size(); ++i) {
+ const GDScriptParser::FunctionNode *func = p_class->functions[i];
+ lsp::DocumentSymbol symbol;
+ parse_function_symbol(func, symbol);
+ r_symbol.children.push_back(symbol);
+ }
+
+ for (int i = 0; i < p_class->static_functions.size(); ++i) {
+ const GDScriptParser::FunctionNode *func = p_class->static_functions[i];
+ lsp::DocumentSymbol symbol;
+ parse_function_symbol(func, symbol);
+ r_symbol.children.push_back(symbol);
+ }
+
+ for (int i = 0; i < p_class->subclasses.size(); ++i) {
+ const GDScriptParser::ClassNode *subclass = p_class->subclasses[i];
+ lsp::DocumentSymbol symbol;
+ parse_class_symbol(subclass, symbol);
+ r_symbol.children.push_back(symbol);
+ }
+}
+
+void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol) {
+
+ const String uri = get_uri();
+
+ r_symbol.name = p_func->name;
+ r_symbol.kind = lsp::SymbolKind::Function;
+ r_symbol.detail = "func " + p_func->name + "(";
+ r_symbol.deprecated = false;
+ const int line = LINE_NUMBER_TO_INDEX(p_func->line);
+ r_symbol.range.start.line = line;
+ r_symbol.range.start.character = p_func->column;
+ r_symbol.range.end.line = MAX(p_func->body->end_line - 2, p_func->body->line);
+ r_symbol.range.end.character = lines[r_symbol.range.end.line].length();
+ r_symbol.selectionRange.start.line = r_symbol.range.start.line;
+ r_symbol.documentation = parse_documentation_as_markdown(line);
+ r_symbol.uri = uri;
+ r_symbol.script_path = path;
+
+ String arguments;
+ for (int i = 0; i < p_func->arguments.size(); i++) {
+ lsp::DocumentSymbol symbol;
+ symbol.kind = lsp::SymbolKind::Variable;
+ symbol.name = p_func->arguments[i];
+ symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_func->body->line);
+ symbol.range.start.character = p_func->body->column;
+ symbol.range.end = symbol.range.start;
+ symbol.uri = uri;
+ symbol.script_path = path;
+ r_symbol.children.push_back(symbol);
+ if (i > 0) {
+ arguments += ", ";
+ }
+ arguments += String(p_func->arguments[i]);
+ if (p_func->argument_types[i].kind != GDScriptParser::DataType::UNRESOLVED) {
+ arguments += ": " + p_func->argument_types[i].to_string();
+ }
+ int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
+ if (default_value_idx >= 0) {
+ const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
+ if (const_node == NULL) {
+ const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
+ if (operator_node) {
+ const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
+ }
+ }
+
+ if (const_node) {
+ String value = JSON::print(const_node->value);
+ arguments += " = " + value;
+ }
+ }
+ }
+ r_symbol.detail += arguments + ")";
+ if (p_func->return_type.kind != GDScriptParser::DataType::UNRESOLVED) {
+ r_symbol.detail += " -> " + p_func->return_type.to_string();
+ }
+
+ for (const Map<StringName, LocalVarNode *>::Element *E = p_func->body->variables.front(); E; E = E->next()) {
+ lsp::DocumentSymbol symbol;
+ const GDScriptParser::LocalVarNode *var = E->value();
+ symbol.name = E->key();
+ symbol.kind = lsp::SymbolKind::Variable;
+ symbol.range.start.line = LINE_NUMBER_TO_INDEX(E->get()->line);
+ symbol.range.start.character = E->get()->column;
+ symbol.range.end.line = symbol.range.start.line;
+ symbol.range.end.character = lines[symbol.range.end.line].length();
+ symbol.uri = uri;
+ symbol.script_path = path;
+ symbol.detail = "var " + symbol.name;
+ if (var->datatype.kind != GDScriptParser::DataType::UNRESOLVED) {
+ symbol.detail += ": " + var->datatype.to_string();
+ }
+ symbol.documentation = parse_documentation_as_markdown(line);
+ r_symbol.children.push_back(symbol);
+ }
+}
+
+String ExtendGDScriptParser::marked_documentation(const String &p_bbcode) {
+
+ String markdown = p_bbcode.strip_edges();
+
+ Vector<String> lines = markdown.split("\n");
+ bool in_code_block = false;
+ int code_block_indent = -1;
+
+ markdown = "";
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ int block_start = line.find("[codeblock]");
+ if (block_start != -1) {
+ code_block_indent = block_start;
+ in_code_block = true;
+ line = "'''gdscript\n";
+ } else if (in_code_block) {
+ line = "\t" + line.substr(code_block_indent, line.length());
+ }
+
+ if (in_code_block && line.find("[/codeblock]") != -1) {
+ line = "'''\n\n";
+ in_code_block = false;
+ }
+
+ if (!in_code_block) {
+ line = line.strip_edges();
+ line = line.replace("[code]", "`");
+ line = line.replace("[/code]", "`");
+ line = line.replace("[i]", "*");
+ line = line.replace("[/i]", "*");
+ line = line.replace("[b]", "**");
+ line = line.replace("[/b]", "**");
+ line = line.replace("[u]", "__");
+ line = line.replace("[/u]", "__");
+ line = line.replace("[method ", "`");
+ line = line.replace("[member ", "`");
+ line = line.replace("[signal ", "`");
+ line = line.replace("[enum ", "`");
+ line = line.replace("[constant ", "`");
+ line = line.replace("[", "`");
+ line = line.replace("]", "`");
+ }
+
+ if (!in_code_block && i < lines.size() - 1) {
+ line += "\n\n";
+ } else if (i < lines.size() - 1) {
+ line += "\n";
+ }
+ markdown += line;
+ }
+ return markdown;
+}
+
+String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
+ ERR_FAIL_INDEX_V(p_line, lines.size(), String());
+
+ List<String> doc_lines;
+
+ if (!p_docs_down) { // inline comment
+ String inline_comment = lines[p_line];
+ int comment_start = inline_comment.find("#");
+ if (comment_start != -1) {
+ inline_comment = inline_comment.substr(comment_start, inline_comment.length()).strip_edges();
+ if (inline_comment.length() > 1) {
+ doc_lines.push_back(inline_comment.substr(1, inline_comment.length()));
+ }
+ }
+ }
+
+ int step = p_docs_down ? 1 : -1;
+ int start_line = p_docs_down ? p_line : p_line - 1;
+ for (int i = start_line; true; i += step) {
+
+ if (i < 0 || i >= lines.size()) break;
+
+ String line_comment = lines[i].strip_edges(true, false);
+ if (line_comment.begins_with("#")) {
+ line_comment = line_comment.substr(1, line_comment.length());
+ if (p_docs_down) {
+ doc_lines.push_back(line_comment);
+ } else {
+ doc_lines.push_front(line_comment);
+ }
+ } else {
+ break;
+ }
+ }
+
+ String doc;
+ for (List<String>::Element *E = doc_lines.front(); E; E = E->next()) {
+ doc += E->get() + "\n";
+ }
+ return doc;
+}
+
+String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_cursor) const {
+
+ String longthing;
+ int len = lines.size();
+ for (int i = 0; i < len; i++) {
+
+ if (i == p_cursor.line) {
+ longthing += lines[i].substr(0, p_cursor.character);
+ longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ longthing += lines[i].substr(p_cursor.character, lines[i].size());
+ } else {
+
+ longthing += lines[i];
+ }
+
+ if (i != len - 1)
+ longthing += "\n";
+ }
+
+ return longthing;
+}
+
+String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol, bool p_func_requred) const {
+ String longthing;
+ int len = lines.size();
+ for (int i = 0; i < len; i++) {
+
+ if (i == p_cursor.line) {
+ String line = lines[i];
+ String first_part = line.substr(0, p_cursor.character);
+ String last_part = line.substr(p_cursor.character + 1, lines[i].length());
+ if (!p_symbol.empty()) {
+ String left_cursor_text;
+ for (int c = p_cursor.character - 1; c >= 0; c--) {
+ left_cursor_text = line.substr(c, p_cursor.character - c);
+ if (p_symbol.begins_with(left_cursor_text)) {
+ first_part = line.substr(0, c);
+ first_part += p_symbol;
+ break;
+ }
+ }
+ }
+
+ longthing += first_part;
+ longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ if (p_func_requred) {
+ longthing += "("; // tell the parser this is a function call
+ }
+ longthing += last_part;
+ } else {
+
+ longthing += lines[i];
+ }
+
+ if (i != len - 1)
+ longthing += "\n";
+ }
+
+ return longthing;
+}
+
+String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const {
+
+ ERR_FAIL_INDEX_V(p_position.line, lines.size(), "");
+ String line = lines[p_position.line];
+ ERR_FAIL_INDEX_V(p_position.character, line.size(), "");
+
+ int start_pos = p_position.character;
+ for (int c = p_position.character; c >= 0; c--) {
+ start_pos = c;
+ CharType ch = line[c];
+ bool valid_char = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
+ if (!valid_char) {
+ break;
+ }
+ }
+
+ int end_pos = p_position.character;
+ for (int c = p_position.character; c < line.length(); c++) {
+ CharType ch = line[c];
+ bool valid_char = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_';
+ if (!valid_char) {
+ break;
+ }
+ end_pos = c;
+ }
+ if (start_pos < end_pos) {
+ p_offset.x = start_pos - p_position.character;
+ p_offset.y = end_pos - p_position.character;
+ return line.substr(start_pos + 1, end_pos - start_pos);
+ }
+
+ return "";
+}
+
+String ExtendGDScriptParser::get_uri() const {
+ return GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_uri(path);
+}
+
+const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(int p_line, const lsp::DocumentSymbol &p_parent) const {
+ const lsp::DocumentSymbol *ret = NULL;
+ if (p_line < p_parent.range.start.line) {
+ return ret;
+ } else if (p_parent.range.start.line == p_line) {
+ return &p_parent;
+ } else {
+ for (int i = 0; i < p_parent.children.size(); i++) {
+ ret = search_symbol_defined_at_line(p_line, p_parent.children[i]);
+ if (ret) {
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+String ExtendGDScriptParser::parse_documentation_as_markdown(int p_line, bool p_docs_down) {
+ return marked_documentation(parse_documentation(p_line, p_docs_down));
+}
+
+const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int p_line) const {
+ if (p_line <= 0) {
+ return &class_symbol;
+ }
+ return search_symbol_defined_at_line(p_line, class_symbol);
+}
+
+const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const {
+
+ if (p_subclass.empty()) {
+ const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
+ if (ptr) {
+ return *ptr;
+ }
+ } else {
+ if (const ClassMembers *_class = inner_classes.getptr(p_subclass)) {
+ const lsp::DocumentSymbol *const *ptr = _class->getptr(p_name);
+ if (ptr) {
+ return *ptr;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+const Array &ExtendGDScriptParser::get_member_completions() {
+
+ if (member_completions.empty()) {
+
+ const String *name = members.next(NULL);
+ while (name) {
+
+ const lsp::DocumentSymbol *symbol = members.get(*name);
+ lsp::CompletionItem item = symbol->make_completion_item();
+ item.data = JOIN_SYMBOLS(path, *name);
+ member_completions.push_back(item.to_json());
+
+ name = members.next(name);
+ }
+
+ const String *_class = inner_classes.next(NULL);
+ while (_class) {
+
+ const ClassMembers *inner_class = inner_classes.getptr(*_class);
+ const String *member_name = inner_class->next(NULL);
+ while (member_name) {
+ const lsp::DocumentSymbol *symbol = inner_class->get(*member_name);
+ lsp::CompletionItem item = symbol->make_completion_item();
+ item.data = JOIN_SYMBOLS(path, JOIN_SYMBOLS(*_class, *member_name));
+ member_completions.push_back(item.to_json());
+
+ member_name = inner_class->next(member_name);
+ }
+
+ _class = inner_classes.next(_class);
+ }
+ }
+
+ return member_completions;
+}
+
+Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::FunctionNode *p_func) const {
+ Dictionary func;
+ ERR_FAIL_NULL_V(p_func, func);
+ func["name"] = p_func->name;
+ func["return_type"] = p_func->return_type.to_string();
+ func["rpc_mode"] = p_func->rpc_mode;
+ Array arguments;
+ for (int i = 0; i < p_func->arguments.size(); i++) {
+ Dictionary arg;
+ arg["name"] = p_func->arguments[i];
+ arg["type"] = p_func->argument_types[i].to_string();
+ int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
+ if (default_value_idx >= 0) {
+ const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
+ if (const_node == NULL) {
+ const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
+ if (operator_node) {
+ const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
+ }
+ }
+ if (const_node) {
+ arg["default_value"] = const_node->value;
+ }
+ }
+ arguments.push_back(arg);
+ }
+ if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(p_func->line))) {
+ func["signature"] = symbol->detail;
+ func["description"] = symbol->documentation;
+ }
+ func["arguments"] = arguments;
+ return func;
+}
+
+Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode *p_class) const {
+ Dictionary class_api;
+
+ ERR_FAIL_NULL_V(p_class, class_api);
+
+ class_api["name"] = String(p_class->name);
+ class_api["path"] = path;
+ Array extends_class;
+ for (int i = 0; i < p_class->extends_class.size(); i++) {
+ extends_class.append(String(p_class->extends_class[i]));
+ }
+ class_api["extends_class"] = extends_class;
+ class_api["extends_file"] = String(p_class->extends_file);
+ class_api["icon"] = String(p_class->icon_path);
+
+ if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(p_class->line))) {
+ class_api["signature"] = symbol->detail;
+ class_api["description"] = symbol->documentation;
+ }
+
+ Array subclasses;
+ for (int i = 0; i < p_class->subclasses.size(); i++) {
+ subclasses.push_back(dump_class_api(p_class->subclasses[i]));
+ }
+ class_api["sub_classes"] = subclasses;
+
+ Array constants;
+ for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
+
+ const GDScriptParser::ClassNode::Constant &c = E->value();
+ const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression);
+ ERR_FAIL_COND_V(!node, class_api);
+
+ Dictionary api;
+ api["name"] = E->key();
+ api["value"] = node->value;
+ api["data_type"] = node->datatype.to_string();
+ if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(node->line))) {
+ api["signature"] = symbol->detail;
+ api["description"] = symbol->documentation;
+ }
+ constants.push_back(api);
+ }
+ class_api["constants"] = constants;
+
+ Array members;
+ for (int i = 0; i < p_class->variables.size(); ++i) {
+ const GDScriptParser::ClassNode::Member &m = p_class->variables[i];
+ Dictionary api;
+ api["name"] = m.identifier;
+ api["data_type"] = m.data_type.to_string();
+ api["default_value"] = m.default_value;
+ api["setter"] = String(m.setter);
+ api["getter"] = String(m.getter);
+ api["export"] = m._export.type != Variant::NIL;
+ if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(m.line))) {
+ api["signature"] = symbol->detail;
+ api["description"] = symbol->documentation;
+ }
+ members.push_back(api);
+ }
+ class_api["members"] = members;
+
+ Array signals;
+ for (int i = 0; i < p_class->_signals.size(); ++i) {
+ const GDScriptParser::ClassNode::Signal &signal = p_class->_signals[i];
+ Dictionary api;
+ api["name"] = signal.name;
+ Array args;
+ for (int j = 0; j < signal.arguments.size(); j++) {
+ args.append(signal.arguments[j]);
+ }
+ api["arguments"] = args;
+ if (const lsp::DocumentSymbol *symbol = get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(signal.line))) {
+ api["signature"] = symbol->detail;
+ api["description"] = symbol->documentation;
+ }
+ signals.push_back(api);
+ }
+ class_api["signals"] = signals;
+
+ Array methods;
+ for (int i = 0; i < p_class->functions.size(); ++i) {
+ methods.append(dump_function_api(p_class->functions[i]));
+ }
+ class_api["methods"] = methods;
+
+ Array static_functions;
+ for (int i = 0; i < p_class->static_functions.size(); ++i) {
+ static_functions.append(dump_function_api(p_class->functions[i]));
+ }
+ class_api["static_functions"] = static_functions;
+
+ return class_api;
+}
+
+Dictionary ExtendGDScriptParser::generate_api() const {
+
+ Dictionary api;
+ const GDScriptParser::Node *head = get_parse_tree();
+ if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
+ api = dump_class_api(gdclass);
+ }
+ return api;
+}
+
+Error ExtendGDScriptParser::parse(const String &p_code, const String &p_path) {
+ path = p_path;
+ lines = p_code.split("\n");
+
+ Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, NULL, false);
+ update_diagnostics();
+ update_symbols();
+ return err;
+}
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h
new file mode 100644
index 0000000000..dd0453d3ff
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_extend_parser.h
@@ -0,0 +1,103 @@
+/*************************************************************************/
+/* gdscript_extend_parser.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 GDSCRIPT_EXTEND_PARSER_H
+#define GDSCRIPT_EXTEND_PARSER_H
+
+#include "../gdscript_parser.h"
+#include "core/variant.h"
+#include "lsp.hpp"
+
+#ifndef LINE_NUMBER_TO_INDEX
+#define LINE_NUMBER_TO_INDEX(p_line) ((p_line)-1)
+#endif
+
+#ifndef SYMBOL_SEPERATOR
+#define SYMBOL_SEPERATOR "::"
+#endif
+
+#ifndef JOIN_SYMBOLS
+#define JOIN_SYMBOLS(p_path, name) ((p_path) + SYMBOL_SEPERATOR + (name))
+#endif
+
+typedef HashMap<String, const lsp::DocumentSymbol *> ClassMembers;
+
+class ExtendGDScriptParser : public GDScriptParser {
+
+ String path;
+ Vector<String> lines;
+
+ lsp::DocumentSymbol class_symbol;
+ Vector<lsp::Diagnostic> diagnostics;
+ ClassMembers members;
+ HashMap<String, ClassMembers> inner_classes;
+
+ void update_diagnostics();
+
+ void update_symbols();
+ void parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol);
+ void parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol);
+
+ Dictionary dump_function_api(const GDScriptParser::FunctionNode *p_func) const;
+ Dictionary dump_class_api(const GDScriptParser::ClassNode *p_class) const;
+
+ String parse_documentation(int p_line, bool p_docs_down = false);
+ const lsp::DocumentSymbol *search_symbol_defined_at_line(int p_line, const lsp::DocumentSymbol &p_parent) const;
+
+ Array member_completions;
+
+ String parse_documentation_as_markdown(int p_line, bool p_docs_down = false);
+
+public:
+ static String marked_documentation(const String &p_bbcode);
+
+public:
+ _FORCE_INLINE_ const String &get_path() const { return path; }
+ _FORCE_INLINE_ const Vector<String> &get_lines() const { return lines; }
+ _FORCE_INLINE_ const lsp::DocumentSymbol &get_symbols() const { return class_symbol; }
+ _FORCE_INLINE_ const Vector<lsp::Diagnostic> &get_diagnostics() const { return diagnostics; }
+ _FORCE_INLINE_ const ClassMembers &get_members() const { return members; }
+ _FORCE_INLINE_ const HashMap<String, ClassMembers> &get_inner_classes() const { return inner_classes; }
+
+ String get_text_for_completion(const lsp::Position &p_cursor) const;
+ String get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol = "", bool p_func_requred = false) const;
+ String get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const;
+ String get_uri() const;
+
+ const lsp::DocumentSymbol *get_symbol_defined_at_line(int p_line) const;
+ const lsp::DocumentSymbol *get_member_symbol(const String &p_name, const String &p_subclass = "") const;
+
+ const Array &get_member_completions();
+ Dictionary generate_api() const;
+
+ Error parse(const String &p_code, const String &p_path);
+};
+
+#endif
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
new file mode 100644
index 0000000000..ce3de9bc3b
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -0,0 +1,213 @@
+/*************************************************************************/
+/* gdscript_language_protocol.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 "gdscript_language_protocol.h"
+#include "core/io/json.h"
+#include "core/os/copymem.h"
+#include "core/project_settings.h"
+#include "editor/editor_node.h"
+
+GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = NULL;
+
+void GDScriptLanguageProtocol::on_data_received(int p_id) {
+ lastest_client_id = p_id;
+ Ref<WebSocketPeer> peer = server->get_peer(p_id);
+ PoolByteArray data;
+ if (OK == peer->get_packet_buffer(data)) {
+ String message;
+ message.parse_utf8((const char *)data.read().ptr(), data.size());
+ if (message.begins_with("Content-Length:")) return;
+ String output = process_message(message);
+ if (!output.empty()) {
+ CharString charstr = output.utf8();
+ peer->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ }
+ }
+}
+
+void GDScriptLanguageProtocol::on_client_connected(int p_id, const String &p_protocal) {
+ clients.set(p_id, server->get_peer(p_id));
+}
+
+void GDScriptLanguageProtocol::on_client_disconnected(int p_id, bool p_was_clean_close) {
+ clients.erase(p_id);
+}
+
+String GDScriptLanguageProtocol::process_message(const String &p_text) {
+ String ret = process_string(p_text);
+ if (ret.empty()) {
+ return ret;
+ } else {
+ return format_output(ret);
+ }
+}
+
+String GDScriptLanguageProtocol::format_output(const String &p_text) {
+
+ String header = "Content-Length: ";
+ CharString charstr = p_text.utf8();
+ size_t len = charstr.length();
+ header += itos(len);
+ header += "\r\n\r\n";
+
+ return header + p_text;
+}
+
+void GDScriptLanguageProtocol::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("initialize", "params"), &GDScriptLanguageProtocol::initialize);
+ ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized);
+ ClassDB::bind_method(D_METHOD("on_data_received"), &GDScriptLanguageProtocol::on_data_received);
+ ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected);
+ ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected);
+ ClassDB::bind_method(D_METHOD("notify_all_clients", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_all_clients, DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params", "p_client"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled);
+ ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document);
+ ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace);
+ ClassDB::bind_method(D_METHOD("is_initialized"), &GDScriptLanguageProtocol::is_initialized);
+}
+
+Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
+
+ lsp::InitializeResult ret;
+
+ String root_uri = p_params["rootUri"];
+ String root = p_params["rootPath"];
+ bool is_same_workspace;
+#ifndef WINDOWS_ENABLED
+ is_same_workspace = root.to_lower() == workspace->root.to_lower();
+#else
+ is_same_workspace = root.replace("\\", "/").to_lower() == workspace->root.to_lower();
+#endif
+
+ if (root_uri.length() && is_same_workspace) {
+ workspace->root_uri = root_uri;
+ } else {
+
+ workspace->root_uri = "file://" + workspace->root;
+
+ Dictionary params;
+ params["path"] = workspace->root;
+ Dictionary request = make_notification("gdscrip_client/changeWorkspace", params);
+ if (Ref<WebSocketPeer> *peer = clients.getptr(lastest_client_id)) {
+ String msg = JSON::print(request);
+ msg = format_output(msg);
+ CharString charstr = msg.utf8();
+ (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ }
+ }
+
+ if (!_initialized) {
+ workspace->initialize();
+ text_document->initialize();
+ _initialized = true;
+ }
+
+ return ret.to_json();
+}
+
+void GDScriptLanguageProtocol::initialized(const Variant &p_params) {
+}
+
+void GDScriptLanguageProtocol::poll() {
+ server->poll();
+}
+
+Error GDScriptLanguageProtocol::start(int p_port) {
+ if (server == NULL) {
+ server = dynamic_cast<WebSocketServer *>(ClassDB::instance("WebSocketServer"));
+ ERR_FAIL_COND_V(!server, FAILED);
+ server->set_buffers(8192, 1024, 8192, 1024); // 8mb should be way more than enough
+ server->connect("data_received", this, "on_data_received");
+ server->connect("client_connected", this, "on_client_connected");
+ server->connect("client_disconnected", this, "on_client_disconnected");
+ }
+ return server->listen(p_port);
+}
+
+void GDScriptLanguageProtocol::stop() {
+ server->stop();
+}
+
+void GDScriptLanguageProtocol::notify_all_clients(const String &p_method, const Variant &p_params) {
+
+ Dictionary message = make_notification(p_method, p_params);
+ String msg = JSON::print(message);
+ msg = format_output(msg);
+ CharString charstr = msg.utf8();
+ const int *p_id = clients.next(NULL);
+ while (p_id != NULL) {
+ Ref<WebSocketPeer> peer = clients.get(*p_id);
+ (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ p_id = clients.next(p_id);
+ }
+}
+
+void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client) {
+
+ if (p_client == -1) {
+ p_client = lastest_client_id;
+ }
+
+ Ref<WebSocketPeer> *peer = clients.getptr(p_client);
+ ERR_FAIL_COND(peer == NULL);
+
+ Dictionary message = make_notification(p_method, p_params);
+ String msg = JSON::print(message);
+ msg = format_output(msg);
+ CharString charstr = msg.utf8();
+
+ (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+}
+
+bool GDScriptLanguageProtocol::is_smart_resolve_enabled() const {
+ return bool(_EDITOR_GET("network/language_server/enable_smart_resolve"));
+}
+
+bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const {
+ return bool(_EDITOR_GET("network/language_server/show_native_symbols_in_editor"));
+}
+
+GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
+ server = NULL;
+ singleton = this;
+ _initialized = false;
+ workspace.instance();
+ text_document.instance();
+ set_scope("textDocument", text_document.ptr());
+ set_scope("completionItem", text_document.ptr());
+ set_scope("workspace", workspace.ptr());
+ workspace->root = ProjectSettings::get_singleton()->get_resource_path();
+}
+
+GDScriptLanguageProtocol::~GDScriptLanguageProtocol() {
+ memdelete(server);
+ server = NULL;
+}
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
new file mode 100644
index 0000000000..136b45fd78
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* gdscript_language_protocol.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 GDSCRIPT_PROTOCAL_SERVER_H
+#define GDSCRIPT_PROTOCAL_SERVER_H
+
+#include "gdscript_text_document.h"
+#include "gdscript_workspace.h"
+#include "lsp.hpp"
+#include "modules/jsonrpc/jsonrpc.h"
+#include "modules/websocket/websocket_peer.h"
+#include "modules/websocket/websocket_server.h"
+
+class GDScriptLanguageProtocol : public JSONRPC {
+ GDCLASS(GDScriptLanguageProtocol, JSONRPC)
+
+ enum LSPErrorCode {
+ RequestCancelled = -32800,
+ ContentModified = -32801,
+ };
+
+ static GDScriptLanguageProtocol *singleton;
+
+ HashMap<int, Ref<WebSocketPeer> > clients;
+ WebSocketServer *server;
+ int lastest_client_id;
+
+ Ref<GDScriptTextDocument> text_document;
+ Ref<GDScriptWorkspace> workspace;
+
+ void on_data_received(int p_id);
+ void on_client_connected(int p_id, const String &p_protocal);
+ void on_client_disconnected(int p_id, bool p_was_clean_close);
+
+ String process_message(const String &p_text);
+ String format_output(const String &p_text);
+
+ bool _initialized;
+
+protected:
+ static void _bind_methods();
+
+ Dictionary initialize(const Dictionary &p_params);
+ void initialized(const Variant &p_params);
+
+public:
+ _FORCE_INLINE_ static GDScriptLanguageProtocol *get_singleton() { return singleton; }
+ _FORCE_INLINE_ Ref<GDScriptWorkspace> get_workspace() { return workspace; }
+ _FORCE_INLINE_ Ref<GDScriptTextDocument> get_text_document() { return text_document; }
+ _FORCE_INLINE_ bool is_initialized() const { return _initialized; }
+
+ void poll();
+ Error start(int p_port);
+ void stop();
+
+ void notify_all_clients(const String &p_method, const Variant &p_params = Variant());
+ void notify_client(const String &p_method, const Variant &p_params = Variant(), int p_client = -1);
+
+ bool is_smart_resolve_enabled() const;
+ bool is_goto_native_symbols_enabled() const;
+
+ GDScriptLanguageProtocol();
+ ~GDScriptLanguageProtocol();
+};
+
+#endif
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
new file mode 100644
index 0000000000..62c212a2bd
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -0,0 +1,88 @@
+/*************************************************************************/
+/* gdscript_language_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. */
+/*************************************************************************/
+
+#include "gdscript_language_server.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "editor/editor_node.h"
+
+GDScriptLanguageServer::GDScriptLanguageServer() {
+ thread = NULL;
+ thread_exit = false;
+ _EDITOR_DEF("network/language_server/remote_port", 6008);
+ _EDITOR_DEF("network/language_server/enable_smart_resolve", false);
+ _EDITOR_DEF("network/language_server/show_native_symbols_in_editor", false);
+}
+
+void GDScriptLanguageServer::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ start();
+ break;
+ case NOTIFICATION_EXIT_TREE:
+ stop();
+ break;
+ }
+}
+
+void GDScriptLanguageServer::thread_main(void *p_userdata) {
+ GDScriptLanguageServer *self = static_cast<GDScriptLanguageServer *>(p_userdata);
+ while (!self->thread_exit) {
+ self->protocol.poll();
+ OS::get_singleton()->delay_usec(10);
+ }
+}
+
+void GDScriptLanguageServer::start() {
+ int port = (int)_EDITOR_GET("network/language_server/remote_port");
+ if (protocol.start(port) == OK) {
+ EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR);
+ ERR_FAIL_COND(thread != NULL || thread_exit);
+ thread_exit = false;
+ thread = Thread::create(GDScriptLanguageServer::thread_main, this);
+ }
+}
+
+void GDScriptLanguageServer::stop() {
+ ERR_FAIL_COND(NULL == thread || thread_exit);
+ thread_exit = true;
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+ thread = NULL;
+ protocol.stop();
+ EditorNode::get_log()->add_message("--- GDScript language server stopped ---", EditorLog::MSG_TYPE_EDITOR);
+}
+
+void register_lsp_types() {
+ ClassDB::register_class<GDScriptLanguageProtocol>();
+ ClassDB::register_class<GDScriptTextDocument>();
+ ClassDB::register_class<GDScriptWorkspace>();
+}
diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h
new file mode 100644
index 0000000000..83c2320d98
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_language_server.h
@@ -0,0 +1,60 @@
+/*************************************************************************/
+/* gdscript_language_server.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 GDSCRIPT_LANGUAGE_SERVER_H
+#define GDSCRIPT_LANGUAGE_SERVER_H
+
+#include "../gdscript_parser.h"
+#include "editor/editor_plugin.h"
+#include "gdscript_language_protocol.h"
+
+class GDScriptLanguageServer : public EditorPlugin {
+ GDCLASS(GDScriptLanguageServer, EditorPlugin);
+
+ GDScriptLanguageProtocol protocol;
+
+ Thread *thread;
+ bool thread_exit;
+ static void thread_main(void *p_userdata);
+
+private:
+ void _notification(int p_what);
+ void _iteration();
+
+public:
+ Error parse_script_file(const String &p_path);
+ GDScriptLanguageServer();
+ void start();
+ void stop();
+};
+
+void register_lsp_types();
+
+#endif // GDSCRIPT_LANGUAGE_SERVER_H
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
new file mode 100644
index 0000000000..7c58c7aa15
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -0,0 +1,391 @@
+/*************************************************************************/
+/* gdscript_text_document.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 "gdscript_text_document.h"
+#include "../gdscript.h"
+#include "core/os/os.h"
+#include "editor/editor_settings.h"
+#include "editor/plugins/script_text_editor.h"
+#include "gdscript_extend_parser.h"
+#include "gdscript_language_protocol.h"
+
+void GDScriptTextDocument::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
+ ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
+ ClassDB::bind_method(D_METHOD("documentSymbol"), &GDScriptTextDocument::documentSymbol);
+ ClassDB::bind_method(D_METHOD("completion"), &GDScriptTextDocument::completion);
+ ClassDB::bind_method(D_METHOD("resolve"), &GDScriptTextDocument::resolve);
+ ClassDB::bind_method(D_METHOD("foldingRange"), &GDScriptTextDocument::foldingRange);
+ ClassDB::bind_method(D_METHOD("codeLens"), &GDScriptTextDocument::codeLens);
+ ClassDB::bind_method(D_METHOD("documentLink"), &GDScriptTextDocument::documentLink);
+ ClassDB::bind_method(D_METHOD("colorPresentation"), &GDScriptTextDocument::colorPresentation);
+ ClassDB::bind_method(D_METHOD("hover"), &GDScriptTextDocument::hover);
+ ClassDB::bind_method(D_METHOD("definition"), &GDScriptTextDocument::definition);
+ ClassDB::bind_method(D_METHOD("show_native_symbol_in_editor"), &GDScriptTextDocument::show_native_symbol_in_editor);
+}
+
+void GDScriptTextDocument::didOpen(const Variant &p_param) {
+ lsp::TextDocumentItem doc = load_document_item(p_param);
+ sync_script_content(doc.uri, doc.text);
+}
+
+void GDScriptTextDocument::didChange(const Variant &p_param) {
+ lsp::TextDocumentItem doc = load_document_item(p_param);
+ Dictionary dict = p_param;
+ Array contentChanges = dict["contentChanges"];
+ for (int i = 0; i < contentChanges.size(); ++i) {
+ lsp::TextDocumentContentChangeEvent evt;
+ evt.load(contentChanges[i]);
+ doc.text = evt.text;
+ }
+ sync_script_content(doc.uri, doc.text);
+}
+
+lsp::TextDocumentItem GDScriptTextDocument::load_document_item(const Variant &p_param) {
+ lsp::TextDocumentItem doc;
+ Dictionary params = p_param;
+ doc.load(params["textDocument"]);
+ return doc;
+}
+
+void GDScriptTextDocument::initialize() {
+
+ if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
+
+ const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members;
+
+ const StringName *class_ptr = native_members.next(NULL);
+ while (class_ptr) {
+
+ const ClassMembers &members = native_members.get(*class_ptr);
+
+ const String *name = members.next(NULL);
+ while (name) {
+
+ const lsp::DocumentSymbol *symbol = members.get(*name);
+ lsp::CompletionItem item = symbol->make_completion_item();
+ item.data = JOIN_SYMBOLS(String(*class_ptr), *name);
+ native_member_completions.push_back(item.to_json());
+
+ name = members.next(name);
+ }
+
+ class_ptr = native_members.next(class_ptr);
+ }
+ }
+}
+
+Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {
+ Dictionary params = p_params["textDocument"];
+ String uri = params["uri"];
+ String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(uri);
+ Array arr;
+ if (const Map<String, ExtendGDScriptParser *>::Element *parser = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.find(path)) {
+ Vector<lsp::DocumentedSymbolInformation> list;
+ parser->get()->get_symbols().symbol_tree_as_list(uri, list);
+ for (int i = 0; i < list.size(); i++) {
+ arr.push_back(list[i].to_json());
+ }
+ }
+ return arr;
+}
+
+Array GDScriptTextDocument::completion(const Dictionary &p_params) {
+
+ Array arr;
+
+ lsp::CompletionParams params;
+ params.load(p_params);
+ Dictionary request_data = params.to_json();
+
+ List<ScriptCodeCompletionOption> options;
+ GDScriptLanguageProtocol::get_singleton()->get_workspace()->completion(params, &options);
+
+ if (!options.empty()) {
+
+ int i = 0;
+ arr.resize(options.size());
+
+ for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {
+
+ const ScriptCodeCompletionOption &option = E->get();
+ lsp::CompletionItem item;
+ item.label = option.display;
+ item.data = request_data;
+
+ switch (option.kind) {
+ case ScriptCodeCompletionOption::KIND_ENUM:
+ item.kind = lsp::CompletionItemKind::Enum;
+ break;
+ case ScriptCodeCompletionOption::KIND_CLASS:
+ item.kind = lsp::CompletionItemKind::Class;
+ break;
+ case ScriptCodeCompletionOption::KIND_MEMBER:
+ item.kind = lsp::CompletionItemKind::Property;
+ break;
+ case ScriptCodeCompletionOption::KIND_FUNCTION:
+ item.kind = lsp::CompletionItemKind::Method;
+ break;
+ case ScriptCodeCompletionOption::KIND_SIGNAL:
+ item.kind = lsp::CompletionItemKind::Event;
+ break;
+ case ScriptCodeCompletionOption::KIND_CONSTANT:
+ item.kind = lsp::CompletionItemKind::Constant;
+ break;
+ case ScriptCodeCompletionOption::KIND_VARIABLE:
+ item.kind = lsp::CompletionItemKind::Variable;
+ break;
+ case ScriptCodeCompletionOption::KIND_FILE_PATH:
+ item.kind = lsp::CompletionItemKind::File;
+ break;
+ case ScriptCodeCompletionOption::KIND_NODE_PATH:
+ item.kind = lsp::CompletionItemKind::Snippet;
+ break;
+ case ScriptCodeCompletionOption::KIND_PLAIN_TEXT:
+ item.kind = lsp::CompletionItemKind::Text;
+ break;
+ }
+
+ arr[i] = item.to_json();
+ i++;
+ }
+ } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
+
+ arr = native_member_completions.duplicate();
+
+ for (Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.front(); E; E = E->next()) {
+
+ ExtendGDScriptParser *script = E->get();
+ const Array &items = script->get_member_completions();
+
+ const int start_size = arr.size();
+ arr.resize(start_size + items.size());
+ for (int i = start_size; i < arr.size(); i++) {
+ arr[i] = items[i - start_size];
+ }
+ }
+ }
+ return arr;
+}
+
+Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
+
+ lsp::CompletionItem item;
+ item.load(p_params);
+
+ lsp::CompletionParams params;
+ Variant data = p_params["data"];
+
+ const lsp::DocumentSymbol *symbol = NULL;
+
+ if (data.get_type() == Variant::DICTIONARY) {
+
+ params.load(p_params["data"]);
+ symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params, item.label, item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function);
+
+ } else if (data.get_type() == Variant::STRING) {
+
+ String query = data;
+
+ Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false);
+
+ if (param_symbols.size() >= 2) {
+
+ String class_ = param_symbols[0];
+ StringName class_name = class_;
+ String member_name = param_symbols[param_symbols.size() - 1];
+ String inner_class_name;
+ if (param_symbols.size() >= 3) {
+ inner_class_name = param_symbols[1];
+ }
+
+ if (const ClassMembers *members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members.getptr(class_name)) {
+ if (const lsp::DocumentSymbol *const *member = members->getptr(member_name)) {
+ symbol = *member;
+ }
+ }
+
+ if (!symbol) {
+ if (const Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.find(class_name)) {
+ symbol = E->get()->get_member_symbol(member_name, inner_class_name);
+ }
+ }
+ }
+ }
+
+ if (symbol) {
+ item.documentation = symbol->render();
+ }
+
+ if ((item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function) && !item.label.ends_with("):")) {
+ item.insertText = item.label + "(";
+ if (symbol && symbol->detail.find(",") == -1) {
+ item.insertText += ")";
+ }
+ } else if (item.kind == lsp::CompletionItemKind::Event) {
+ if (params.context.triggerKind == lsp::CompletionTriggerKind::TriggerCharacter && (params.context.triggerCharacter == "(")) {
+ const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
+ item.insertText = quote_style + item.label + quote_style;
+ }
+ }
+
+ return item.to_json(true);
+}
+
+Array GDScriptTextDocument::foldingRange(const Dictionary &p_params) {
+ Dictionary params = p_params["textDocument"];
+ String path = params["uri"];
+ Array arr;
+ return arr;
+}
+
+Array GDScriptTextDocument::codeLens(const Dictionary &p_params) {
+ Array arr;
+ return arr;
+}
+
+Variant GDScriptTextDocument::documentLink(const Dictionary &p_params) {
+ Variant ret;
+ return ret;
+}
+
+Array GDScriptTextDocument::colorPresentation(const Dictionary &p_params) {
+ Array arr;
+ return arr;
+}
+
+Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
+
+ lsp::TextDocumentPositionParams params;
+ params.load(p_params);
+
+ const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params);
+ if (symbol) {
+
+ lsp::Hover hover;
+ hover.contents = symbol->render();
+ return hover.to_json();
+
+ } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
+
+ Dictionary ret;
+ Array contents;
+ List<const lsp::DocumentSymbol *> list;
+ GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(params, list);
+ for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) {
+ if (const lsp::DocumentSymbol *s = E->get()) {
+ contents.push_back(s->render().value);
+ }
+ }
+ ret["contents"] = contents;
+ return ret;
+ }
+
+ return Variant();
+}
+
+Array GDScriptTextDocument::definition(const Dictionary &p_params) {
+ Array arr;
+
+ lsp::TextDocumentPositionParams params;
+ params.load(p_params);
+
+ const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params);
+ if (symbol) {
+ lsp::Location location;
+ location.uri = symbol->uri;
+ location.range = symbol->range;
+
+ const String &path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(symbol->uri);
+ if (file_checker->file_exists(path)) {
+ arr.push_back(location.to_json());
+ } else if (!symbol->native_class.empty() && GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) {
+ String id;
+ switch (symbol->kind) {
+ case lsp::SymbolKind::Class:
+ id = "class_name:" + symbol->name;
+ break;
+ case lsp::SymbolKind::Constant:
+ id = "class_constant:" + symbol->native_class + ":" + symbol->name;
+ break;
+ case lsp::SymbolKind::Property:
+ case lsp::SymbolKind::Variable:
+ id = "class_property:" + symbol->native_class + ":" + symbol->name;
+ break;
+ case lsp::SymbolKind::Enum:
+ id = "class_enum:" + symbol->native_class + ":" + symbol->name;
+ break;
+ case lsp::SymbolKind::Method:
+ case lsp::SymbolKind::Function:
+ id = "class_method:" + symbol->native_class + ":" + symbol->name;
+ break;
+ default:
+ id = "class_global:" + symbol->native_class + ":" + symbol->name;
+ break;
+ }
+ call_deferred("show_native_symbol_in_editor", id);
+ }
+ } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
+
+ List<const lsp::DocumentSymbol *> list;
+ GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(params, list);
+ for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) {
+
+ if (const lsp::DocumentSymbol *s = E->get()) {
+ if (!s->uri.empty()) {
+ lsp::Location location;
+ location.uri = s->uri;
+ location.range = s->range;
+ arr.push_back(location.to_json());
+ }
+ }
+ }
+ }
+
+ return arr;
+}
+
+GDScriptTextDocument::GDScriptTextDocument() {
+ file_checker = FileAccess::create(FileAccess::ACCESS_RESOURCES);
+}
+
+GDScriptTextDocument::~GDScriptTextDocument() {
+ memdelete(file_checker);
+}
+
+void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) {
+ String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path);
+ GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content);
+}
+
+void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {
+ ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id);
+ OS::get_singleton()->move_window_to_foreground();
+}
diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h
new file mode 100644
index 0000000000..d15022d2c4
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_text_document.h
@@ -0,0 +1,73 @@
+/*************************************************************************/
+/* gdscript_text_document.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 GDSCRIPT_TEXT_DOCUMENT_H
+#define GDSCRIPT_TEXT_DOCUMENT_H
+
+#include "core/os/file_access.h"
+#include "core/reference.h"
+#include "lsp.hpp"
+
+class GDScriptTextDocument : public Reference {
+ GDCLASS(GDScriptTextDocument, Reference)
+protected:
+ static void _bind_methods();
+
+ FileAccess *file_checker;
+
+ void didOpen(const Variant &p_param);
+ void didChange(const Variant &p_param);
+
+ void sync_script_content(const String &p_path, const String &p_content);
+ void show_native_symbol_in_editor(const String &p_symbol_id);
+
+ Array native_member_completions;
+
+private:
+ lsp::TextDocumentItem load_document_item(const Variant &p_param);
+
+public:
+ Array documentSymbol(const Dictionary &p_params);
+ Array completion(const Dictionary &p_params);
+ Dictionary resolve(const Dictionary &p_params);
+ Array foldingRange(const Dictionary &p_params);
+ Array codeLens(const Dictionary &p_params);
+ Variant documentLink(const Dictionary &p_params);
+ Array colorPresentation(const Dictionary &p_params);
+ Variant hover(const Dictionary &p_params);
+ Array definition(const Dictionary &p_params);
+
+ void initialize();
+
+ GDScriptTextDocument();
+ virtual ~GDScriptTextDocument();
+};
+
+#endif
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
new file mode 100644
index 0000000000..1901daacff
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -0,0 +1,504 @@
+/*************************************************************************/
+/* gdscript_workspace.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 "gdscript_workspace.h"
+#include "../gdscript.h"
+#include "../gdscript_parser.h"
+#include "core/project_settings.h"
+#include "core/script_language.h"
+#include "editor/editor_help.h"
+#include "gdscript_language_protocol.h"
+
+void GDScriptWorkspace::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol);
+ ClassDB::bind_method(D_METHOD("parse_script", "p_path", "p_content"), &GDScriptWorkspace::parse_script);
+ ClassDB::bind_method(D_METHOD("parse_local_script", "p_path"), &GDScriptWorkspace::parse_local_script);
+ ClassDB::bind_method(D_METHOD("get_file_path", "p_uri"), &GDScriptWorkspace::get_file_path);
+ ClassDB::bind_method(D_METHOD("get_file_uri", "p_path"), &GDScriptWorkspace::get_file_uri);
+ ClassDB::bind_method(D_METHOD("publish_diagnostics", "p_path"), &GDScriptWorkspace::publish_diagnostics);
+ ClassDB::bind_method(D_METHOD("generate_script_api", "p_path"), &GDScriptWorkspace::generate_script_api);
+}
+
+void GDScriptWorkspace::remove_cache_parser(const String &p_path) {
+ Map<String, ExtendGDScriptParser *>::Element *parser = parse_results.find(p_path);
+ Map<String, ExtendGDScriptParser *>::Element *script = scripts.find(p_path);
+ if (parser && script) {
+ if (script->get() && script->get() == script->get()) {
+ memdelete(script->get());
+ } else {
+ memdelete(script->get());
+ memdelete(parser->get());
+ }
+ parse_results.erase(p_path);
+ scripts.erase(p_path);
+ } else if (parser) {
+ memdelete(parser->get());
+ parse_results.erase(p_path);
+ } else if (script) {
+ memdelete(script->get());
+ scripts.erase(p_path);
+ }
+}
+
+const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_class, const String &p_member) const {
+
+ StringName class_name = p_class;
+ StringName empty;
+
+ while (class_name != empty) {
+ if (const Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(class_name)) {
+ const lsp::DocumentSymbol &class_symbol = E->value();
+
+ if (p_member.empty()) {
+ return &class_symbol;
+ } else {
+ for (int i = 0; i < class_symbol.children.size(); i++) {
+ const lsp::DocumentSymbol &symbol = class_symbol.children[i];
+ if (symbol.name == p_member) {
+ return &symbol;
+ }
+ }
+ }
+ }
+ class_name = ClassDB::get_parent_class(class_name);
+ }
+
+ return NULL;
+}
+
+const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_path) const {
+ const Map<String, ExtendGDScriptParser *>::Element *S = scripts.find(p_path);
+ if (S) {
+ return &(S->get()->get_symbols());
+ }
+ return NULL;
+}
+
+void GDScriptWorkspace::reload_all_workspace_scripts() {
+ List<String> pathes;
+ list_script_files("res://", pathes);
+ for (List<String>::Element *E = pathes.front(); E; E = E->next()) {
+ const String &path = E->get();
+ Error err;
+ String content = FileAccess::get_file_as_string(path, &err);
+ ERR_CONTINUE(err != OK);
+ err = parse_script(path, content);
+
+ if (err != OK) {
+ Map<String, ExtendGDScriptParser *>::Element *S = parse_results.find(path);
+ String err_msg = "Failed parse script " + path;
+ if (S) {
+ err_msg += "\n" + S->get()->get_error();
+ }
+ ERR_EXPLAIN(err_msg);
+ ERR_CONTINUE(err != OK);
+ }
+ }
+}
+
+void GDScriptWorkspace::list_script_files(const String &p_root_dir, List<String> &r_files) {
+ Error err;
+ DirAccessRef dir = DirAccess::open(p_root_dir, &err);
+ if (OK == err) {
+ dir->list_dir_begin();
+ String file_name = dir->get_next();
+ while (file_name.length()) {
+ if (dir->current_is_dir() && file_name != "." && file_name != ".." && file_name != "./") {
+ list_script_files(p_root_dir.plus_file(file_name), r_files);
+ } else if (file_name.ends_with(".gd")) {
+ String script_file = p_root_dir.plus_file(file_name);
+ r_files.push_back(script_file);
+ }
+ file_name = dir->get_next();
+ }
+ }
+}
+
+ExtendGDScriptParser *GDScriptWorkspace::get_parse_successed_script(const String &p_path) {
+ const Map<String, ExtendGDScriptParser *>::Element *S = scripts.find(p_path);
+ if (!S) {
+ parse_local_script(p_path);
+ S = scripts.find(p_path);
+ }
+ if (S) {
+ return S->get();
+ }
+ return NULL;
+}
+
+ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path) {
+ const Map<String, ExtendGDScriptParser *>::Element *S = parse_results.find(p_path);
+ if (!S) {
+ parse_local_script(p_path);
+ S = parse_results.find(p_path);
+ }
+ if (S) {
+ return S->get();
+ }
+ return NULL;
+}
+
+Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
+ String query = p_params["query"];
+ Array arr;
+ if (!query.empty()) {
+ for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) {
+ Vector<lsp::DocumentedSymbolInformation> script_symbols;
+ E->get()->get_symbols().symbol_tree_as_list(E->key(), script_symbols);
+ for (int i = 0; i < script_symbols.size(); ++i) {
+ if (query.is_subsequence_ofi(script_symbols[i].name)) {
+ arr.push_back(script_symbols[i].to_json());
+ }
+ }
+ }
+ }
+ return arr;
+}
+
+Error GDScriptWorkspace::initialize() {
+ if (initialized) return OK;
+
+ DocData *doc = EditorHelp::get_doc_data();
+ for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
+
+ const DocData::ClassDoc &class_data = E->value();
+ lsp::DocumentSymbol class_symbol;
+ String class_name = E->key();
+ class_symbol.name = class_name;
+ class_symbol.native_class = class_name;
+ class_symbol.kind = lsp::SymbolKind::Class;
+ class_symbol.detail = String("<Native> class ") + class_name;
+ if (!class_data.inherits.empty()) {
+ class_symbol.detail += " extends " + class_data.inherits;
+ }
+ class_symbol.documentation = ExtendGDScriptParser::marked_documentation(class_data.brief_description) + "\n" + ExtendGDScriptParser::marked_documentation(class_data.description);
+
+ for (int i = 0; i < class_data.constants.size(); i++) {
+ const DocData::ConstantDoc &const_data = class_data.constants[i];
+ lsp::DocumentSymbol symbol;
+ symbol.name = const_data.name;
+ symbol.native_class = class_name;
+ symbol.kind = lsp::SymbolKind::Constant;
+ symbol.detail = "const " + class_name + "." + const_data.name;
+ if (const_data.enumeration.length()) {
+ symbol.detail += ": " + const_data.enumeration;
+ }
+ symbol.detail += " = " + const_data.value;
+ symbol.documentation = ExtendGDScriptParser::marked_documentation(const_data.description);
+ class_symbol.children.push_back(symbol);
+ }
+
+ Vector<DocData::PropertyDoc> properties;
+ properties.append_array(class_data.properties);
+ const int theme_prop_start_idx = properties.size();
+ properties.append_array(class_data.theme_properties);
+
+ for (int i = 0; i < class_data.properties.size(); i++) {
+ const DocData::PropertyDoc &data = class_data.properties[i];
+ lsp::DocumentSymbol symbol;
+ symbol.name = data.name;
+ symbol.native_class = class_name;
+ symbol.kind = lsp::SymbolKind::Property;
+ symbol.detail = String(i >= theme_prop_start_idx ? "<Theme> var" : "var") + " " + class_name + "." + data.name;
+ if (data.enumeration.length()) {
+ symbol.detail += ": " + data.enumeration;
+ } else {
+ symbol.detail += ": " + data.type;
+ }
+ symbol.documentation = ExtendGDScriptParser::marked_documentation(data.description);
+ class_symbol.children.push_back(symbol);
+ }
+
+ Vector<DocData::MethodDoc> methods_signals;
+ methods_signals.append_array(class_data.methods);
+ const int signal_start_idx = methods_signals.size();
+ methods_signals.append_array(class_data.signals);
+
+ for (int i = 0; i < methods_signals.size(); i++) {
+ const DocData::MethodDoc &data = methods_signals[i];
+
+ lsp::DocumentSymbol symbol;
+ symbol.name = data.name;
+ symbol.native_class = class_name;
+ symbol.kind = i >= signal_start_idx ? lsp::SymbolKind::Event : lsp::SymbolKind::Method;
+
+ String params = "";
+ bool arg_default_value_started = false;
+ for (int j = 0; j < data.arguments.size(); j++) {
+ const DocData::ArgumentDoc &arg = data.arguments[j];
+ if (!arg_default_value_started && !arg.default_value.empty()) {
+ arg_default_value_started = true;
+ }
+ String arg_str = arg.name + ": " + arg.type;
+ if (arg_default_value_started) {
+ arg_str += " = " + arg.default_value;
+ }
+ if (j < data.arguments.size() - 1) {
+ arg_str += ", ";
+ }
+ params += arg_str;
+ }
+ if (data.qualifiers.find("vararg") != -1) {
+ params += params.empty() ? "..." : ", ...";
+ }
+
+ symbol.detail = "func " + class_name + "." + data.name + "(" + params + ") -> " + data.return_type;
+ symbol.documentation = ExtendGDScriptParser::marked_documentation(data.description);
+ class_symbol.children.push_back(symbol);
+ }
+
+ native_symbols.insert(class_name, class_symbol);
+ }
+
+ reload_all_workspace_scripts();
+
+ if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
+ for (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.front(); E; E = E->next()) {
+ ClassMembers members;
+ const lsp::DocumentSymbol &class_symbol = E->get();
+ for (int i = 0; i < class_symbol.children.size(); i++) {
+ const lsp::DocumentSymbol &symbol = class_symbol.children[i];
+ members.set(symbol.name, &symbol);
+ }
+ native_members.set(E->key(), members);
+ }
+
+ // cache member completions
+ for (Map<String, ExtendGDScriptParser *>::Element *S = scripts.front(); S; S = S->next()) {
+ S->get()->get_member_completions();
+ }
+ }
+
+ return OK;
+}
+
+Error GDScriptWorkspace::parse_script(const String &p_path, const String &p_content) {
+
+ ExtendGDScriptParser *parser = memnew(ExtendGDScriptParser);
+ Error err = parser->parse(p_content, p_path);
+ Map<String, ExtendGDScriptParser *>::Element *last_parser = parse_results.find(p_path);
+ Map<String, ExtendGDScriptParser *>::Element *last_script = scripts.find(p_path);
+
+ if (err == OK) {
+
+ remove_cache_parser(p_path);
+ parse_results[p_path] = parser;
+ scripts[p_path] = parser;
+
+ } else {
+ if (last_parser && last_script && last_parser->get() != last_script->get()) {
+ memdelete(last_parser->get());
+ }
+ parse_results[p_path] = parser;
+ }
+
+ publish_diagnostics(p_path);
+
+ return err;
+}
+
+Error GDScriptWorkspace::parse_local_script(const String &p_path) {
+ Error err;
+ String content = FileAccess::get_file_as_string(p_path, &err);
+ if (err == OK) {
+ err = parse_script(p_path, content);
+ }
+ return err;
+}
+
+String GDScriptWorkspace::get_file_path(const String &p_uri) const {
+ String path = p_uri;
+ path = path.replace(root_uri + "/", "res://");
+ path = path.http_unescape();
+ return path;
+}
+
+String GDScriptWorkspace::get_file_uri(const String &p_path) const {
+ String uri = p_path;
+ uri = uri.replace("res://", root_uri + "/");
+ return uri;
+}
+
+void GDScriptWorkspace::publish_diagnostics(const String &p_path) {
+ Dictionary params;
+ Array errors;
+ const Map<String, ExtendGDScriptParser *>::Element *ele = parse_results.find(p_path);
+ if (ele) {
+ const Vector<lsp::Diagnostic> &list = ele->get()->get_diagnostics();
+ errors.resize(list.size());
+ for (int i = 0; i < list.size(); ++i) {
+ errors[i] = list[i].to_json();
+ }
+ }
+ params["diagnostics"] = errors;
+ params["uri"] = get_file_uri(p_path);
+ GDScriptLanguageProtocol::get_singleton()->notify_client("textDocument/publishDiagnostics", params);
+}
+
+void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) {
+
+ String path = get_file_path(p_params.textDocument.uri);
+ String call_hint;
+ bool forced = false;
+
+ if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
+ String code = parser->get_text_for_completion(p_params.position);
+ GDScriptLanguage::get_singleton()->complete_code(code, path, NULL, r_options, forced, call_hint);
+ }
+}
+
+const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) {
+
+ const lsp::DocumentSymbol *symbol = NULL;
+
+ String path = get_file_path(p_doc_pos.textDocument.uri);
+ if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
+
+ String symbol_identifier = p_symbol_name;
+ Vector<String> identifier_parts = symbol_identifier.split("(");
+ if (identifier_parts.size()) {
+ symbol_identifier = identifier_parts[0];
+ }
+
+ lsp::Position pos = p_doc_pos.position;
+ if (symbol_identifier.empty()) {
+ Vector2i offset;
+ symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
+ pos.character += offset.y;
+ }
+
+ if (!symbol_identifier.empty()) {
+
+ if (ScriptServer::is_global_class(symbol_identifier)) {
+
+ String class_path = ScriptServer::get_global_class_path(symbol_identifier);
+ symbol = get_script_symbol(class_path);
+
+ } else {
+
+ ScriptLanguage::LookupResult ret;
+ if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, NULL, ret)) {
+
+ if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) {
+
+ String target_script_path = path;
+ if (!ret.script.is_null()) {
+ target_script_path = ret.script->get_path();
+ }
+
+ if (const ExtendGDScriptParser *target_parser = get_parse_result(target_script_path)) {
+ symbol = target_parser->get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(ret.location));
+ }
+
+ } else {
+
+ String member = ret.class_member;
+ if (member.empty() && symbol_identifier != ret.class_name) {
+ member = symbol_identifier;
+ }
+ symbol = get_native_symbol(ret.class_name, member);
+ }
+ } else {
+ symbol = parser->get_member_symbol(symbol_identifier);
+ }
+ }
+ }
+ }
+
+ return symbol;
+}
+
+void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list) {
+
+ String path = get_file_path(p_doc_pos.textDocument.uri);
+ if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
+
+ String symbol_identifier;
+ Vector2i offset;
+ symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
+
+ const StringName *class_ptr = native_members.next(NULL);
+ while (class_ptr) {
+ const ClassMembers &members = native_members.get(*class_ptr);
+ if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) {
+ r_list.push_back(*symbol);
+ }
+ class_ptr = native_members.next(class_ptr);
+ }
+
+ for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) {
+ const ExtendGDScriptParser *script = E->get();
+ const ClassMembers &members = script->get_members();
+ if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) {
+ r_list.push_back(*symbol);
+ }
+
+ const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes();
+ const String *_class = inner_classes.next(NULL);
+ while (_class) {
+
+ const ClassMembers *inner_class = inner_classes.getptr(*_class);
+ if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) {
+ r_list.push_back(*symbol);
+ }
+
+ _class = inner_classes.next(_class);
+ }
+ }
+ }
+}
+
+Dictionary GDScriptWorkspace::generate_script_api(const String &p_path) {
+ Dictionary api;
+ if (const ExtendGDScriptParser *parser = get_parse_successed_script(p_path)) {
+ api = parser->generate_api();
+ }
+ return api;
+}
+
+GDScriptWorkspace::GDScriptWorkspace() {
+ ProjectSettings::get_singleton()->get_resource_path();
+}
+
+GDScriptWorkspace::~GDScriptWorkspace() {
+ Set<String> cached_parsers;
+
+ for (Map<String, ExtendGDScriptParser *>::Element *E = parse_results.front(); E; E = E->next()) {
+ cached_parsers.insert(E->key());
+ }
+
+ for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) {
+ cached_parsers.insert(E->key());
+ }
+
+ for (Set<String>::Element *E = cached_parsers.front(); E; E = E->next()) {
+ remove_cache_parser(E->get());
+ }
+}
diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h
new file mode 100644
index 0000000000..adce169d4b
--- /dev/null
+++ b/modules/gdscript/language_server/gdscript_workspace.h
@@ -0,0 +1,91 @@
+/*************************************************************************/
+/* gdscript_workspace.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 GDSCRIPT_WORKSPACE_H
+#define GDSCRIPT_WORKSPACE_H
+
+#include "../gdscript_parser.h"
+#include "core/variant.h"
+#include "gdscript_extend_parser.h"
+#include "lsp.hpp"
+
+class GDScriptWorkspace : public Reference {
+ GDCLASS(GDScriptWorkspace, Reference);
+
+protected:
+ static void _bind_methods();
+ void remove_cache_parser(const String &p_path);
+ bool initialized = false;
+ Map<StringName, lsp::DocumentSymbol> native_symbols;
+
+ const lsp::DocumentSymbol *get_native_symbol(const String &p_class, const String &p_member = "") const;
+ const lsp::DocumentSymbol *get_script_symbol(const String &p_path) const;
+
+ void reload_all_workspace_scripts();
+
+ ExtendGDScriptParser *get_parse_successed_script(const String &p_path);
+ ExtendGDScriptParser *get_parse_result(const String &p_path);
+
+ void strip_flat_symbols(const String &p_branch);
+ void list_script_files(const String &p_root_dir, List<String> &r_files);
+
+public:
+ String root;
+ String root_uri;
+
+ Map<String, ExtendGDScriptParser *> scripts;
+ Map<String, ExtendGDScriptParser *> parse_results;
+ HashMap<StringName, ClassMembers> native_members;
+
+public:
+ Array symbol(const Dictionary &p_params);
+
+public:
+ Error initialize();
+
+ Error parse_script(const String &p_path, const String &p_content);
+ Error parse_local_script(const String &p_path);
+
+ String get_file_path(const String &p_uri) const;
+ String get_file_uri(const String &p_path) const;
+
+ void publish_diagnostics(const String &p_path);
+ void completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options);
+
+ const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_requred = false);
+ void resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list);
+
+ Dictionary generate_script_api(const String &p_path);
+
+ GDScriptWorkspace();
+ ~GDScriptWorkspace();
+};
+
+#endif
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
new file mode 100644
index 0000000000..3e57b6ee7e
--- /dev/null
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -0,0 +1,1506 @@
+/*************************************************************************/
+/* lsp.hpp */
+/*************************************************************************/
+/* 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 GODOT_LSP_H
+#define GODOT_LSP_H
+
+#include "core/variant.h"
+
+namespace lsp {
+
+typedef String DocumentUri;
+
+/**
+ * Text documents are identified using a URI. On the protocol level, URIs are passed as strings.
+ */
+struct TextDocumentIdentifier {
+ /**
+ * The text document's URI.
+ */
+ DocumentUri uri;
+
+ _FORCE_INLINE_ void load(const Dictionary &p_params) {
+ uri = p_params["uri"];
+ }
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["uri"] = uri;
+ return dict;
+ }
+};
+
+/**
+ * Position in a text document expressed as zero-based line and zero-based character offset.
+ * A position is between two characters like an ‘insert’ cursor in a editor.
+ * Special values like for example -1 to denote the end of a line are not supported.
+ */
+struct Position {
+ /**
+ * Line position in a document (zero-based).
+ */
+ int line = 0;
+
+ /**
+ * Character offset on a line in a document (zero-based). Assuming that the line is
+ * represented as a string, the `character` value represents the gap between the
+ * `character` and `character + 1`.
+ *
+ * If the character value is greater than the line length it defaults back to the
+ * line length.
+ */
+ int character = 0;
+
+ _FORCE_INLINE_ void load(const Dictionary &p_params) {
+ line = p_params["line"];
+ character = p_params["character"];
+ }
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["line"] = line;
+ dict["character"] = character;
+ return dict;
+ }
+};
+
+/**
+ * A range in a text document expressed as (zero-based) start and end positions.
+ * A range is comparable to a selection in an editor. Therefore the end position is exclusive.
+ * If you want to specify a range that contains a line including the line ending character(s) then use an end position denoting the start of the next line.
+ */
+struct Range {
+ /**
+ * The range's start position.
+ */
+ Position start;
+
+ /**
+ * The range's end position.
+ */
+ Position end;
+
+ _FORCE_INLINE_ void load(const Dictionary &p_params) {
+ start.load(p_params["start"]);
+ end.load(p_params["end"]);
+ }
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["start"] = start.to_json();
+ dict["end"] = end.to_json();
+ return dict;
+ }
+};
+
+/**
+ * Represents a location inside a resource, such as a line inside a text file.
+ */
+struct Location {
+ DocumentUri uri;
+ Range range;
+
+ _FORCE_INLINE_ void load(const Dictionary &p_params) {
+ uri = p_params["uri"];
+ range.load(p_params["range"]);
+ }
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["uri"] = uri;
+ dict["range"] = range.to_json();
+ return dict;
+ }
+};
+
+/**
+ * Represents a link between a source and a target location.
+ */
+struct LocationLink {
+
+ /**
+ * Span of the origin of this link.
+ *
+ * Used as the underlined span for mouse interaction. Defaults to the word range at
+ * the mouse position.
+ */
+ Range *originSelectionRange = NULL;
+
+ /**
+ * The target resource identifier of this link.
+ */
+ String targetUri;
+
+ /**
+ * The full target range of this link. If the target for example is a symbol then target range is the
+ * range enclosing this symbol not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to highlight the range in the editor.
+ */
+ Range targetRange;
+
+ /**
+ * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+ * Must be contained by the the `targetRange`. See also `DocumentSymbol#range`
+ */
+ Range targetSelectionRange;
+};
+
+/**
+ * A parameter literal used in requests to pass a text document and a position inside that document.
+ */
+struct TextDocumentPositionParams {
+ /**
+ * The text document.
+ */
+ TextDocumentIdentifier textDocument;
+
+ /**
+ * The position inside the text document.
+ */
+ Position position;
+
+ _FORCE_INLINE_ void load(const Dictionary &p_params) {
+ textDocument.load(p_params["textDocument"]);
+ position.load(p_params["position"]);
+ }
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["textDocument"] = textDocument.to_json();
+ dict["position"] = position.to_json();
+ return dict;
+ }
+};
+
+/**
+ * A textual edit applicable to a text document.
+ */
+struct TextEdit {
+ /**
+ * The range of the text document to be manipulated. To insert
+ * text into a document create a range where start === end.
+ */
+ Range range;
+
+ /**
+ * The string to be inserted. For delete operations use an
+ * empty string.
+ */
+ String newText;
+};
+
+/**
+ * Represents a reference to a command.
+ * Provides a title which will be used to represent a command in the UI.
+ * Commands are identified by a string identifier.
+ * The recommended way to handle commands is to implement their execution on the server side if the client and server provides the corresponding capabilities.
+ * Alternatively the tool extension code could handle the command. The protocol currently doesn’t specify a set of well-known commands.
+ */
+struct Command {
+ /**
+ * Title of the command, like `save`.
+ */
+ String title;
+ /**
+ * The identifier of the actual command handler.
+ */
+ String command;
+ /**
+ * Arguments that the command handler should be
+ * invoked with.
+ */
+ Array arguments;
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["title"] = title;
+ dict["command"] = command;
+ if (arguments.size()) dict["arguments"] = arguments;
+ return dict;
+ }
+};
+
+namespace TextDocumentSyncKind {
+/**
+ * Documents should not be synced at all.
+ */
+static const int None = 0;
+
+/**
+ * Documents are synced by always sending the full content
+ * of the document.
+ */
+static const int Full = 1;
+
+/**
+ * Documents are synced by sending the full content on open.
+ * After that only incremental updates to the document are
+ * send.
+ */
+static const int Incremental = 2;
+}; // namespace TextDocumentSyncKind
+
+/**
+ * Completion options.
+ */
+struct CompletionOptions {
+ /**
+ * The server provides support to resolve additional
+ * information for a completion item.
+ */
+ bool resolveProvider = true;
+
+ /**
+ * The characters that trigger completion automatically.
+ */
+ Vector<String> triggerCharacters;
+
+ CompletionOptions() {
+ triggerCharacters.push_back(".");
+ triggerCharacters.push_back("$");
+ triggerCharacters.push_back("'");
+ triggerCharacters.push_back("\"");
+ triggerCharacters.push_back("(");
+ triggerCharacters.push_back(",");
+ }
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["resolveProvider"] = resolveProvider;
+ dict["triggerCharacters"] = triggerCharacters;
+ return dict;
+ }
+};
+
+/**
+ * Signature help options.
+ */
+struct SignatureHelpOptions {
+ /**
+ * The characters that trigger signature help
+ * automatically.
+ */
+ Vector<String> triggerCharacters;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["triggerCharacters"] = triggerCharacters;
+ return dict;
+ }
+};
+
+/**
+ * Code Lens options.
+ */
+struct CodeLensOptions {
+ /**
+ * Code lens has a resolve provider as well.
+ */
+ bool resolveProvider = false;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["resolveProvider"] = resolveProvider;
+ return dict;
+ }
+};
+
+/**
+ * Rename options
+ */
+struct RenameOptions {
+ /**
+ * Renames should be checked and tested before being executed.
+ */
+ bool prepareProvider = false;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["prepareProvider"] = prepareProvider;
+ return dict;
+ }
+};
+
+/**
+ * Document link options.
+ */
+struct DocumentLinkOptions {
+ /**
+ * Document links have a resolve provider as well.
+ */
+ bool resolveProvider = false;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["resolveProvider"] = resolveProvider;
+ return dict;
+ }
+};
+
+/**
+ * Execute command options.
+ */
+struct ExecuteCommandOptions {
+ /**
+ * The commands to be executed on the server
+ */
+ Vector<String> commands;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["commands"] = commands;
+ return dict;
+ }
+};
+
+/**
+ * Save options.
+ */
+struct SaveOptions {
+ /**
+ * The client is supposed to include the content on save.
+ */
+ bool includeText = true;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["includeText"] = includeText;
+ return dict;
+ }
+};
+
+/**
+ * Color provider options.
+ */
+struct ColorProviderOptions {
+ Dictionary to_json() {
+ Dictionary dict;
+ return dict;
+ }
+};
+
+/**
+ * Folding range provider options.
+ */
+struct FoldingRangeProviderOptions {
+ Dictionary to_json() {
+ Dictionary dict;
+ return dict;
+ }
+};
+
+struct TextDocumentSyncOptions {
+ /**
+ * Open and close notifications are sent to the server. If omitted open close notification should not
+ * be sent.
+ */
+ bool openClose = true;
+
+ /**
+ * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+ * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
+ */
+ int change = TextDocumentSyncKind::Full;
+
+ /**
+ * If present will save notifications are sent to the server. If omitted the notification should not be
+ * sent.
+ */
+ bool willSave = false;
+
+ /**
+ * If present will save wait until requests are sent to the server. If omitted the request should not be
+ * sent.
+ */
+ bool willSaveWaitUntil = false;
+
+ /**
+ * If present save notifications are sent to the server. If omitted the notification should not be
+ * sent.
+ */
+ SaveOptions save;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["willSaveWaitUntil"] = willSaveWaitUntil;
+ dict["willSave"] = willSave;
+ dict["openClose"] = openClose;
+ dict["change"] = change;
+ dict["change"] = save.to_json();
+ return dict;
+ }
+};
+
+/**
+ * Static registration options to be returned in the initialize request.
+ */
+struct StaticRegistrationOptions {
+ /**
+ * The id used to register the request. The id can be used to deregister
+ * the request again. See also Registration#id.
+ */
+ String id;
+};
+
+/**
+ * Format document on type options.
+ */
+struct DocumentOnTypeFormattingOptions {
+ /**
+ * A character on which formatting should be triggered, like `}`.
+ */
+ String firstTriggerCharacter;
+
+ /**
+ * More trigger characters.
+ */
+ Vector<String> moreTriggerCharacter;
+
+ Dictionary to_json() {
+ Dictionary dict;
+ dict["firstTriggerCharacter"] = firstTriggerCharacter;
+ dict["moreTriggerCharacter"] = moreTriggerCharacter;
+ return dict;
+ }
+};
+
+struct TextDocumentItem {
+ /**
+ * The text document's URI.
+ */
+ DocumentUri uri;
+
+ /**
+ * The text document's language identifier.
+ */
+ String languageId;
+
+ /**
+ * The version number of this document (it will increase after each
+ * change, including undo/redo).
+ */
+ int version;
+
+ /**
+ * The content of the opened text document.
+ */
+ String text;
+
+ void load(const Dictionary &p_dict) {
+ uri = p_dict["uri"];
+ languageId = p_dict["languageId"];
+ version = p_dict["version"];
+ text = p_dict["text"];
+ }
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["uri"] = uri;
+ dict["languageId"] = languageId;
+ dict["version"] = version;
+ dict["text"] = text;
+ return dict;
+ }
+};
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted
+ * the new text is considered to be the full content of the document.
+ */
+struct TextDocumentContentChangeEvent {
+ /**
+ * The range of the document that changed.
+ */
+ Range range;
+
+ /**
+ * The length of the range that got replaced.
+ */
+ int rangeLength;
+
+ /**
+ * The new text of the range/document.
+ */
+ String text;
+
+ void load(const Dictionary &p_params) {
+ text = p_params["text"];
+ rangeLength = p_params["rangeLength"];
+ range.load(p_params["range"]);
+ }
+};
+
+namespace DiagnosticSeverity {
+/**
+ * Reports an error.
+ */
+static const int Error = 1;
+/**
+ * Reports a warning.
+ */
+static const int Warning = 2;
+/**
+ * Reports an information.
+ */
+static const int Information = 3;
+/**
+ * Reports a hint.
+ */
+static const int Hint = 4;
+}; // namespace DiagnosticSeverity
+
+/**
+ * Represents a related message and source code location for a diagnostic. This should be
+ * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+ * a symbol in a scope.
+ */
+struct DiagnosticRelatedInformation {
+ /**
+ * The location of this related diagnostic information.
+ */
+ Location location;
+
+ /**
+ * The message of this related diagnostic information.
+ */
+ String message;
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["location"] = location.to_json(),
+ dict["message"] = message;
+ return dict;
+ }
+};
+
+/**
+ * Represents a diagnostic, such as a compiler error or warning.
+ * Diagnostic objects are only valid in the scope of a resource.
+ */
+struct Diagnostic {
+ /**
+ * The range at which the message applies.
+ */
+ Range range;
+
+ /**
+ * The diagnostic's severity. Can be omitted. If omitted it is up to the
+ * client to interpret diagnostics as error, warning, info or hint.
+ */
+ int severity;
+
+ /**
+ * The diagnostic's code, which might appear in the user interface.
+ */
+ int code;
+
+ /**
+ * A human-readable string describing the source of this
+ * diagnostic, e.g. 'typescript' or 'super lint'.
+ */
+ String source;
+
+ /**
+ * The diagnostic's message.
+ */
+ String message;
+
+ /**
+ * An array of related diagnostic information, e.g. when symbol-names within
+ * a scope collide all definitions can be marked via this property.
+ */
+ Vector<DiagnosticRelatedInformation> relatedInformation;
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["range"] = range.to_json();
+ dict["code"] = code;
+ dict["severity"] = severity;
+ dict["message"] = message;
+ dict["source"] = source;
+ if (!relatedInformation.empty()) {
+ Array arr;
+ arr.resize(relatedInformation.size());
+ for (int i = 0; i < relatedInformation.size(); i++) {
+ arr[i] = relatedInformation[i].to_json();
+ }
+ dict["relatedInformation"] = arr;
+ }
+ return dict;
+ }
+};
+
+/**
+ * Describes the content type that a client supports in various
+ * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
+ *
+ * Please note that `MarkupKinds` must not start with a `$`. This kinds
+ * are reserved for internal usage.
+ */
+namespace MarkupKind {
+static const String PlainText = "plaintext";
+static const String Markdown = "markdown";
+}; // namespace MarkupKind
+
+/**
+ * A `MarkupContent` literal represents a string value which content is interpreted base on its
+ * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
+ *
+ * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
+ * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ *
+ * Here is an example how such a string can be constructed using JavaScript / TypeScript:
+ * ```typescript
+ * let markdown: MarkdownContent = {
+ * kind: MarkupKind.Markdown,
+ * value: [
+ * '# Header',
+ * 'Some text',
+ * '```typescript',
+ * 'someCode();',
+ * '```'
+ * ].join('\n')
+ * };
+ * ```
+ *
+ * *Please Note* that clients might sanitize the return markdown. A client could decide to
+ * remove HTML from the markdown to avoid script execution.
+ */
+struct MarkupContent {
+ /**
+ * The type of the Markup
+ */
+ String kind;
+
+ /**
+ * The content itself
+ */
+ String value;
+
+ MarkupContent() {
+ kind = MarkupKind::Markdown;
+ }
+
+ MarkupContent(const String &p_value) {
+ value = p_value;
+ kind = MarkupKind::Markdown;
+ }
+
+ Dictionary to_json() const {
+ Dictionary dict;
+ dict["kind"] = kind;
+ dict["value"] = value;
+ return dict;
+ }
+};
+
+/**
+ * The kind of a completion entry.
+ */
+namespace CompletionItemKind {
+static const int Text = 1;
+static const int Method = 2;
+static const int Function = 3;
+static const int Constructor = 4;
+static const int Field = 5;
+static const int Variable = 6;
+static const int Class = 7;
+static const int Interface = 8;
+static const int Module = 9;
+static const int Property = 10;
+static const int Unit = 11;
+static const int Value = 12;
+static const int Enum = 13;
+static const int Keyword = 14;
+static const int Snippet = 15;
+static const int Color = 16;
+static const int File = 17;
+static const int Reference = 18;
+static const int Folder = 19;
+static const int EnumMember = 20;
+static const int Constant = 21;
+static const int Struct = 22;
+static const int Event = 23;
+static const int Operator = 24;
+static const int TypeParameter = 25;
+}; // namespace CompletionItemKind
+
+/**
+ * Defines whether the insert text in a completion item should be interpreted as
+ * plain text or a snippet.
+ */
+namespace InsertTextFormat {
+/**
+ * The primary text to be inserted is treated as a plain string.
+ */
+static const int PlainText = 1;
+
+/**
+ * The primary text to be inserted is treated as a snippet.
+ *
+ * A snippet can define tab stops and placeholders with `$1`, `$2`
+ * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ * the end of the snippet. Placeholders with equal identifiers are linked,
+ * that is typing in one will update others too.
+ */
+static const int Snippet = 2;
+}; // namespace InsertTextFormat
+
+struct CompletionItem {
+ /**
+ * The label of this completion item. By default
+ * also the text that is inserted when selecting
+ * this completion.
+ */
+ String label;
+
+ /**
+ * The kind of this completion item. Based of the kind
+ * an icon is chosen by the editor. The standardized set
+ * of available values is defined in `CompletionItemKind`.
+ */
+ int kind;
+
+ /**
+ * A human-readable string with additional information
+ * about this item, like type or symbol information.
+ */
+ String detail;
+
+ /**
+ * A human-readable string that represents a doc-comment.
+ */
+ MarkupContent documentation;
+
+ /**
+ * Indicates if this item is deprecated.
+ */
+ bool deprecated = false;
+
+ /**
+ * Select this item when showing.
+ *
+ * *Note* that only one completion item can be selected and that the
+ * tool / client decides which item that is. The rule is that the *first*
+ * item of those that match best is selected.
+ */
+ bool preselect = false;
+
+ /**
+ * A string that should be used when comparing this item
+ * with other items. When `falsy` the label is used.
+ */
+ String sortText;
+
+ /**
+ * A string that should be used when filtering a set of
+ * completion items. When `falsy` the label is used.
+ */
+ String filterText;
+
+ /**
+ * A string that should be inserted into a document when selecting
+ * this completion. When `falsy` the label is used.
+ *
+ * The `insertText` is subject to interpretation by the client side.
+ * Some tools might not take the string literally. For example
+ * VS Code when code complete is requested in this example `con<cursor position>`
+ * and a completion item with an `insertText` of `console` is provided it
+ * will only insert `sole`. Therefore it is recommended to use `textEdit` instead
+ * since it avoids additional client side interpretation.
+ *
+ * @deprecated Use textEdit instead.
+ */
+ String insertText;
+
+ /**
+ * The format of the insert text. The format applies to both the `insertText` property
+ * and the `newText` property of a provided `textEdit`.
+ */
+ int insertTextFormat;
+
+ /**
+ * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
+ * `insertText` is ignored.
+ *
+ * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
+ * has been requested.
+ */
+ TextEdit textEdit;
+
+ /**
+ * An optional array of additional text edits that are applied when
+ * selecting this completion. Edits must not overlap (including the same insert position)
+ * with the main edit nor with themselves.
+ *
+ * Additional text edits should be used to change text unrelated to the current cursor position
+ * (for example adding an import statement at the top of the file if the completion item will
+ * insert an unqualified type).
+ */
+ Vector<TextEdit> additionalTextEdits;
+
+ /**
+ * An optional set of characters that when pressed while this completion is active will accept it first and
+ * then type that character. *Note* that all commit characters should have `length=1` and that superfluous
+ * characters will be ignored.
+ */
+ Vector<String> commitCharacters;
+
+ /**
+ * An optional command that is executed *after* inserting this completion. *Note* that
+ * additional modifications to the current document should be described with the
+ * additionalTextEdits-property.
+ */
+ Command command;
+
+ /**
+ * A data entry field that is preserved on a completion item between
+ * a completion and a completion resolve request.
+ */
+ Variant data;
+
+ _FORCE_INLINE_ Dictionary to_json(bool resolved = false) const {
+ Dictionary dict;
+ dict["label"] = label;
+ dict["kind"] = kind;
+ dict["data"] = data;
+ if (resolved) {
+ dict["insertText"] = insertText;
+ dict["detail"] = detail;
+ dict["documentation"] = documentation.to_json();
+ dict["deprecated"] = deprecated;
+ dict["preselect"] = preselect;
+ dict["sortText"] = sortText;
+ dict["filterText"] = filterText;
+ if (commitCharacters.size()) dict["commitCharacters"] = commitCharacters;
+ dict["command"] = command.to_json();
+ }
+ return dict;
+ }
+
+ void load(const Dictionary &p_dict) {
+ if (p_dict.has("label")) label = p_dict["label"];
+ if (p_dict.has("kind")) kind = p_dict["kind"];
+ if (p_dict.has("detail")) detail = p_dict["detail"];
+ if (p_dict.has("documentation")) {
+ Variant doc = p_dict["documentation"];
+ if (doc.get_type() == Variant::STRING) {
+ documentation.value = doc;
+ } else if (doc.get_type() == Variant::DICTIONARY) {
+ Dictionary v = doc;
+ documentation.value = v["value"];
+ }
+ }
+ if (p_dict.has("deprecated")) deprecated = p_dict["deprecated"];
+ if (p_dict.has("preselect")) preselect = p_dict["preselect"];
+ if (p_dict.has("sortText")) sortText = p_dict["sortText"];
+ if (p_dict.has("filterText")) filterText = p_dict["filterText"];
+ if (p_dict.has("insertText")) insertText = p_dict["insertText"];
+ if (p_dict.has("data")) data = p_dict["data"];
+ }
+};
+
+/**
+ * Represents a collection of [completion items](#CompletionItem) to be presented
+ * in the editor.
+ */
+struct CompletionList {
+ /**
+ * This list it not complete. Further typing should result in recomputing
+ * this list.
+ */
+ bool isIncomplete;
+
+ /**
+ * The completion items.
+ */
+ Vector<CompletionItem> items;
+};
+
+/**
+ * A symbol kind.
+ */
+namespace SymbolKind {
+static const int File = 1;
+static const int Module = 2;
+static const int Namespace = 3;
+static const int Package = 4;
+static const int Class = 5;
+static const int Method = 6;
+static const int Property = 7;
+static const int Field = 8;
+static const int Constructor = 9;
+static const int Enum = 10;
+static const int Interface = 11;
+static const int Function = 12;
+static const int Variable = 13;
+static const int Constant = 14;
+static const int String = 15;
+static const int Number = 16;
+static const int Boolean = 17;
+static const int Array = 18;
+static const int Object = 19;
+static const int Key = 20;
+static const int Null = 21;
+static const int EnumMember = 22;
+static const int Struct = 23;
+static const int Event = 24;
+static const int Operator = 25;
+static const int TypeParameter = 26;
+}; // namespace SymbolKind
+
+/**
+ * Represents information about programming constructs like variables, classes,
+ * interfaces etc.
+ */
+struct SymbolInformation {
+ /**
+ * The name of this symbol.
+ */
+ String name;
+
+ /**
+ * The kind of this symbol.
+ */
+ int kind = SymbolKind::File;
+
+ /**
+ * Indicates if this symbol is deprecated.
+ */
+ bool deprecated = false;
+
+ /**
+ * The location of this symbol. The location's range is used by a tool
+ * to reveal the location in the editor. If the symbol is selected in the
+ * tool the range's start information is used to position the cursor. So
+ * the range usually spans more then the actual symbol's name and does
+ * normally include things like visibility modifiers.
+ *
+ * The range doesn't have to denote a node range in the sense of a abstract
+ * syntax tree. It can therefore not be used to re-construct a hierarchy of
+ * the symbols.
+ */
+ Location location;
+
+ /**
+ * The name of the symbol containing this symbol. This information is for
+ * user interface purposes (e.g. to render a qualifier in the user interface
+ * if necessary). It can't be used to re-infer a hierarchy for the document
+ * symbols.
+ */
+ String containerName;
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["name"] = name;
+ dict["kind"] = kind;
+ dict["deprecated"] = deprecated;
+ dict["location"] = location.to_json();
+ dict["containerName"] = containerName;
+ return dict;
+ }
+};
+
+struct DocumentedSymbolInformation : public SymbolInformation {
+ /**
+ * A human-readable string with additional information
+ */
+ String detail;
+
+ /**
+ * A human-readable string that represents a doc-comment.
+ */
+ String documentation;
+};
+
+/**
+ * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
+ * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
+ * e.g. the range of an identifier.
+ */
+struct DocumentSymbol {
+
+ /**
+ * The name of this symbol. Will be displayed in the user interface and therefore must not be
+ * an empty string or a string only consisting of white spaces.
+ */
+ String name;
+
+ /**
+ * More detail for this symbol, e.g the signature of a function.
+ */
+ String detail;
+
+ /**
+ * Documentation for this symbol
+ */
+ String documentation;
+
+ /**
+ * Class name for the native symbols
+ */
+ String native_class;
+
+ /**
+ * The kind of this symbol.
+ */
+ int kind = SymbolKind::File;
+
+ /**
+ * Indicates if this symbol is deprecated.
+ */
+ bool deprecated = false;
+
+ /**
+ * The range enclosing this symbol not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to determine if the clients cursor is
+ * inside the symbol to reveal in the symbol in the UI.
+ */
+ Range range;
+
+ /**
+ * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+ * Must be contained by the `range`.
+ */
+ Range selectionRange;
+
+ DocumentUri uri;
+ String script_path;
+
+ /**
+ * Children of this symbol, e.g. properties of a class.
+ */
+ Vector<DocumentSymbol> children;
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["name"] = name;
+ dict["detail"] = detail;
+ dict["kind"] = kind;
+ dict["deprecated"] = deprecated;
+ dict["range"] = range.to_json();
+ dict["selectionRange"] = selectionRange.to_json();
+ Array arr;
+ arr.resize(children.size());
+ for (int i = 0; i < children.size(); i++) {
+ arr[i] = children[i].to_json();
+ }
+ dict["children"] = arr;
+ return dict;
+ }
+
+ void symbol_tree_as_list(const String &p_uri, Vector<DocumentedSymbolInformation> &r_list, const String &p_container = "", bool p_join_name = false) const {
+ DocumentedSymbolInformation si;
+ if (p_join_name && !p_container.empty()) {
+ si.name = p_container + ">" + name;
+ } else {
+ si.name = name;
+ }
+ si.kind = kind;
+ si.containerName = p_container;
+ si.deprecated = deprecated;
+ si.location.uri = p_uri;
+ si.location.range = range;
+ si.detail = detail;
+ si.documentation = documentation;
+ r_list.push_back(si);
+ for (int i = 0; i < children.size(); i++) {
+ children[i].symbol_tree_as_list(p_uri, r_list, si.name, p_join_name);
+ }
+ }
+
+ _FORCE_INLINE_ MarkupContent render() const {
+ MarkupContent markdown;
+ if (detail.length()) {
+ markdown.value = "\t" + detail + "\n\n";
+ }
+ if (documentation.length()) {
+ markdown.value += documentation + "\n\n";
+ }
+ if (script_path.length()) {
+ markdown.value += "Defined in [" + script_path + "](" + uri + ")";
+ }
+ return markdown;
+ }
+
+ _FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const {
+
+ lsp::CompletionItem item;
+ item.label = name;
+
+ if (resolved) {
+ item.documentation = render();
+ }
+
+ switch (kind) {
+ case lsp::SymbolKind::Enum:
+ item.kind = lsp::CompletionItemKind::Enum;
+ break;
+ case lsp::SymbolKind::Class:
+ item.kind = lsp::CompletionItemKind::Class;
+ break;
+ case lsp::SymbolKind::Property:
+ item.kind = lsp::CompletionItemKind::Property;
+ break;
+ case lsp::SymbolKind::Method:
+ case lsp::SymbolKind::Function:
+ item.kind = lsp::CompletionItemKind::Method;
+ break;
+ case lsp::SymbolKind::Event:
+ item.kind = lsp::CompletionItemKind::Event;
+ break;
+ case lsp::SymbolKind::Constant:
+ item.kind = lsp::CompletionItemKind::Constant;
+ break;
+ case lsp::SymbolKind::Variable:
+ item.kind = lsp::CompletionItemKind::Variable;
+ break;
+ case lsp::SymbolKind::File:
+ item.kind = lsp::CompletionItemKind::File;
+ break;
+ default:
+ item.kind = lsp::CompletionItemKind::Text;
+ break;
+ }
+
+ return item;
+ }
+};
+
+/**
+ * Enum of known range kinds
+ */
+namespace FoldingRangeKind {
+/**
+ * Folding range for a comment
+ */
+static const String Comment = "comment";
+/**
+ * Folding range for a imports or includes
+ */
+static const String Imports = "imports";
+/**
+ * Folding range for a region (e.g. `#region`)
+ */
+static const String Region = "region";
+} // namespace FoldingRangeKind
+
+/**
+ * Represents a folding range.
+ */
+struct FoldingRange {
+
+ /**
+ * The zero-based line number from where the folded range starts.
+ */
+ int startLine = 0;
+
+ /**
+ * The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
+ */
+ int startCharacter = 0;
+
+ /**
+ * The zero-based line number where the folded range ends.
+ */
+ int endLine = 0;
+
+ /**
+ * The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
+ */
+ int endCharacter = 0;
+
+ /**
+ * Describes the kind of the folding range such as `comment' or 'region'. The kind
+ * is used to categorize folding ranges and used by commands like 'Fold all comments'. See
+ * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
+ */
+ String kind = FoldingRangeKind::Region;
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["startLine"] = startLine;
+ dict["startCharacter"] = startCharacter;
+ dict["endLine"] = endLine;
+ dict["endCharacter"] = endCharacter;
+ return dict;
+ }
+};
+
+/**
+ * How a completion was triggered
+ */
+namespace CompletionTriggerKind {
+/**
+ * Completion was triggered by typing an identifier (24x7 code
+ * complete), manual invocation (e.g Ctrl+Space) or via API.
+ */
+static const int Invoked = 1;
+
+/**
+ * Completion was triggered by a trigger character specified by
+ * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+ */
+static const int TriggerCharacter = 2;
+
+/**
+ * Completion was re-triggered as the current completion list is incomplete.
+ */
+static const int TriggerForIncompleteCompletions = 3;
+} // namespace CompletionTriggerKind
+
+/**
+ * Contains additional information about the context in which a completion request is triggered.
+ */
+struct CompletionContext {
+ /**
+ * How the completion was triggered.
+ */
+ int triggerKind = CompletionTriggerKind::TriggerCharacter;
+
+ /**
+ * The trigger character (a single character) that has trigger code complete.
+ * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+ */
+ String triggerCharacter;
+
+ void load(const Dictionary &p_params) {
+ triggerKind = int(p_params["triggerKind"]);
+ triggerCharacter = p_params["triggerCharacter"];
+ }
+};
+
+struct CompletionParams : public TextDocumentPositionParams {
+
+ /**
+ * The completion context. This is only available if the client specifies
+ * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+ */
+ CompletionContext context;
+
+ void load(const Dictionary &p_params) {
+ TextDocumentPositionParams::load(p_params);
+ context.load(p_params["context"]);
+ }
+};
+
+/**
+ * The result of a hover request.
+ */
+struct Hover {
+ /**
+ * The hover's content
+ */
+ MarkupContent contents;
+
+ /**
+ * An optional range is a range inside a text document
+ * that is used to visualize a hover, e.g. by changing the background color.
+ */
+ Range range;
+
+ _FORCE_INLINE_ Dictionary to_json() const {
+ Dictionary dict;
+ dict["range"] = range.to_json();
+ dict["contents"] = contents.to_json();
+ return dict;
+ }
+};
+
+struct ServerCapabilities {
+ /**
+ * Defines how text documents are synced. Is either a detailed structure defining each notification or
+ * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
+ */
+ TextDocumentSyncOptions textDocumentSync;
+
+ /**
+ * The server provides hover support.
+ */
+ bool hoverProvider = true;
+
+ /**
+ * The server provides completion support.
+ */
+ CompletionOptions completionProvider;
+
+ /**
+ * The server provides signature help support.
+ */
+ SignatureHelpOptions signatureHelpProvider;
+
+ /**
+ * The server provides goto definition support.
+ */
+ bool definitionProvider = true;
+
+ /**
+ * The server provides Goto Type Definition support.
+ *
+ * Since 3.6.0
+ */
+ bool typeDefinitionProvider = false;
+
+ /**
+ * The server provides Goto Implementation support.
+ *
+ * Since 3.6.0
+ */
+ bool implementationProvider = false;
+
+ /**
+ * The server provides find references support.
+ */
+ bool referencesProvider = false;
+
+ /**
+ * The server provides document highlight support.
+ */
+ bool documentHighlightProvider = false;
+
+ /**
+ * The server provides document symbol support.
+ */
+ bool documentSymbolProvider = true;
+
+ /**
+ * The server provides workspace symbol support.
+ */
+ bool workspaceSymbolProvider = true;
+
+ /**
+ * The server provides code actions. The `CodeActionOptions` return type is only
+ * valid if the client signals code action literal support via the property
+ * `textDocument.codeAction.codeActionLiteralSupport`.
+ */
+ bool codeActionProvider = false;
+
+ /**
+ * The server provides code lens.
+ */
+ CodeLensOptions codeLensProvider;
+
+ /**
+ * The server provides document formatting.
+ */
+ bool documentFormattingProvider = false;
+
+ /**
+ * The server provides document range formatting.
+ */
+ bool documentRangeFormattingProvider = false;
+
+ /**
+ * The server provides document formatting on typing.
+ */
+ DocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
+
+ /**
+ * The server provides rename support. RenameOptions may only be
+ * specified if the client states that it supports
+ * `prepareSupport` in its initial `initialize` request.
+ */
+ RenameOptions renameProvider;
+
+ /**
+ * The server provides document link support.
+ */
+ DocumentLinkOptions documentLinkProvider;
+
+ /**
+ * The server provides color provider support.
+ *
+ * Since 3.6.0
+ */
+ ColorProviderOptions colorProvider;
+
+ /**
+ * The server provides folding provider support.
+ *
+ * Since 3.10.0
+ */
+ FoldingRangeProviderOptions foldingRangeProvider;
+
+ /**
+ * The server provides go to declaration support.
+ *
+ * Since 3.14.0
+ */
+ bool declarationProvider = true;
+
+ /**
+ * The server provides execute command support.
+ */
+ ExecuteCommandOptions executeCommandProvider;
+
+ _FORCE_INLINE_ Dictionary to_json() {
+ Dictionary dict;
+ dict["textDocumentSync"] = (int)textDocumentSync.change;
+ dict["completionProvider"] = completionProvider.to_json();
+ dict["signatureHelpProvider"] = signatureHelpProvider.to_json();
+ dict["codeLensProvider"] = false; // codeLensProvider.to_json();
+ dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json();
+ dict["renameProvider"] = renameProvider.to_json();
+ dict["documentLinkProvider"] = documentLinkProvider.to_json();
+ dict["colorProvider"] = false; // colorProvider.to_json();
+ dict["foldingRangeProvider"] = false; //foldingRangeProvider.to_json();
+ dict["executeCommandProvider"] = executeCommandProvider.to_json();
+ dict["hoverProvider"] = hoverProvider;
+ dict["definitionProvider"] = definitionProvider;
+ dict["typeDefinitionProvider"] = typeDefinitionProvider;
+ dict["implementationProvider"] = implementationProvider;
+ dict["referencesProvider"] = referencesProvider;
+ dict["documentHighlightProvider"] = documentHighlightProvider;
+ dict["documentSymbolProvider"] = documentSymbolProvider;
+ dict["workspaceSymbolProvider"] = workspaceSymbolProvider;
+ dict["codeActionProvider"] = codeActionProvider;
+ dict["documentFormattingProvider"] = documentFormattingProvider;
+ dict["documentRangeFormattingProvider"] = documentRangeFormattingProvider;
+ dict["declarationProvider"] = declarationProvider;
+ return dict;
+ }
+};
+
+struct InitializeResult {
+ /**
+ * The capabilities the language server provides.
+ */
+ ServerCapabilities capabilities;
+
+ _FORCE_INLINE_ Dictionary to_json() {
+ Dictionary dict;
+ dict["capabilities"] = capabilities.to_json();
+ return dict;
+ }
+};
+
+} // namespace lsp
+
+#endif
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index b8a13ed91b..94b9e8c2d9 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -32,8 +32,8 @@
#include "core/io/file_access_encrypted.h"
#include "core/io/resource_loader.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
-#include "editor/gdscript_highlighter.h"
#include "gdscript.h"
#include "gdscript_tokenizer.h"
@@ -46,6 +46,12 @@ Ref<ResourceFormatSaverGDScript> resource_saver_gd;
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/gdscript_highlighter.h"
+
+#ifndef GDSCRIPT_NO_LSP
+#include "core/engine.h"
+#include "language_server/gdscript_language_server.h"
+#endif // !GDSCRIPT_NO_LSP
class EditorExportGDScript : public EditorExportPlugin {
@@ -117,6 +123,9 @@ public:
file = FileAccess::get_file_as_array(tmp_path);
add_file(p_path.get_basename() + ".gde", file, true);
+ // Clean up temporary file.
+ DirAccess::remove_file_or_error(tmp_path);
+
} else {
add_file(p_path.get_basename() + ".gdc", file, true);
@@ -130,9 +139,16 @@ static void _editor_init() {
Ref<EditorExportGDScript> gd_export;
gd_export.instance();
EditorExport::get_singleton()->add_export_plugin(gd_export);
+
+#ifndef GDSCRIPT_NO_LSP
+ register_lsp_types();
+ GDScriptLanguageServer *lsp_plugin = memnew(GDScriptLanguageServer);
+ EditorNode::get_singleton()->add_editor_plugin(lsp_plugin);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("GDScriptLanguageProtocol", GDScriptLanguageProtocol::get_singleton()));
+#endif // !GDSCRIPT_NO_LSP
}
-#endif
+#endif // TOOLS_ENABLED
void register_gdscript_types() {
@@ -151,7 +167,7 @@ void register_gdscript_types() {
#ifdef TOOLS_ENABLED
ScriptEditor::register_create_syntax_highlighter_function(GDScriptSyntaxHighlighter::create);
EditorNode::add_init_callback(_editor_init);
-#endif
+#endif // TOOLS_ENABLED
}
void unregister_gdscript_types() {
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.cpp b/modules/gridmap/grid_map.cpp
index 994a84fbc4..b36afd4386 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -196,16 +196,14 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
#ifndef DISABLE_DEPRECATED
void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
- ERR_EXPLAIN("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
set_mesh_library(p_theme);
}
Ref<MeshLibrary> GridMap::get_theme() const {
- ERR_EXPLAIN("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
return get_mesh_library();
}
@@ -481,11 +479,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Transform xform;
- if (clip && ((clip_above && cellpos[clip_axis] > clip_floor) || (!clip_above && cellpos[clip_axis] < clip_floor))) {
-
- } else {
- }
-
xform.basis.set_orthogonal_index(c.rot);
xform.set_origin(cellpos * cell_size + ofs);
xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale));
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 5a21833ffa..7e2986ca85 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -863,28 +863,36 @@ void GridMapEditor::_icon_size_changed(float p_value) {
void GridMapEditor::update_palette() {
int selected = mesh_library_palette->get_current();
+ float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64);
+ min_size *= EDSCALE;
+
mesh_library_palette->clear();
if (display_mode == DISPLAY_THUMBNAIL) {
mesh_library_palette->set_max_columns(0);
mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_TOP);
+ mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5));
} else if (display_mode == DISPLAY_LIST) {
mesh_library_palette->set_max_columns(1);
mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_LEFT);
+ mesh_library_palette->set_fixed_column_width(0);
}
- float min_size = EDITOR_DEF("editors/grid_map/preview_size", 64);
- min_size *= EDSCALE;
mesh_library_palette->set_fixed_icon_size(Size2(min_size, min_size));
- mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5));
mesh_library_palette->set_max_text_lines(2);
Ref<MeshLibrary> mesh_library = node->get_mesh_library();
if (mesh_library.is_null()) {
last_mesh_library = NULL;
+ search_box->set_text("");
+ search_box->set_editable(false);
+ info_message->show();
return;
}
+ search_box->set_editable(true);
+ info_message->hide();
+
Vector<int> ids;
ids = mesh_library->get_item_list();
@@ -1067,6 +1075,7 @@ void GridMapEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ get_tree()->connect("node_removed", this, "_node_removed");
mesh_library_palette->connect("item_selected", this, "_item_selected_cbk");
for (int i = 0; i < 3; i++) {
@@ -1083,6 +1092,7 @@ void GridMapEditor::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ get_tree()->disconnect("node_removed", this, "_node_removed");
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
@@ -1196,6 +1206,7 @@ void GridMapEditor::_bind_methods() {
ClassDB::bind_method("_floor_changed", &GridMapEditor::_floor_changed);
ClassDB::bind_method("_floor_mouse_exited", &GridMapEditor::_floor_mouse_exited);
ClassDB::bind_method("_set_selection", &GridMapEditor::_set_selection);
+ ClassDB::bind_method("_node_removed", &GridMapEditor::_node_removed);
ClassDB::bind_method(D_METHOD("_set_display_mode", "mode"), &GridMapEditor::_set_display_mode);
}
@@ -1269,7 +1280,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
options->get_popup()->add_item(TTR("Fill Selection"), MENU_OPTION_SELECTION_FILL, KEY_MASK_CTRL + KEY_F);
options->get_popup()->add_separator();
- options->get_popup()->add_item(TTR("Settings"), MENU_OPTION_GRIDMAP_SETTINGS);
+ options->get_popup()->add_item(TTR("Settings..."), MENU_OPTION_GRIDMAP_SETTINGS);
settings_dialog = memnew(ConfirmationDialog);
settings_dialog->set_title(TTR("GridMap Settings"));
@@ -1294,6 +1305,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
search_box = memnew(LineEdit);
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ search_box->set_placeholder(TTR("Filter meshes"));
hb->add_child(search_box);
search_box->connect("text_changed", this, "_text_changed");
search_box->connect("gui_input", this, "_sbox_input");
@@ -1329,6 +1341,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ mesh_library_palette->add_child(info_message);
+
edit_axis = Vector3::AXIS_Y;
edit_floor[0] = -1;
edit_floor[1] = -1;
@@ -1344,7 +1364,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
paste_mesh = VisualServer::get_singleton()->mesh_create();
{
- //selection mesh create
+ // Selection mesh create.
PoolVector<Vector3> lines;
PoolVector<Vector3> triangles;
@@ -1422,7 +1442,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
inner_mat.instance();
inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2));
- //inner_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
@@ -1442,7 +1461,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
selection_floor_mat->set_on_top_of_alpha();
selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
selection_floor_mat->set_line_width(3.0);
- //selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
d[VS::ARRAY_VERTEX] = lines;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d);
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index b9be925ff7..103913485f 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -35,9 +35,6 @@
#include "editor/editor_plugin.h"
#include "editor/pane_drag.h"
#include "grid_map.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class SpatialEditorPlugin;
@@ -200,12 +197,16 @@ class GridMapEditor : public VBoxContainer {
RID instance;
};
+ ItemList *mesh_library_palette;
+ Label *info_message;
+
+ EditorNode *editor;
+
void update_grid();
void _configure();
void _menu_option(int);
void update_palette();
void _set_display_mode(int p_mode);
- ItemList *mesh_library_palette;
void _item_selected_cbk(int idx);
void _update_cursor_transform();
void _update_cursor_instance();
@@ -230,7 +231,6 @@ class GridMapEditor : public VBoxContainer {
void _delete_selection();
void _fill_selection();
- EditorNode *editor;
bool do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click);
friend class GridMapEditorPlugin;
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index f75a4a926a..1abf26bfee 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -37,7 +37,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
String header = f->get_token();
- ERR_FAIL_COND_V(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED);
+ ERR_FAIL_COND_V_MSG(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED, "Unsupported header information in HDR: " + header + ".");
while (true) {
String line = f->get_line();
@@ -45,12 +45,9 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
if (line == "") // empty line indicates end of header
break;
if (line.begins_with("FORMAT=")) { // leave option to implement other commands
- if (line != "FORMAT=32-bit_rle_rgbe") {
- ERR_EXPLAIN("Only 32-bit_rle_rgbe is supported for HDR files.");
- return ERR_FILE_UNRECOGNIZED;
- }
+ ERR_FAIL_COND_V_MSG(line != "FORMAT=32-bit_rle_rgbe", ERR_FILE_UNRECOGNIZED, "Only 32-bit_rle_rgbe is supported for HDR files.");
} else if (!line.begins_with("#")) { // not comment
- WARN_PRINTS("Ignoring unsupported header information in HDR : " + line);
+ WARN_PRINTS("Ignoring unsupported header information in HDR: " + line + ".");
}
}
@@ -102,10 +99,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
len <<= 8;
len |= f->get_8();
- if (len != width) {
- ERR_EXPLAIN("invalid decoded scanline length, corrupt HDR");
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
+ ERR_FAIL_COND_V_MSG(len != width, ERR_FILE_CORRUPT, "Invalid decoded scanline length, corrupt HDR.");
for (int k = 0; k < 4; ++k) {
int i = 0;
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 8ebf52def7..e9575ee4fb 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderHDR : public ImageFormatLoader {
public:
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index 9a96fe008d..e9016ce43e 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderJPG : public ImageFormatLoader {
public:
diff --git a/modules/jsonrpc/SCsub b/modules/jsonrpc/SCsub
new file mode 100644
index 0000000000..13c9ffb253
--- /dev/null
+++ b/modules/jsonrpc/SCsub
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_jsonrpc = env_modules.Clone()
+env_jsonrpc.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/jsonrpc/config.py b/modules/jsonrpc/config.py
new file mode 100644
index 0000000000..53bc827027
--- /dev/null
+++ b/modules/jsonrpc/config.py
@@ -0,0 +1,5 @@
+def can_build(env, platform):
+ return True
+
+def configure(env):
+ pass
diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp
new file mode 100644
index 0000000000..e1bba60f2f
--- /dev/null
+++ b/modules/jsonrpc/jsonrpc.cpp
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* jsonrpc.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 "jsonrpc.h"
+#include "core/io/json.h"
+
+JSONRPC::JSONRPC() {
+}
+
+JSONRPC::~JSONRPC() {
+}
+
+void JSONRPC::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_scope", "scope", "target"), &JSONRPC::set_scope);
+ ClassDB::bind_method(D_METHOD("process_action", "action", "recurse"), &JSONRPC::process_action, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("process_string", "action"), &JSONRPC::process_string);
+
+ ClassDB::bind_method(D_METHOD("make_request", "method", "params", "id"), &JSONRPC::make_request);
+ ClassDB::bind_method(D_METHOD("make_response", "result", "id"), &JSONRPC::make_response);
+ ClassDB::bind_method(D_METHOD("make_notification", "method", "params"), &JSONRPC::make_notification);
+ ClassDB::bind_method(D_METHOD("make_response_error", "code", "message", "id"), &JSONRPC::make_response_error, DEFVAL(Variant()));
+
+ BIND_ENUM_CONSTANT(PARSE_ERROR)
+ BIND_ENUM_CONSTANT(INVALID_REQUEST)
+ BIND_ENUM_CONSTANT(METHOD_NOT_FOUND)
+ BIND_ENUM_CONSTANT(INVALID_PARAMS)
+ BIND_ENUM_CONSTANT(INTERNAL_ERROR)
+}
+
+Dictionary JSONRPC::make_response_error(int p_code, const String &p_message, const Variant &p_id) const {
+ Dictionary dict;
+ dict["jsonrpc"] = "2.0";
+
+ Dictionary err;
+ err["code"] = p_code;
+ err["message"] = p_message;
+
+ dict["error"] = err;
+ dict["id"] = p_id;
+
+ return dict;
+}
+
+Dictionary JSONRPC::make_response(const Variant &p_value, const Variant &p_id) {
+ Dictionary dict;
+ dict["jsonrpc"] = "2.0";
+ dict["id"] = p_id;
+ dict["result"] = p_value;
+ return dict;
+}
+
+Dictionary JSONRPC::make_notification(const String &p_method, const Variant &p_params) {
+ Dictionary dict;
+ dict["jsonrpc"] = "2.0";
+ dict["method"] = p_method;
+ dict["params"] = p_params;
+ return dict;
+}
+
+Dictionary JSONRPC::make_request(const String &p_method, const Variant &p_params, const Variant &p_id) {
+ Dictionary dict;
+ dict["jsonrpc"] = "2.0";
+ dict["method"] = p_method;
+ dict["params"] = p_params;
+ dict["id"] = p_id;
+ return dict;
+}
+
+Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elements) {
+ Variant ret;
+ if (p_action.get_type() == Variant::DICTIONARY) {
+ Dictionary dict = p_action;
+ String method = dict.get("method", "");
+ Array args;
+ if (dict.has("params")) {
+ Variant params = dict.get("params", Variant());
+ if (params.get_type() == Variant::ARRAY) {
+ args = params;
+ } else {
+ args.push_back(params);
+ }
+ }
+
+ Object *object = this;
+ if (method_scopes.has(method.get_base_dir())) {
+ object = method_scopes[method.get_base_dir()];
+ method = method.get_file();
+ }
+
+ Variant id;
+ if (dict.has("id")) {
+ id = dict["id"];
+ }
+
+ if (object == NULL || !object->has_method(method)) {
+ ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found", id);
+ } else {
+ Variant call_ret = object->callv(method, args);
+ if (id.get_type() != Variant::NIL) {
+ ret = make_response(call_ret, id);
+ }
+ }
+ } else if (p_action.get_type() == Variant::ARRAY && p_process_arr_elements) {
+ Array arr = p_action;
+ int size = arr.size();
+ if (size) {
+ Array arr_ret;
+ for (int i = 0; i < size; i++) {
+ const Variant &var = arr.get(i);
+ arr_ret.push_back(process_action(var));
+ }
+ ret = arr_ret;
+ } else {
+ ret = make_response_error(JSONRPC::INVALID_REQUEST, "Invalid Request");
+ }
+ } else {
+ ret = make_response_error(JSONRPC::INVALID_REQUEST, "Invalid Request");
+ }
+ return ret;
+}
+
+String JSONRPC::process_string(const String &p_input) {
+
+ if (p_input.empty()) return String();
+
+ Variant ret;
+ Variant input;
+ String err_message;
+ int err_line;
+ if (OK != JSON::parse(p_input, input, err_message, err_line)) {
+ ret = make_response_error(JSONRPC::PARSE_ERROR, "Parse error");
+ } else {
+ ret = process_action(input, true);
+ }
+
+ if (ret.get_type() == Variant::NIL) {
+ return "";
+ }
+ return JSON::print(ret);
+}
+
+void JSONRPC::set_scope(const String &p_scope, Object *p_obj) {
+ method_scopes[p_scope] = p_obj;
+}
diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h
new file mode 100644
index 0000000000..91897d0b55
--- /dev/null
+++ b/modules/jsonrpc/jsonrpc.h
@@ -0,0 +1,70 @@
+/*************************************************************************/
+/* jsonrpc.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 GODOT_JSON_RPC_H
+#define GODOT_JSON_RPC_H
+
+#include "core/object.h"
+#include "core/variant.h"
+
+class JSONRPC : public Object {
+ GDCLASS(JSONRPC, Object)
+
+ Map<String, Object *> method_scopes;
+
+protected:
+ static void _bind_methods();
+
+public:
+ JSONRPC();
+ ~JSONRPC();
+
+ enum ErrorCode {
+ PARSE_ERROR = -32700,
+ INVALID_REQUEST = -32600,
+ METHOD_NOT_FOUND = -32601,
+ INVALID_PARAMS = -32602,
+ INTERNAL_ERROR = -32603,
+ };
+
+ Dictionary make_response_error(int p_code, const String &p_message, const Variant &p_id = Variant()) const;
+ Dictionary make_response(const Variant &p_value, const Variant &p_id);
+ Dictionary make_notification(const String &p_method, const Variant &p_params);
+ Dictionary make_request(const String &p_method, const Variant &p_params, const Variant &p_id);
+
+ Variant process_action(const Variant &p_action, bool p_process_arr_elements = false);
+ String process_string(const String &p_input);
+
+ void set_scope(const String &p_scope, Object *p_obj);
+};
+
+VARIANT_ENUM_CAST(JSONRPC::ErrorCode);
+
+#endif
diff --git a/modules/jsonrpc/register_types.cpp b/modules/jsonrpc/register_types.cpp
new file mode 100644
index 0000000000..242b0e9df4
--- /dev/null
+++ b/modules/jsonrpc/register_types.cpp
@@ -0,0 +1,40 @@
+/*************************************************************************/
+/* register_types.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 "register_types.h"
+#include "core/class_db.h"
+#include "jsonrpc.h"
+
+void register_jsonrpc_types() {
+ ClassDB::register_class<JSONRPC>();
+}
+
+void unregister_jsonrpc_types() {
+}
diff --git a/modules/jsonrpc/register_types.h b/modules/jsonrpc/register_types.h
new file mode 100644
index 0000000000..e4648b901f
--- /dev/null
+++ b/modules/jsonrpc/register_types.h
@@ -0,0 +1,32 @@
+/*************************************************************************/
+/* register_types.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. */
+/*************************************************************************/
+
+void register_jsonrpc_types();
+void unregister_jsonrpc_types();
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
new file mode 100644
index 0000000000..1e02084ae2
--- /dev/null
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -0,0 +1,285 @@
+/*************************************************************************/
+/* crypto_mbedtls.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_mbedtls.h"
+
+#include "core/os/file_access.h"
+
+#include "core/engine.h"
+#include "core/io/certs_compressed.gen.h"
+#include "core/io/compression.h"
+#include "core/project_settings.h"
+
+#ifdef TOOLS_ENABLED
+#include "editor/editor_settings.h"
+#endif
+#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
+#define PEM_END_CRT "-----END CERTIFICATE-----\n"
+
+#include "mbedtls/pem.h"
+#include <mbedtls/debug.h>
+
+CryptoKey *CryptoKeyMbedTLS::create() {
+ return memnew(CryptoKeyMbedTLS);
+}
+
+Error CryptoKeyMbedTLS::load(String p_path) {
+ ERR_FAIL_COND_V_MSG(locks, ERR_ALREADY_IN_USE, "Key is in use");
+
+ PoolByteArray out;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_INVALID_PARAMETER);
+
+ int flen = f->get_len();
+ out.resize(flen + 1);
+ {
+ PoolByteArray::Write w = out.write();
+ f->get_buffer(w.ptr(), flen);
+ w[flen] = 0; //end f string
+ }
+ memdelete(f);
+
+ int ret = mbedtls_pk_parse_key(&pkey, out.read().ptr(), out.size(), NULL, 0);
+ // We MUST zeroize the memory for safety!
+ mbedtls_platform_zeroize(out.write().ptr(), out.size());
+ ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing private key: " + itos(ret));
+
+ return OK;
+}
+
+Error CryptoKeyMbedTLS::save(String p_path) {
+ FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V(!f, ERR_INVALID_PARAMETER);
+
+ unsigned char w[16000];
+ memset(w, 0, sizeof(w));
+
+ int ret = mbedtls_pk_write_key_pem(&pkey, w, sizeof(w));
+ if (ret != 0) {
+ memdelete(f);
+ memset(w, 0, sizeof(w)); // Zeroize anything we might have written.
+ ERR_FAIL_V_MSG(FAILED, "Error writing key: " + itos(ret));
+ }
+
+ size_t len = strlen((char *)w);
+ f->store_buffer(w, len);
+ memdelete(f);
+ memset(w, 0, sizeof(w)); // Zeroize temporary buffer.
+ return OK;
+}
+
+X509Certificate *X509CertificateMbedTLS::create() {
+ return memnew(X509CertificateMbedTLS);
+}
+
+Error X509CertificateMbedTLS::load(String p_path) {
+ ERR_FAIL_COND_V_MSG(locks, ERR_ALREADY_IN_USE, "Certificate is in use");
+
+ PoolByteArray out;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_INVALID_PARAMETER);
+
+ int flen = f->get_len();
+ out.resize(flen + 1);
+ {
+ PoolByteArray::Write w = out.write();
+ f->get_buffer(w.ptr(), flen);
+ w[flen] = 0; //end f string
+ }
+ memdelete(f);
+
+ int ret = mbedtls_x509_crt_parse(&cert, out.read().ptr(), out.size());
+ ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing some certificates: " + itos(ret));
+
+ return OK;
+}
+
+Error X509CertificateMbedTLS::load_from_memory(const uint8_t *p_buffer, int p_len) {
+ ERR_FAIL_COND_V_MSG(locks, ERR_ALREADY_IN_USE, "Certificate is in use");
+
+ int ret = mbedtls_x509_crt_parse(&cert, p_buffer, p_len);
+ ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing certificates: " + itos(ret));
+ return OK;
+}
+
+Error X509CertificateMbedTLS::save(String p_path) {
+ FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V(!f, ERR_INVALID_PARAMETER);
+
+ mbedtls_x509_crt *crt = &cert;
+ while (crt) {
+ unsigned char w[4096];
+ size_t wrote = 0;
+ int ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, cert.raw.p, cert.raw.len, w, sizeof(w), &wrote);
+ if (ret != 0 || wrote == 0) {
+ memdelete(f);
+ ERR_FAIL_V_MSG(FAILED, "Error writing certificate: " + itos(ret));
+ }
+
+ f->store_buffer(w, wrote - 1); // don't write the string terminator
+ crt = crt->next;
+ }
+ memdelete(f);
+ return OK;
+}
+
+Crypto *CryptoMbedTLS::create() {
+ return memnew(CryptoMbedTLS);
+}
+
+void CryptoMbedTLS::initialize_crypto() {
+
+#ifdef DEBUG_ENABLED
+ mbedtls_debug_set_threshold(1);
+#endif
+
+ Crypto::_create = create;
+ Crypto::_load_default_certificates = load_default_certificates;
+ X509CertificateMbedTLS::make_default();
+ CryptoKeyMbedTLS::make_default();
+}
+
+void CryptoMbedTLS::finalize_crypto() {
+ Crypto::_create = NULL;
+ Crypto::_load_default_certificates = NULL;
+ if (default_certs) {
+ memdelete(default_certs);
+ default_certs = NULL;
+ }
+ X509CertificateMbedTLS::finalize();
+ CryptoKeyMbedTLS::finalize();
+}
+
+CryptoMbedTLS::CryptoMbedTLS() {
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_entropy_init(&entropy);
+ int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
+ if (ret != 0) {
+ ERR_PRINTS(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
+ }
+}
+
+CryptoMbedTLS::~CryptoMbedTLS() {
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+}
+
+X509CertificateMbedTLS *CryptoMbedTLS::default_certs = NULL;
+
+X509CertificateMbedTLS *CryptoMbedTLS::get_default_certificates() {
+ return default_certs;
+}
+
+void CryptoMbedTLS::load_default_certificates(String p_path) {
+ ERR_FAIL_COND(default_certs != NULL);
+
+ default_certs = memnew(X509CertificateMbedTLS);
+ ERR_FAIL_COND(default_certs == NULL);
+
+ String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
+
+ if (p_path != "") {
+ // Use certs defined in project settings.
+ default_certs->load(p_path);
+ }
+#ifdef BUILTIN_CERTS_ENABLED
+ else {
+ // Use builtin certs only if user did not override it in project settings.
+ PoolByteArray out;
+ out.resize(_certs_uncompressed_size + 1);
+ PoolByteArray::Write w = out.write();
+ Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
+ w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
+#ifdef DEBUG_ENABLED
+ print_verbose("Loaded builtin certs");
+#endif
+ default_certs->load_from_memory(out.read().ptr(), out.size());
+ }
+#endif
+}
+
+Ref<CryptoKey> CryptoMbedTLS::generate_rsa(int p_bytes) {
+ Ref<CryptoKeyMbedTLS> out;
+ out.instance();
+ int ret = mbedtls_pk_setup(&(out->pkey), mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
+ ERR_FAIL_COND_V(ret != 0, NULL);
+ ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(out->pkey), mbedtls_ctr_drbg_random, &ctr_drbg, p_bytes, 65537);
+ ERR_FAIL_COND_V(ret != 0, NULL);
+ return out;
+}
+
+Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
+ Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS> >(p_key);
+ mbedtls_x509write_cert crt;
+ mbedtls_x509write_crt_init(&crt);
+
+ mbedtls_x509write_crt_set_subject_key(&crt, &(key->pkey));
+ mbedtls_x509write_crt_set_issuer_key(&crt, &(key->pkey));
+ mbedtls_x509write_crt_set_subject_name(&crt, p_issuer_name.utf8().get_data());
+ mbedtls_x509write_crt_set_issuer_name(&crt, p_issuer_name.utf8().get_data());
+ mbedtls_x509write_crt_set_version(&crt, MBEDTLS_X509_CRT_VERSION_3);
+ mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
+
+ mbedtls_mpi serial;
+ mbedtls_mpi_init(&serial);
+ uint8_t rand_serial[20];
+ mbedtls_ctr_drbg_random(&ctr_drbg, rand_serial, 20);
+ ERR_FAIL_COND_V(mbedtls_mpi_read_binary(&serial, rand_serial, 20), NULL);
+ mbedtls_x509write_crt_set_serial(&crt, &serial);
+
+ mbedtls_x509write_crt_set_validity(&crt, p_not_before.utf8().get_data(), p_not_after.utf8().get_data());
+ mbedtls_x509write_crt_set_basic_constraints(&crt, 1, -1);
+ mbedtls_x509write_crt_set_basic_constraints(&crt, 1, 0);
+
+ unsigned char buf[4096];
+ memset(buf, 0, 4096);
+ Ref<X509CertificateMbedTLS> out;
+ out.instance();
+ mbedtls_x509write_crt_pem(&crt, buf, 4096, mbedtls_ctr_drbg_random, &ctr_drbg);
+
+ int err = mbedtls_x509_crt_parse(&(out->cert), buf, 4096);
+ if (err != 0) {
+ mbedtls_mpi_free(&serial);
+ mbedtls_x509write_crt_free(&crt);
+ ERR_PRINTS("Generated invalid certificate: " + itos(err));
+ return NULL;
+ }
+
+ mbedtls_mpi_free(&serial);
+ mbedtls_x509write_crt_free(&crt);
+ return out;
+}
+
+PoolByteArray CryptoMbedTLS::generate_random_bytes(int p_bytes) {
+ PoolByteArray out;
+ out.resize(p_bytes);
+ mbedtls_ctr_drbg_random(&ctr_drbg, out.write().ptr(), p_bytes);
+ return out;
+}
diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h
new file mode 100644
index 0000000000..06b3ecd234
--- /dev/null
+++ b/modules/mbedtls/crypto_mbedtls.h
@@ -0,0 +1,124 @@
+/*************************************************************************/
+/* crypto_mbedtls.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_MBEDTLS_H
+#define CRYPTO_MBEDTLS_H
+
+#include "core/crypto/crypto.h"
+#include "core/resource.h"
+
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ssl.h>
+
+class CryptoMbedTLS;
+class SSLContextMbedTLS;
+class CryptoKeyMbedTLS : public CryptoKey {
+
+private:
+ mbedtls_pk_context pkey;
+ int locks;
+
+public:
+ static CryptoKey *create();
+ static void make_default() { CryptoKey::_create = create; }
+ static void finalize() { CryptoKey::_create = NULL; }
+
+ virtual Error load(String p_path);
+ virtual Error save(String p_path);
+
+ CryptoKeyMbedTLS() {
+ mbedtls_pk_init(&pkey);
+ locks = 0;
+ }
+ ~CryptoKeyMbedTLS() {
+ mbedtls_pk_free(&pkey);
+ }
+
+ _FORCE_INLINE_ void lock() { locks++; }
+ _FORCE_INLINE_ void unlock() { locks--; }
+
+ friend class CryptoMbedTLS;
+ friend class SSLContextMbedTLS;
+};
+
+class X509CertificateMbedTLS : public X509Certificate {
+
+private:
+ mbedtls_x509_crt cert;
+ int locks;
+
+public:
+ static X509Certificate *create();
+ static void make_default() { X509Certificate::_create = create; }
+ static void finalize() { X509Certificate::_create = NULL; }
+
+ virtual Error load(String p_path);
+ virtual Error load_from_memory(const uint8_t *p_buffer, int p_len);
+ virtual Error save(String p_path);
+
+ X509CertificateMbedTLS() {
+ mbedtls_x509_crt_init(&cert);
+ locks = 0;
+ }
+ ~X509CertificateMbedTLS() {
+ mbedtls_x509_crt_free(&cert);
+ }
+
+ _FORCE_INLINE_ void lock() { locks++; }
+ _FORCE_INLINE_ void unlock() { locks--; }
+
+ friend class CryptoMbedTLS;
+ friend class SSLContextMbedTLS;
+};
+
+class CryptoMbedTLS : public Crypto {
+
+private:
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ static X509CertificateMbedTLS *default_certs;
+
+public:
+ static Crypto *create();
+ static void initialize_crypto();
+ static void finalize_crypto();
+ static X509CertificateMbedTLS *get_default_certificates();
+ static void load_default_certificates(String p_path);
+
+ virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual Ref<CryptoKey> generate_rsa(int p_bytes);
+ virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
+
+ CryptoMbedTLS();
+ ~CryptoMbedTLS();
+};
+
+#endif // CRYPTO_MBEDTLS_H
diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp
index 121ed5eb02..f7dc6c785f 100755
--- a/modules/mbedtls/register_types.cpp
+++ b/modules/mbedtls/register_types.cpp
@@ -30,15 +30,17 @@
#include "register_types.h"
-#include "stream_peer_mbed_tls.h"
+#include "crypto_mbedtls.h"
+#include "stream_peer_mbedtls.h"
void register_mbedtls_types() {
- ClassDB::register_class<StreamPeerMbedTLS>();
+ CryptoMbedTLS::initialize_crypto();
StreamPeerMbedTLS::initialize_ssl();
}
void unregister_mbedtls_types() {
StreamPeerMbedTLS::finalize_ssl();
+ CryptoMbedTLS::finalize_crypto();
}
diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp
new file mode 100644
index 0000000000..eeaf831b4a
--- /dev/null
+++ b/modules/mbedtls/ssl_context_mbedtls.cpp
@@ -0,0 +1,151 @@
+/*************************************************************************/
+/* ssl_context_mbedtls.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 "ssl_context_mbedtls.h"
+
+static void my_debug(void *ctx, int level,
+ const char *file, int line,
+ const char *str) {
+
+ printf("%s:%04d: %s", file, line, str);
+ fflush(stdout);
+}
+
+Error SSLContextMbedTLS::_setup(int p_endpoint, int p_transport, int p_authmode) {
+ ERR_FAIL_COND_V_MSG(inited, ERR_ALREADY_IN_USE, "This SSL context is already active");
+
+ mbedtls_ssl_init(&ssl);
+ mbedtls_ssl_config_init(&conf);
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_entropy_init(&entropy);
+ inited = true;
+
+ int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
+ if (ret != 0) {
+ clear(); // Never leave unusable resources around.
+ ERR_FAIL_V_MSG(FAILED, "mbedtls_ctr_drbg_seed returned an error" + itos(ret));
+ }
+
+ ret = mbedtls_ssl_config_defaults(&conf, p_endpoint, p_transport, MBEDTLS_SSL_PRESET_DEFAULT);
+ if (ret != 0) {
+ clear();
+ ERR_FAIL_V_MSG(FAILED, "mbedtls_ssl_config_defaults returned an error" + itos(ret));
+ }
+ mbedtls_ssl_conf_authmode(&conf, p_authmode);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
+ mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
+ return OK;
+}
+
+Error SSLContextMbedTLS::init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert) {
+ ERR_FAIL_COND_V(!p_pkey.is_valid(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(!p_cert.is_valid(), ERR_INVALID_PARAMETER);
+
+ Error err = _setup(MBEDTLS_SSL_IS_SERVER, p_transport, p_authmode);
+ ERR_FAIL_COND_V(err != OK, err);
+
+ // Locking key and certificate(s)
+ pkey = p_pkey;
+ certs = p_cert;
+ if (pkey.is_valid())
+ pkey->lock();
+ if (certs.is_valid())
+ certs->lock();
+
+ // Adding key and certificate
+ int ret = mbedtls_ssl_conf_own_cert(&conf, &(certs->cert), &(pkey->pkey));
+ if (ret != 0) {
+ clear();
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Invalid cert/key combination " + itos(ret));
+ }
+ // Adding CA chain if available.
+ if (certs->cert.next) {
+ mbedtls_ssl_conf_ca_chain(&conf, certs->cert.next, NULL);
+ }
+ mbedtls_ssl_setup(&ssl, &conf);
+ return OK;
+}
+
+Error SSLContextMbedTLS::init_client(int p_transport, int p_authmode, Ref<X509CertificateMbedTLS> p_valid_cas) {
+ Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, p_authmode);
+ ERR_FAIL_COND_V(err != OK, err);
+
+ X509CertificateMbedTLS *cas = NULL;
+
+ if (p_valid_cas.is_valid()) {
+ // Locking CA certificates
+ certs = p_valid_cas;
+ certs->lock();
+ cas = certs.ptr();
+ } else {
+ // Fall back to default certificates (no need to lock those).
+ cas = CryptoMbedTLS::get_default_certificates();
+ if (cas == NULL) {
+ clear();
+ ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "SSL module failed to initialize!");
+ }
+ }
+
+ // Set valid CAs
+ mbedtls_ssl_conf_ca_chain(&conf, &(cas->cert), NULL);
+ mbedtls_ssl_setup(&ssl, &conf);
+ return OK;
+}
+
+void SSLContextMbedTLS::clear() {
+ if (!inited)
+ return;
+ mbedtls_ssl_free(&ssl);
+ mbedtls_ssl_config_free(&conf);
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+
+ // Unlock and key and certificates
+ if (certs.is_valid())
+ certs->unlock();
+ certs = Ref<X509Certificate>();
+ if (pkey.is_valid())
+ pkey->unlock();
+ pkey = Ref<CryptoKeyMbedTLS>();
+ inited = false;
+}
+
+mbedtls_ssl_context *SSLContextMbedTLS::get_context() {
+ ERR_FAIL_COND_V(!inited, NULL);
+ return &ssl;
+}
+
+SSLContextMbedTLS::SSLContextMbedTLS() {
+ inited = false;
+}
+
+SSLContextMbedTLS::~SSLContextMbedTLS() {
+ clear();
+}
diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h
new file mode 100644
index 0000000000..e49d532912
--- /dev/null
+++ b/modules/mbedtls/ssl_context_mbedtls.h
@@ -0,0 +1,73 @@
+/*************************************************************************/
+/* ssl_context_mbedtls.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 SSL_CONTEXT_MBED_TLS_H
+#define SSL_CONTEXT_MBED_TLS_H
+
+#include "crypto_mbedtls.h"
+
+#include "core/os/file_access.h"
+#include "core/pool_vector.h"
+#include "core/reference.h"
+
+#include <mbedtls/config.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/debug.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ssl.h>
+
+class SSLContextMbedTLS : public Reference {
+
+protected:
+ bool inited;
+
+ static PoolByteArray _read_file(String p_path);
+
+public:
+ Ref<X509CertificateMbedTLS> certs;
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_ssl_context ssl;
+ mbedtls_ssl_config conf;
+
+ Ref<CryptoKeyMbedTLS> pkey;
+
+ Error _setup(int p_endpoint, int p_transport, int p_authmode);
+ Error init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert);
+ Error init_client(int p_transport, int p_authmode, Ref<X509CertificateMbedTLS> p_valid_cas);
+ void clear();
+
+ mbedtls_ssl_context *get_context();
+
+ SSLContextMbedTLS();
+ ~SSLContextMbedTLS();
+};
+
+#endif // SSL_CONTEXT_MBED_TLS_H
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp
index 4bb7557150..a2e342e219 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbedtls.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* stream_peer_mbed_tls.cpp */
+/* stream_peer_mbedtls.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,19 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "stream_peer_mbed_tls.h"
+#include "stream_peer_mbedtls.h"
#include "core/io/stream_peer_tcp.h"
#include "core/os/file_access.h"
-static void my_debug(void *ctx, int level,
- const char *file, int line,
- const char *str) {
-
- printf("%s:%04d: %s", file, line, str);
- fflush(stdout);
-}
-
void _print_error(int ret) {
printf("mbedtls error: returned -0x%x\n\n", -ret);
fflush(stdout);
@@ -86,18 +78,14 @@ int StreamPeerMbedTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
void StreamPeerMbedTLS::_cleanup() {
- mbedtls_ssl_free(&ssl);
- mbedtls_ssl_config_free(&conf);
- mbedtls_ctr_drbg_free(&ctr_drbg);
- mbedtls_entropy_free(&entropy);
-
+ ssl_ctx->clear();
base = Ref<StreamPeer>();
status = STATUS_DISCONNECTED;
}
Error StreamPeerMbedTLS::_do_handshake() {
int ret = 0;
- while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
+ while ((ret = mbedtls_ssl_handshake(ssl_ctx->get_context())) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
// An error occurred.
ERR_PRINTS("TLS handshake error: " + itos(ret));
@@ -118,7 +106,7 @@ Error StreamPeerMbedTLS::_do_handshake() {
return OK;
}
-Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) {
+Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname, Ref<X509Certificate> p_ca_certs) {
ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);
@@ -126,31 +114,11 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
int ret = 0;
int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE;
- mbedtls_ssl_init(&ssl);
- mbedtls_ssl_config_init(&conf);
- mbedtls_ctr_drbg_init(&ctr_drbg);
- mbedtls_entropy_init(&entropy);
-
- ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
- if (ret != 0) {
- ERR_PRINTS(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
- _cleanup();
- return FAILED;
- }
+ Error err = ssl_ctx->init_client(MBEDTLS_SSL_TRANSPORT_STREAM, authmode, p_ca_certs);
+ ERR_FAIL_COND_V(err != OK, err);
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
- mbedtls_ssl_conf_authmode(&conf, authmode);
- mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
- mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
- mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
- mbedtls_ssl_setup(&ssl, &conf);
- mbedtls_ssl_set_hostname(&ssl, p_for_hostname.utf8().get_data());
-
- mbedtls_ssl_set_bio(&ssl, this, bio_send, bio_recv, NULL);
+ mbedtls_ssl_set_hostname(ssl_ctx->get_context(), p_for_hostname.utf8().get_data());
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, NULL);
status = STATUS_HANDSHAKING;
@@ -162,11 +130,26 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
return OK;
}
-Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base) {
+Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain) {
+
+ ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);
+
+ Error err = ssl_ctx->init_server(MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert);
+ ERR_FAIL_COND_V(err != OK, err);
+
+ base = p_base;
+
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, NULL);
+
+ status = STATUS_HANDSHAKING;
+
+ if ((err = _do_handshake()) != OK) {
+ return FAILED;
+ }
+ status = STATUS_CONNECTED;
return OK;
}
-
Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
@@ -197,7 +180,7 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in
if (p_bytes == 0)
return OK;
- int ret = mbedtls_ssl_write(&ssl, p_data, p_bytes);
+ int ret = mbedtls_ssl_write(ssl_ctx->get_context(), p_data, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
// Non blocking IO
ret = 0;
@@ -243,7 +226,7 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
r_received = 0;
- int ret = mbedtls_ssl_read(&ssl, p_buffer, p_bytes);
+ int ret = mbedtls_ssl_read(ssl_ctx->get_context(), p_buffer, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
ret = 0; // non blocking io
} else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
@@ -273,7 +256,7 @@ void StreamPeerMbedTLS::poll() {
// We could pass NULL as second parameter, but some behaviour sanitizers doesn't seem to like that.
// Passing a 1 byte buffer to workaround it.
uint8_t byte;
- int ret = mbedtls_ssl_read(&ssl, &byte, 0);
+ int ret = mbedtls_ssl_read(ssl_ctx->get_context(), &byte, 0);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
// Nothing to read/write (non blocking IO)
@@ -298,10 +281,11 @@ int StreamPeerMbedTLS::get_available_bytes() const {
ERR_FAIL_COND_V(status != STATUS_CONNECTED, 0);
- return mbedtls_ssl_get_bytes_avail(&ssl);
+ return mbedtls_ssl_get_bytes_avail(&(ssl_ctx->ssl));
}
StreamPeerMbedTLS::StreamPeerMbedTLS() {
+ ssl_ctx.instance();
status = STATUS_DISCONNECTED;
}
@@ -317,7 +301,7 @@ void StreamPeerMbedTLS::disconnect_from_stream() {
Ref<StreamPeerTCP> tcp = base;
if (tcp.is_valid() && tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
// We are still connected on the socket, try to send close notify.
- mbedtls_ssl_close_notify(&ssl);
+ mbedtls_ssl_close_notify(ssl_ctx->get_context());
}
_cleanup();
@@ -333,28 +317,9 @@ StreamPeerSSL *StreamPeerMbedTLS::_create_func() {
return memnew(StreamPeerMbedTLS);
}
-mbedtls_x509_crt StreamPeerMbedTLS::cacert;
-
-void StreamPeerMbedTLS::_load_certs(const PoolByteArray &p_array) {
- int arr_len = p_array.size();
- PoolByteArray::Read r = p_array.read();
- int err = mbedtls_x509_crt_parse(&cacert, &r[0], arr_len);
- if (err != 0) {
- WARN_PRINTS("Error parsing some certificates: " + itos(err));
- }
-}
-
void StreamPeerMbedTLS::initialize_ssl() {
_create = _create_func;
- load_certs_func = _load_certs;
-
- mbedtls_x509_crt_init(&cacert);
-
-#ifdef DEBUG_ENABLED
- mbedtls_debug_set_threshold(1);
-#endif
-
available = true;
}
@@ -362,6 +327,4 @@ void StreamPeerMbedTLS::finalize_ssl() {
available = false;
_create = NULL;
- load_certs_func = NULL;
- mbedtls_x509_crt_free(&cacert);
}
diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbedtls.h
index ab87b779c1..eec7eab631 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.h
+++ b/modules/mbedtls/stream_peer_mbedtls.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* stream_peer_mbed_tls.h */
+/* stream_peer_mbedtls.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -32,15 +32,7 @@
#define STREAM_PEER_OPEN_SSL_H
#include "core/io/stream_peer_ssl.h"
-
-#include <mbedtls/config.h>
-#include <mbedtls/ctr_drbg.h>
-#include <mbedtls/debug.h>
-#include <mbedtls/entropy.h>
-#include <mbedtls/ssl.h>
-
-#include <stdio.h>
-#include <stdlib.h>
+#include "ssl_context_mbedtls.h"
class StreamPeerMbedTLS : public StreamPeerSSL {
private:
@@ -50,19 +42,13 @@ private:
Ref<StreamPeer> base;
static StreamPeerSSL *_create_func();
- static void _load_certs(const PoolByteArray &p_array);
static int bio_recv(void *ctx, unsigned char *buf, size_t len);
static int bio_send(void *ctx, const unsigned char *buf, size_t len);
void _cleanup();
protected:
- static mbedtls_x509_crt cacert;
-
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
- mbedtls_ssl_context ssl;
- mbedtls_ssl_config conf;
+ Ref<SSLContextMbedTLS> ssl_ctx;
static void _bind_methods();
@@ -70,8 +56,8 @@ protected:
public:
virtual void poll();
- virtual Error accept_stream(Ref<StreamPeer> p_base);
- virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String());
+ virtual Error accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>());
+ virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref<X509Certificate> p_valid_cert = Ref<X509Certificate>());
virtual Status get_status() const;
virtual void disconnect_from_stream();
diff --git a/modules/mono/.gitignore b/modules/mono/.gitignore
new file mode 100644
index 0000000000..fa6d00cbbb
--- /dev/null
+++ b/modules/mono/.gitignore
@@ -0,0 +1,2 @@
+# Do not ignore solution files inside the mono module. Overrides Godot's global gitignore.
+!*.sln
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index cc60e64a11..a9afa7ccf6 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -8,13 +8,7 @@ Import('env_modules')
env_mono = env_modules.Clone()
-env_mono.add_source_files(env.modules_sources, '*.cpp')
-env_mono.add_source_files(env.modules_sources, 'glue/*.cpp')
-env_mono.add_source_files(env.modules_sources, 'mono_gd/*.cpp')
-env_mono.add_source_files(env.modules_sources, 'utils/*.cpp')
-
if env['tools']:
- env_mono.add_source_files(env.modules_sources, 'editor/*.cpp')
# NOTE: It is safe to generate this file here, since this is still executed serially
import build_scripts.make_cs_compressed_header as make_cs_compressed_header
make_cs_compressed_header.generate_header(
@@ -62,3 +56,13 @@ if env_mono['tools']:
# 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)
+
+# Add sources
+
+env_mono.add_source_files(env.modules_sources, '*.cpp')
+env_mono.add_source_files(env.modules_sources, 'glue/*.cpp')
+env_mono.add_source_files(env.modules_sources, 'mono_gd/*.cpp')
+env_mono.add_source_files(env.modules_sources, 'utils/*.cpp')
+
+if env['tools']:
+ env_mono.add_source_files(env.modules_sources, 'editor/*.cpp')
diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py
index c47cfc8a38..35daa6d307 100644
--- a/modules/mono/build_scripts/godot_tools_build.py
+++ b/modules/mono/build_scripts/godot_tools_build.py
@@ -84,10 +84,16 @@ def build(env_mono):
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']
+ target_filenames = [
+ 'GodotTools.dll', 'GodotTools.IdeConnection.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']
+ target_filenames += [
+ 'GodotTools.pdb', 'GodotTools.IdeConnection.pdb', 'GodotTools.BuildLogger.pdb',
+ 'GodotTools.ProjectEditor.pdb', 'GodotTools.Core.pdb'
+ ]
targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames]
diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py
index cd9210897d..8cad204d7b 100644
--- a/modules/mono/build_scripts/make_android_mono_config.py
+++ b/modules/mono/build_scripts/make_android_mono_config.py
@@ -3,23 +3,6 @@ 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:
@@ -36,7 +19,7 @@ String get_godot_android_mono_config();
bytes_seq_str += byte_to_str(buf[buf_idx])
cpp.write('''/* THIS FILE IS GENERATED DO NOT EDIT */
-#include "android_mono_config.gen.h"
+#include "android_mono_config.h"
#ifdef ANDROID_ENABLED
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 9f0eb58896..4c1ebd8d74 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -18,7 +18,7 @@ android_arch_dirs = {
def get_android_out_dir(env):
- return os.path.join(Dir('#platform/android/java/libs').abspath,
+ return os.path.join(Dir('#platform/android/java/lib/libs').abspath,
'release' if env['target'] == 'release' else 'debug',
android_arch_dirs[env['android_arch']])
@@ -113,8 +113,8 @@ def configure(env, env_mono):
else:
env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix))
- env.Append(LIBS='psapi')
- env.Append(LIBS='version')
+ env.Append(LIBS=['psapi'])
+ env.Append(LIBS=['version'])
else:
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
@@ -124,7 +124,7 @@ def configure(env, env_mono):
if env.msvc:
env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
else:
- env.Append(LIBS=mono_lib_name)
+ env.Append(LIBS=[mono_lib_name])
mono_bin_path = os.path.join(mono_root, 'bin')
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/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index 71ccdb7aab..7580911a0a 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
@@ -30,6 +30,8 @@
#include "class_db_api_json.h"
+#ifdef DEBUG_METHODS_ENABLED
+
#include "core/io/json.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
@@ -240,3 +242,5 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
print_line(String() + "ClassDB API JSON written to: " + ProjectSettings::get_singleton()->globalize_path(p_output_file));
}
+
+#endif // DEBUG_METHODS_ENABLED
diff --git a/modules/mono/class_db_api_json.h b/modules/mono/class_db_api_json.h
index 0aa9c20930..9888ecfb55 100644
--- a/modules/mono/class_db_api_json.h
+++ b/modules/mono/class_db_api_json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* 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 */
@@ -31,9 +31,16 @@
#ifndef CLASS_DB_API_JSON_H
#define CLASS_DB_API_JSON_H
+// 'core/method_bind.h' defines DEBUG_METHODS_ENABLED, but it looks like we
+// cannot include it here. That's why we include it through 'core/class_db.h'.
#include "core/class_db.h"
+
+#ifdef DEBUG_METHODS_ENABLED
+
#include "core/ustring.h"
void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api);
+#endif // DEBUG_METHODS_ENABLED
+
#endif // CLASS_DB_API_JSON_H
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 1add697997..e14e919f92 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -114,15 +114,20 @@ 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");
-#endif
-
#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
+#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(&_editor_init_callback);
@@ -624,7 +629,6 @@ void CSharpLanguage::frame() {
if (exc) {
GDMonoUtils::debug_unhandled_exception(exc);
- GD_UNREACHABLE();
}
}
}
@@ -710,14 +714,6 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
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;
}
@@ -1040,6 +1036,7 @@ void CSharpLanguage::_load_scripts_metadata() {
String old_json;
Error ferr = read_all_file_utf8(scripts_metadata_path, old_json);
+
ERR_FAIL_COND(ferr != OK);
Variant old_dict_var;
@@ -1047,7 +1044,7 @@ void CSharpLanguage::_load_scripts_metadata() {
int err_line;
Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line);
if (json_err != OK) {
- ERR_PRINTS("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ")");
+ ERR_PRINTS("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ").");
return;
}
@@ -1057,7 +1054,7 @@ void CSharpLanguage::_load_scripts_metadata() {
print_verbose("Successfully loaded scripts metadata");
} else {
if (!Engine::get_singleton()->is_editor_hint()) {
- ERR_PRINT("Missing scripts metadata file");
+ ERR_PRINT("Missing scripts metadata file.");
}
}
}
@@ -1104,7 +1101,7 @@ bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const S
_debug_parse_err_line = p_line;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false);
+ ScriptDebugger::get_singleton()->debug(this, false, true);
return true;
} else {
return false;
@@ -1772,12 +1769,8 @@ MonoObject *CSharpInstance::_internal_new_managed() {
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- if (ctor == NULL) {
- ERR_PRINTS("Cannot create script instance because the class does not define a parameterless constructor: " + script->get_path());
-
- ERR_EXPLAIN("Constructor not found");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_NULL_V_MSG(ctor, NULL,
+ "Cannot create script instance because the class does not define a parameterless constructor: '" + script->get_path() + "'.");
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
@@ -1796,8 +1789,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
owner = NULL;
- ERR_EXPLAIN("Failed to allocate memory for the object");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
}
// Tie managed to unmanaged
@@ -2237,7 +2229,7 @@ bool CSharpScript::_update_exports() {
MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
if (!tmp_object) {
- ERR_PRINT("Failed to allocate temporary MonoObject");
+ ERR_PRINT("Failed to allocate temporary MonoObject.");
return false;
}
@@ -2245,12 +2237,8 @@ bool CSharpScript::_update_exports() {
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- if (ctor == NULL) {
- ERR_PRINTS("Cannot construct temporary MonoObject because the class does not define a parameterless constructor: " + get_path());
-
- ERR_EXPLAIN("Constructor not found");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_NULL_V_MSG(ctor, NULL,
+ "Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
MonoException *ctor_exc = NULL;
ctor->invoke(tmp_object, NULL, &ctor_exc);
@@ -2403,7 +2391,7 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve
arg.type = GDMonoMarshal::managed_to_variant_type(types[i]);
if (arg.type == Variant::NIL) {
- ERR_PRINTS("Unknown type of signal parameter: " + arg.name + " in " + p_class->get_full_name());
+ ERR_PRINTS("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'.");
return false;
}
@@ -2431,7 +2419,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->is_static()) {
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
- ERR_PRINTS("Cannot export member because it is static: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
+ ERR_PRINTS("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false;
}
@@ -2454,12 +2442,12 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) {
if (exported)
- ERR_PRINTS("Read-only property cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
+ ERR_PRINTS("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false;
}
if (!property->has_setter()) {
if (exported)
- ERR_PRINTS("Write-only property (without getter) cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
+ ERR_PRINTS("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false;
}
}
@@ -2478,16 +2466,15 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
String hint_string;
if (variant_type == Variant::NIL) {
- ERR_PRINTS("Unknown exported member type: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
+ ERR_PRINTS("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false;
}
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
- if (hint_res == -1) {
- ERR_EXPLAIN("Error while trying to determine information about the exported member: " + MEMBER_FULL_QUALIFIED_NAME(p_member));
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(hint_res == -1, false,
+ "Error while trying to determine information about the exported member: '" +
+ MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
if (hint_res == 0) {
hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
@@ -2536,17 +2523,11 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
MonoObject *val_obj = mono_field_get_value_object(mono_domain_get(), field, NULL);
- if (val_obj == NULL) {
- ERR_EXPLAIN("Failed to get '" + enum_field_name + "' constant enum value");
- ERR_FAIL_V(-1);
- }
+ ERR_FAIL_NULL_V_MSG(val_obj, -1, "Failed to get '" + enum_field_name + "' constant enum value.");
bool r_error;
uint64_t val = GDMonoUtils::unbox_enum_value(val_obj, enum_basetype, r_error);
- if (r_error) {
- ERR_EXPLAIN("Failed to unbox '" + enum_field_name + "' constant enum value");
- ERR_FAIL_V(-1);
- }
+ ERR_FAIL_COND_V_MSG(r_error, -1, "Failed to unbox '" + enum_field_name + "' constant enum value.");
if (val != (unsigned int)i) {
uses_default_values = false;
@@ -2581,17 +2562,11 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
PropertyHint elem_hint = PROPERTY_HINT_NONE;
String elem_hint_string;
- if (elem_variant_type == Variant::NIL) {
- ERR_EXPLAIN("Unknown array element type");
- ERR_FAIL_V(-1);
- }
+ ERR_FAIL_COND_V_MSG(elem_variant_type == Variant::NIL, -1, "Unknown array element type.");
int hint_res = _try_get_member_export_hint(p_member, elem_type, elem_variant_type, /* allow_generics: */ false, elem_hint, elem_hint_string);
- if (hint_res == -1) {
- ERR_EXPLAIN("Error while trying to determine information about the array element type");
- ERR_FAIL_V(-1);
- }
+ ERR_FAIL_COND_V_MSG(hint_res == -1, -1, "Error while trying to determine information about the array element type.");
// Format: type/hint:hint_string
r_hint_string = itos(elem_variant_type) + "/" + itos(elem_hint) + ":" + elem_hint_string;
@@ -2686,7 +2661,7 @@ void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const {
void CSharpScript::_bind_methods() {
- ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo(Variant::OBJECT, "new"));
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo("new"));
}
Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) {
@@ -2779,7 +2754,7 @@ bool CSharpScript::can_instance() const {
"Compile",
ProjectSettings::get_singleton()->globalize_path(get_path()));
} else {
- ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created.");
+ ERR_PRINTS("C# project could not be created; cannot add file: '" + get_path() + "'.");
}
}
}
@@ -2797,12 +2772,10 @@ bool CSharpScript::can_instance() const {
if (extra_cond && !script_class) {
if (GDMono::get_singleton()->get_project_assembly() == NULL) {
// The project assembly is not loaded
- ERR_EXPLAIN("Cannot instance script because the project assembly is not loaded. Script: " + get_path());
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'.");
} else {
// The project assembly is loaded, but the class could not found
- ERR_EXPLAIN("Cannot instance script because the class '" + name + "' could not be found. Script: " + get_path());
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Cannot instance script because the class '" + name + "' could not be found. Script: '" + get_path() + "'.");
}
}
@@ -2824,14 +2797,12 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
if (ctor == NULL) {
- if (p_argcount == 0) {
- 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_FAIL_COND_V_MSG(p_argcount == 0, NULL,
+ "Cannot create script instance. The class '" + script_class->get_full_name() +
+ "' does not define a parameterless constructor." +
+ (get_path().empty() ? String() : " Path: '" + get_path() + "'."));
- ERR_EXPLAIN("Constructor not found");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Constructor not found.");
}
Ref<Reference> ref;
@@ -2882,8 +2853,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
p_owner->set_script_instance(NULL);
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
- ERR_EXPLAIN("Failed to allocate memory for the object");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
}
// Tie managed to unmanaged
@@ -2917,11 +2887,10 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call
r_error.error = Variant::CallError::CALL_OK;
REF ref;
- Object *owner = NULL;
ERR_FAIL_NULL_V(native, Variant());
- owner = ClassDB::instance(NATIVE_GDMONOCLASS_NAME(native));
+ Object *owner = ClassDB::instance(NATIVE_GDMONOCLASS_NAME(native));
Reference *r = Object::cast_to<Reference>(owner);
if (r) {
@@ -2955,8 +2924,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
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() + "'");
}
- ERR_EXPLAIN("Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + native_name +
+ "', so it can't be instanced in object of type: '" + p_this->get_class() + "'.");
}
}
@@ -3208,12 +3177,12 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
Error CSharpScript::load_source_code(const String &p_path) {
Error ferr = read_all_file_utf8(p_path, source);
- if (ferr != OK) {
- if (ferr == ERR_INVALID_DATA) {
- ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
- }
- ERR_FAIL_V(ferr);
- }
+
+ ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
+ ferr == ERR_INVALID_DATA ?
+ "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
+ " Please ensure that scripts are saved in valid UTF-8 unicode." :
+ "Failed to read file: '" + p_path + "'.");
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@@ -3282,8 +3251,7 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
#ifdef DEBUG_ENABLED
// User is responsible for thread attach/detach
- ERR_EXPLAIN("Thread is not attached");
- CRASH_COND(mono_domain_get() == NULL);
+ CRASH_COND_MSG(mono_domain_get() == NULL, "Thread is not attached.");
#endif
#endif
@@ -3350,8 +3318,7 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
"Compile",
ProjectSettings::get_singleton()->globalize_path(p_path));
} else {
- ERR_PRINTS("Failed to create C# project");
- ERR_PRINTS("Cannot add " + p_path + " to the C# project");
+ ERR_PRINTS("C# project could not be created; cannot add file: '" + p_path + "'.");
}
}
#endif
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
index f3ac353c0f..dcfdd83831 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
@@ -11,6 +11,7 @@
<AssemblyName>GodotTools.BuildLogger</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <LangVersion>7</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
index f36b40f87c..24c7cb1573 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
@@ -8,6 +8,7 @@
<RootNamespace>GodotTools.Core</RootNamespace>
<AssemblyName>GodotTools.Core</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <LangVersion>7</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
new file mode 100644
index 0000000000..7a2ff2ca56
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace GodotTools.IdeConnection
+{
+ public class ConsoleLogger : ILogger
+ {
+ public void LogDebug(string message)
+ {
+ Console.WriteLine("DEBUG: " + message);
+ }
+
+ public void LogInfo(string message)
+ {
+ Console.WriteLine("INFO: " + message);
+ }
+
+ public void LogWarning(string message)
+ {
+ Console.WriteLine("WARN: " + message);
+ }
+
+ public void LogError(string message)
+ {
+ Console.WriteLine("ERROR: " + message);
+ }
+
+ public void LogError(string message, Exception e)
+ {
+ Console.WriteLine("EXCEPTION: " + message);
+ Console.WriteLine(e);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
new file mode 100644
index 0000000000..be89638241
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
@@ -0,0 +1,94 @@
+using System;
+using Path = System.IO.Path;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeBase : IDisposable
+ {
+ private ILogger logger;
+
+ public ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ private readonly string projectMetadataDir;
+
+ protected const string MetaFileName = "ide_server_meta.txt";
+ protected string MetaFilePath => Path.Combine(projectMetadataDir, MetaFileName);
+
+ private GodotIdeConnection connection;
+ protected readonly object ConnectionLock = new object();
+
+ public bool IsDisposed { get; private set; } = false;
+
+ public bool IsConnected => connection != null && !connection.IsDisposed && connection.IsConnected;
+
+ public event Action Connected
+ {
+ add
+ {
+ if (connection != null && !connection.IsDisposed)
+ connection.Connected += value;
+ }
+ remove
+ {
+ if (connection != null && !connection.IsDisposed)
+ connection.Connected -= value;
+ }
+ }
+
+ protected GodotIdeConnection Connection
+ {
+ get => connection;
+ set
+ {
+ connection?.Dispose();
+ connection = value;
+ }
+ }
+
+ protected GodotIdeBase(string projectMetadataDir)
+ {
+ this.projectMetadataDir = projectMetadataDir;
+ }
+
+ protected void DisposeConnection()
+ {
+ lock (ConnectionLock)
+ {
+ connection?.Dispose();
+ }
+ }
+
+ ~GodotIdeBase()
+ {
+ Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed) // lock may not be fair
+ return;
+ IsDisposed = true;
+ }
+
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ connection?.Dispose();
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
new file mode 100644
index 0000000000..4f56a8d71b
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace GodotTools.IdeConnection
+{
+ public abstract class GodotIdeClient : GodotIdeBase
+ {
+ protected GodotIdeMetadata GodotIdeMetadata;
+
+ private readonly FileSystemWatcher fsWatcher;
+
+ protected GodotIdeClient(string projectMetadataDir) : base(projectMetadataDir)
+ {
+ messageHandlers = InitializeMessageHandlers();
+
+ // FileSystemWatcher requires an existing directory
+ if (!File.Exists(projectMetadataDir))
+ Directory.CreateDirectory(projectMetadataDir);
+
+ fsWatcher = new FileSystemWatcher(projectMetadataDir, MetaFileName);
+ }
+
+ private void OnMetaFileChanged(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null && metadata != GodotIdeMetadata)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ }
+ }
+
+ private void OnMetaFileDeleted(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected)
+ DisposeConnection();
+
+ // The file may have been re-created
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected || !File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ }
+ }
+
+ private GodotIdeMetadata? ReadMetadataFile()
+ {
+ using (var reader = File.OpenText(MetaFilePath))
+ {
+ string portStr = reader.ReadLine();
+
+ if (portStr == null)
+ return null;
+
+ string editorExecutablePath = reader.ReadLine();
+
+ if (editorExecutablePath == null)
+ return null;
+
+ if (!int.TryParse(portStr, out int port))
+ return null;
+
+ return new GodotIdeMetadata(port, editorExecutablePath);
+ }
+ }
+
+ private void ConnectToServer()
+ {
+ var tcpClient = new TcpClient();
+
+ Connection = new GodotIdeConnectionClient(tcpClient, HandleMessage);
+ Connection.Logger = Logger;
+
+ try
+ {
+ Logger.LogInfo("Connecting to Godot Ide Server");
+
+ tcpClient.Connect(IPAddress.Loopback, GodotIdeMetadata.Port);
+
+ Logger.LogInfo("Connection open with Godot Ide Server");
+
+ var clientThread = new Thread(Connection.Start)
+ {
+ IsBackground = true,
+ Name = "Godot Ide Connection Client"
+ };
+ clientThread.Start();
+ }
+ catch (SocketException e)
+ {
+ if (e.SocketErrorCode == SocketError.ConnectionRefused)
+ Logger.LogError("The connection to the Godot Ide Server was refused");
+ else
+ throw;
+ }
+ }
+
+ public void Start()
+ {
+ Logger.LogInfo("Starting Godot Ide Client");
+
+ fsWatcher.Changed += OnMetaFileChanged;
+ fsWatcher.Deleted += OnMetaFileDeleted;
+ fsWatcher.EnableRaisingEvents = true;
+
+ lock (ConnectionLock)
+ {
+ if (IsDisposed)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ {
+ Logger.LogInfo("There is no Godot Ide Server running");
+ return;
+ }
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ GodotIdeMetadata = metadata.Value;
+ ConnectToServer();
+ }
+ else
+ {
+ Logger.LogError("Failed to read Godot Ide metadata file");
+ }
+ }
+ }
+
+ public bool WriteMessage(Message message)
+ {
+ return Connection.WriteMessage(message);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ fsWatcher?.Dispose();
+ }
+ }
+
+ protected virtual bool HandleMessage(Message message)
+ {
+ if (messageHandlers.TryGetValue(message.Id, out var action))
+ {
+ action(message.Arguments);
+ return true;
+ }
+
+ return false;
+ }
+
+ private readonly Dictionary<string, Action<string[]>> messageHandlers;
+
+ private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
+ {
+ return new Dictionary<string, Action<string[]>>
+ {
+ ["OpenFile"] = args =>
+ {
+ switch (args.Length)
+ {
+ case 1:
+ OpenFile(file: args[0]);
+ return;
+ case 2:
+ OpenFile(file: args[0], line: int.Parse(args[1]));
+ return;
+ case 3:
+ OpenFile(file: args[0], line: int.Parse(args[1]), column: int.Parse(args[2]));
+ return;
+ default:
+ throw new ArgumentException();
+ }
+ }
+ };
+ }
+
+ protected abstract void OpenFile(string file);
+ protected abstract void OpenFile(string file, int line);
+ protected abstract void OpenFile(string file, int line, int column);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
new file mode 100644
index 0000000000..e7e81f175e
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
@@ -0,0 +1,207 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public abstract class GodotIdeConnection : IDisposable
+ {
+ protected const string Version = "1.0";
+
+ protected static readonly string ClientHandshake = $"Godot Ide Client Version {Version}";
+ protected static readonly string ServerHandshake = $"Godot Ide Server Version {Version}";
+
+ private const int ClientWriteTimeout = 8000;
+ private readonly TcpClient tcpClient;
+
+ private TextReader clientReader;
+ private TextWriter clientWriter;
+
+ private readonly object writeLock = new object();
+
+ private readonly Func<Message, bool> messageHandler;
+
+ public event Action Connected;
+
+ private ILogger logger;
+
+ public ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ public bool IsDisposed { get; private set; } = false;
+
+ public bool IsConnected => tcpClient.Client != null && tcpClient.Client.Connected;
+
+ protected GodotIdeConnection(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ {
+ this.tcpClient = tcpClient;
+ this.messageHandler = messageHandler;
+ }
+
+ public void Start()
+ {
+ try
+ {
+ if (!StartConnection())
+ return;
+
+ string messageLine;
+ while ((messageLine = ReadLine()) != null)
+ {
+ if (!MessageParser.TryParse(messageLine, out Message msg))
+ {
+ Logger.LogError($"Received message with invalid format: {messageLine}");
+ continue;
+ }
+
+ Logger.LogDebug($"Received message: {msg}");
+
+ if (msg.Id == "close")
+ {
+ Logger.LogInfo("Closing connection");
+ return;
+ }
+
+ try
+ {
+ try
+ {
+ Debug.Assert(messageHandler != null);
+
+ if (!messageHandler(msg))
+ Logger.LogError($"Received unknown message: {msg}");
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Message handler for '{msg}' failed with exception", e);
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Exception thrown from message handler. Message: {msg}", e);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Unhandled exception in the Godot Ide Connection thread", e);
+ }
+ finally
+ {
+ Dispose();
+ }
+ }
+
+ private bool StartConnection()
+ {
+ NetworkStream clientStream = tcpClient.GetStream();
+
+ clientReader = new StreamReader(clientStream, Encoding.UTF8);
+
+ lock (writeLock)
+ clientWriter = new StreamWriter(clientStream, Encoding.UTF8);
+
+ clientStream.WriteTimeout = ClientWriteTimeout;
+
+ if (!WriteHandshake())
+ {
+ Logger.LogError("Could not write handshake");
+ return false;
+ }
+
+ if (!IsValidResponseHandshake(ReadLine()))
+ {
+ Logger.LogError("Received invalid handshake");
+ return false;
+ }
+
+ Connected?.Invoke();
+
+ Logger.LogInfo("Godot Ide connection started");
+
+ return true;
+ }
+
+ private string ReadLine()
+ {
+ try
+ {
+ return clientReader?.ReadLine();
+ }
+ catch (Exception e)
+ {
+ if (IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Interrupted)
+ return null;
+ }
+
+ throw;
+ }
+ }
+
+ public bool WriteMessage(Message message)
+ {
+ Logger.LogDebug($"Sending message {message}");
+
+ var messageComposer = new MessageComposer();
+
+ messageComposer.AddArgument(message.Id);
+ foreach (string argument in message.Arguments)
+ messageComposer.AddArgument(argument);
+
+ return WriteLine(messageComposer.ToString());
+ }
+
+ protected bool WriteLine(string text)
+ {
+ if (clientWriter == null || IsDisposed || !IsConnected)
+ return false;
+
+ lock (writeLock)
+ {
+ try
+ {
+ clientWriter.WriteLine(text);
+ clientWriter.Flush();
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Shutdown)
+ Logger.LogInfo("Client disconnected ungracefully");
+ else
+ Logger.LogError("Exception thrown when trying to write to client", e);
+
+ Dispose();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected abstract bool WriteHandshake();
+ protected abstract bool IsValidResponseHandshake(string handshakeLine);
+
+ public void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ IsDisposed = true;
+
+ clientReader?.Dispose();
+ clientWriter?.Dispose();
+ ((IDisposable) tcpClient)?.Dispose();
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
new file mode 100644
index 0000000000..1b11a14358
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeConnectionClient : GodotIdeConnection
+ {
+ public GodotIdeConnectionClient(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ : base(tcpClient, messageHandler)
+ {
+ }
+
+ protected override bool WriteHandshake()
+ {
+ return WriteLine(ClientHandshake);
+ }
+
+ protected override bool IsValidResponseHandshake(string handshakeLine)
+ {
+ return handshakeLine == ServerHandshake;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
new file mode 100644
index 0000000000..aa98dc7ca3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeConnection
+{
+ public class GodotIdeConnectionServer : GodotIdeConnection
+ {
+ public GodotIdeConnectionServer(TcpClient tcpClient, Func<Message, bool> messageHandler)
+ : base(tcpClient, messageHandler)
+ {
+ }
+
+ protected override bool WriteHandshake()
+ {
+ return WriteLine(ServerHandshake);
+ }
+
+ protected override bool IsValidResponseHandshake(string handshakeLine)
+ {
+ return handshakeLine == ClientHandshake;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs
new file mode 100644
index 0000000000..d16daba0e2
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs
@@ -0,0 +1,45 @@
+namespace GodotTools.IdeConnection
+{
+ public struct GodotIdeMetadata
+ {
+ public int Port { get; }
+ public string EditorExecutablePath { get; }
+
+ public GodotIdeMetadata(int port, string editorExecutablePath)
+ {
+ Port = port;
+ EditorExecutablePath = editorExecutablePath;
+ }
+
+ public static bool operator ==(GodotIdeMetadata a, GodotIdeMetadata b)
+ {
+ return a.Port == b.Port && a.EditorExecutablePath == b.EditorExecutablePath;
+ }
+
+ public static bool operator !=(GodotIdeMetadata a, GodotIdeMetadata b)
+ {
+ return !(a == b);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is GodotIdeMetadata metadata)
+ return metadata == this;
+
+ return false;
+ }
+
+ public bool Equals(GodotIdeMetadata other)
+ {
+ return Port == other.Port && EditorExecutablePath == other.EditorExecutablePath;
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (Port * 397) ^ (EditorExecutablePath != null ? EditorExecutablePath.GetHashCode() : 0);
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
new file mode 100644
index 0000000000..94e525715b
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
@@ -0,0 +1,53 @@
+<?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>{92600954-25F0-4291-8E11-1FEE9FC4BE20}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>GodotTools.IdeConnection</RootNamespace>
+ <AssemblyName>GodotTools.IdeConnection</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <LangVersion>7</LangVersion>
+ </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="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ConsoleLogger.cs" />
+ <Compile Include="GodotIdeMetadata.cs" />
+ <Compile Include="GodotIdeBase.cs" />
+ <Compile Include="GodotIdeClient.cs" />
+ <Compile Include="GodotIdeConnection.cs" />
+ <Compile Include="GodotIdeConnectionClient.cs" />
+ <Compile Include="GodotIdeConnectionServer.cs" />
+ <Compile Include="ILogger.cs" />
+ <Compile Include="Message.cs" />
+ <Compile Include="MessageComposer.cs" />
+ <Compile Include="MessageParser.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs
new file mode 100644
index 0000000000..614bb30271
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace GodotTools.IdeConnection
+{
+ public interface ILogger
+ {
+ void LogDebug(string message);
+ void LogInfo(string message);
+ void LogWarning(string message);
+ void LogError(string message);
+ void LogError(string message, Exception e);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
new file mode 100644
index 0000000000..f24d324ae3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
@@ -0,0 +1,21 @@
+using System.Linq;
+
+namespace GodotTools.IdeConnection
+{
+ public struct Message
+ {
+ public string Id { get; set; }
+ public string[] Arguments { get; set; }
+
+ public Message(string id, params string[] arguments)
+ {
+ Id = id;
+ Arguments = arguments;
+ }
+
+ public override string ToString()
+ {
+ return $"(Id: '{Id}', Arguments: '{string.Join(",", Arguments)}')";
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
new file mode 100644
index 0000000000..9e4cd6ec1a
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
@@ -0,0 +1,46 @@
+using System.Linq;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public class MessageComposer
+ {
+ private readonly StringBuilder stringBuilder = new StringBuilder();
+
+ private static readonly char[] CharsToEscape = { '\\', '"' };
+
+ public void AddArgument(string argument)
+ {
+ AddArgument(argument, quoted: argument.Contains(","));
+ }
+
+ public void AddArgument(string argument, bool quoted)
+ {
+ if (stringBuilder.Length > 0)
+ stringBuilder.Append(',');
+
+ if (quoted)
+ {
+ stringBuilder.Append('"');
+
+ foreach (char @char in argument)
+ {
+ if (CharsToEscape.Contains(@char))
+ stringBuilder.Append('\\');
+ stringBuilder.Append(@char);
+ }
+
+ stringBuilder.Append('"');
+ }
+ else
+ {
+ stringBuilder.Append(argument);
+ }
+ }
+
+ public override string ToString()
+ {
+ return stringBuilder.ToString();
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
new file mode 100644
index 0000000000..ed691e481f
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
@@ -0,0 +1,88 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace GodotTools.IdeConnection
+{
+ public static class MessageParser
+ {
+ public static bool TryParse(string messageLine, out Message message)
+ {
+ var arguments = new List<string>();
+ var stringBuilder = new StringBuilder();
+
+ bool expectingArgument = true;
+
+ for (int i = 0; i < messageLine.Length; i++)
+ {
+ char @char = messageLine[i];
+
+ if (@char == ',')
+ {
+ if (expectingArgument)
+ arguments.Add(string.Empty);
+
+ expectingArgument = true;
+ continue;
+ }
+
+ bool quoted = false;
+
+ if (messageLine[i] == '"')
+ {
+ quoted = true;
+ i++;
+ }
+
+ while (i < messageLine.Length)
+ {
+ @char = messageLine[i];
+
+ if (quoted && @char == '"')
+ {
+ i++;
+ break;
+ }
+
+ if (@char == '\\')
+ {
+ i++;
+ if (i < messageLine.Length)
+ break;
+
+ stringBuilder.Append(messageLine[i]);
+ }
+ else if (!quoted && @char == ',')
+ {
+ break; // We don't increment the counter to allow the colon to be parsed after this
+ }
+ else
+ {
+ stringBuilder.Append(@char);
+ }
+
+ i++;
+ }
+
+ arguments.Add(stringBuilder.ToString());
+ stringBuilder.Clear();
+
+ expectingArgument = false;
+ }
+
+ if (arguments.Count == 0)
+ {
+ message = new Message();
+ return false;
+ }
+
+ message = new Message
+ {
+ Id = arguments[0],
+ Arguments = arguments.Skip(1).ToArray()
+ };
+
+ return true;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..c7c00e66a2
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/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.IdeConnection")]
+[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("92600954-25F0-4291-8E11-1FEE9FC4BE20")]
+
+// 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.ProjectEditor/GodotTools.ProjectEditor.csproj b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
index 08b8ba3946..ab3a5d1aea 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
@@ -9,6 +9,7 @@
<AssemblyName>GodotTools.ProjectEditor</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath>
+ <LangVersion>7</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -36,9 +37,8 @@
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? -->
+ <HintPath Condition=" '$(SolutionDir)' != '' And Exists('$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll') ">$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
+ <HintPath Condition=" '$(SolutionDir)' == '' Or !Exists('$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll') ">$(ProjectDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
index 7cf58b6755..4f21871f1a 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
@@ -91,13 +91,11 @@ namespace GodotTools.ProjectEditor
var coreApiRef = root.AddItem("Reference", CoreApiProjectName);
coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll"));
- coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", CoreApiProjectName + ".dll"));
coreApiRef.AddMetadata("Private", "False");
var editorApiRef = root.AddItem("Reference", EditorApiProjectName);
editorApiRef.Condition = " '$(Configuration)' == 'Tools' ";
editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll"));
- editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", EditorApiProjectName + ".dll"));
editorApiRef.AddMetadata("Private", "False");
GenAssemblyInfoFile(root, dir, name);
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 22cf89695d..233aab45b3 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -1,6 +1,8 @@
using GodotTools.Core;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
+using System.Linq;
using DotNet.Globbing;
using Microsoft.Build.Construction;
@@ -12,6 +14,8 @@ namespace GodotTools.ProjectEditor
{
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))
@@ -23,7 +27,8 @@ namespace GodotTools.ProjectEditor
string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
// We want relative paths
- for (int i = 0; i < files.Length; i++) {
+ for (int i = 0; i < files.Length; i++)
+ {
files[i] = files[i].RelativeToPath(rootDirectory);
}
@@ -35,7 +40,7 @@ namespace GodotTools.ProjectEditor
var result = new List<string>();
var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
- GlobOptions globOptions = new GlobOptions();
+ var globOptions = new GlobOptions();
globOptions.Evaluation.CaseInsensitive = false;
var root = ProjectRootElement.Open(projectPath);
@@ -68,5 +73,103 @@ namespace GodotTools.ProjectEditor
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/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln
index 6f7d44bec2..a3438ea5f3 100644
--- a/modules/mono/editor/GodotTools/GodotTools.sln
+++ b/modules/mono/editor/GodotTools/GodotTools.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Core", "GodotToo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.BuildLogger", "GodotTools.BuildLogger\GodotTools.BuildLogger.csproj", "{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.IdeConnection", "GodotTools.IdeConnection\GodotTools.IdeConnection.csproj", "{92600954-25F0-4291-8E11-1FEE9FC4BE20}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -31,5 +33,9 @@ Global
{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
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92600954-25F0-4291-8E11-1FEE9FC4BE20}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
index 300cf7fcb9..44813f962c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
@@ -3,12 +3,13 @@ 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
+ public class BottomPanel : VBoxContainer
{
private EditorInterface editorInterface;
@@ -33,7 +34,7 @@ namespace GodotTools
for (int i = 0; i < buildTabs.GetChildCount(); i++)
{
- var tab = (MonoBuildTab) buildTabs.GetChild(i);
+ var tab = (BuildTab) buildTabs.GetChild(i);
if (tab == null)
continue;
@@ -48,11 +49,11 @@ namespace GodotTools
itemTooltip += "\nStatus: ";
if (tab.BuildExited)
- itemTooltip += tab.BuildResult == MonoBuildTab.BuildResults.Success ? "Succeeded" : "Errored";
+ itemTooltip += tab.BuildResult == BuildTab.BuildResults.Success ? "Succeeded" : "Errored";
else
itemTooltip += "Running";
- if (!tab.BuildExited || tab.BuildResult == MonoBuildTab.BuildResults.Error)
+ if (!tab.BuildExited || tab.BuildResult == BuildTab.BuildResults.Error)
itemTooltip += $"\nErrors: {tab.ErrorCount}";
itemTooltip += $"\nWarnings: {tab.WarningCount}";
@@ -67,15 +68,15 @@ namespace GodotTools
}
}
- public MonoBuildTab GetBuildTabFor(MonoBuildInfo buildInfo)
+ public BuildTab GetBuildTabFor(BuildInfo buildInfo)
{
- foreach (var buildTab in new Array<MonoBuildTab>(buildTabs.GetChildren()))
+ foreach (var buildTab in new Array<BuildTab>(buildTabs.GetChildren()))
{
if (buildTab.BuildInfo.Equals(buildInfo))
return buildTab;
}
- var newBuildTab = new MonoBuildTab(buildInfo);
+ var newBuildTab = new BuildTab(buildInfo);
AddBuildTab(newBuildTab);
return newBuildTab;
@@ -119,7 +120,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
buildTab.WarningsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -131,7 +132,7 @@ namespace GodotTools
if (currentTab < 0 || currentTab >= buildTabs.GetTabCount())
throw new InvalidOperationException("No tab selected");
- var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab);
+ var buildTab = (BuildTab) buildTabs.GetChild(currentTab);
buildTab.ErrorsVisible = pressed;
buildTab.UpdateIssuesList();
}
@@ -144,7 +145,7 @@ namespace GodotTools
string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");
- CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
if (File.Exists(editorScriptsMetadataPath))
{
@@ -165,7 +166,7 @@ namespace GodotTools
Internal.GodotIs32Bits() ? "32" : "64"
};
- bool buildSuccess = GodotSharpBuilds.BuildProjectBlocking("Tools", godotDefines);
+ bool buildSuccess = BuildManager.BuildProjectBlocking("Tools", godotDefines);
if (!buildSuccess)
return;
@@ -192,9 +193,9 @@ namespace GodotTools
int selectedItem = selectedItems[0];
- var buildTab = (MonoBuildTab) buildTabs.GetTabControl(selectedItem);
+ var buildTab = (BuildTab) buildTabs.GetTabControl(selectedItem);
- OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildLogFileName));
+ OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, BuildManager.MsBuildLogFileName));
}
public override void _Notification(int what)
@@ -210,13 +211,13 @@ namespace GodotTools
}
}
- public void AddBuildTab(MonoBuildTab buildTab)
+ public void AddBuildTab(BuildTab buildTab)
{
buildTabs.AddChild(buildTab);
RaiseBuildTab(buildTab);
}
- public void RaiseBuildTab(MonoBuildTab buildTab)
+ public void RaiseBuildTab(BuildTab buildTab)
{
if (buildTab.GetParent() != buildTabs)
throw new InvalidOperationException("Build tab is not in the tabs list");
@@ -254,7 +255,7 @@ namespace GodotTools
panelTabs = new TabContainer
{
TabAlign = TabContainer.TabAlignEnum.Left,
- RectMinSize = new Vector2(0, 228) * Internal.EditorScale,
+ RectMinSize = new Vector2(0, 228) * EditorScale,
SizeFlagsVertical = (int) SizeFlags.ExpandFill
};
panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles"));
@@ -266,7 +267,7 @@ namespace GodotTools
// Builds tab
panelBuildsTab = new VBoxContainer
{
- Name = "Builds", // TTR
+ Name = "Builds".TTR(),
SizeFlagsHorizontal = (int) SizeFlags.ExpandFill
};
panelTabs.AddChild(panelBuildsTab);
@@ -276,7 +277,7 @@ namespace GodotTools
var buildProjectBtn = new Button
{
- Text = "Build Project", // TTR
+ Text = "Build Project".TTR(),
FocusMode = FocusModeEnum.None
};
buildProjectBtn.Connect("pressed", this, nameof(BuildProjectPressed));
@@ -286,7 +287,7 @@ namespace GodotTools
warningsBtn = new ToolButton
{
- Text = "Warnings", // TTR
+ Text = "Warnings".TTR(),
ToggleMode = true,
Pressed = true,
Visible = false,
@@ -297,7 +298,7 @@ namespace GodotTools
errorsBtn = new ToolButton
{
- Text = "Errors", // TTR
+ Text = "Errors".TTR(),
ToggleMode = true,
Pressed = true,
Visible = false,
@@ -310,7 +311,7 @@ namespace GodotTools
viewLogBtn = new Button
{
- Text = "View log", // TTR
+ Text = "View log".TTR(),
FocusMode = FocusModeEnum.None,
Visible = false
};
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index f849356919..9a2b2e3a26 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -46,8 +46,8 @@ namespace GodotTools.Build
{
if (OS.IsWindows())
{
- return (GodotSharpBuilds.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool")
- == GodotSharpBuilds.BuildTool.MsBuildMono;
+ return (BuildManager.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool")
+ == BuildManager.BuildTool.MsBuildMono;
}
return false;
@@ -103,16 +103,16 @@ namespace GodotTools.Build
return process;
}
- public static int Build(MonoBuildInfo monoBuildInfo)
+ public static int Build(BuildInfo buildInfo)
{
- return Build(monoBuildInfo.Solution, monoBuildInfo.Configuration,
- monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties);
+ return Build(buildInfo.Solution, buildInfo.Configuration,
+ buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
- public static async Task<int> BuildAsync(MonoBuildInfo monoBuildInfo)
+ public static async Task<int> BuildAsync(BuildInfo buildInfo)
{
- return await BuildAsync(monoBuildInfo.Solution, monoBuildInfo.Configuration,
- monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties);
+ return await BuildAsync(buildInfo.Solution, buildInfo.Configuration,
+ buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
public static int Build(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
@@ -137,7 +137,7 @@ namespace GodotTools.Build
private static string BuildArguments(string solution, string config, string loggerOutputDir, List<string> customProperties)
{
- string arguments = $@"""{solution}"" /v:normal /t:Rebuild ""/p:{"Configuration=" + config}"" " +
+ string arguments = $@"""{solution}"" /v:normal /t:Build ""/p:{"Configuration=" + config}"" " +
$@"""/l:{typeof(GodotBuildLogger).FullName},{GodotBuildLogger.AssemblyPath};{loggerOutputDir}""";
foreach (string customProperty in customProperties)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index a0d14c43c9..4c1e47ecad 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -15,18 +15,17 @@ namespace GodotTools.Build
{
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");
+ var buildTool = (BuildManager.BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
if (OS.IsWindows())
{
switch (buildTool)
{
- case GodotSharpBuilds.BuildTool.MsBuildVs:
+ case BuildManager.BuildTool.MsBuildVs:
{
if (_msbuildToolsPath.Empty() || !File.Exists(_msbuildToolsPath))
{
@@ -35,7 +34,7 @@ namespace GodotTools.Build
if (_msbuildToolsPath.Empty())
{
- throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameMsbuildVs}'. Tried with path: {_msbuildToolsPath}");
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMsbuildVs}'. Tried with path: {_msbuildToolsPath}");
}
}
@@ -44,31 +43,17 @@ namespace GodotTools.Build
return Path.Combine(_msbuildToolsPath, "MSBuild.exe");
}
-
- case GodotSharpBuilds.BuildTool.MsBuildMono:
+ case BuildManager.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}");
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.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");
}
@@ -76,20 +61,7 @@ namespace GodotTools.Build
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 (buildTool == BuildManager.BuildTool.MsBuildMono)
{
if (_msbuildUnixPath.Empty() || !File.Exists(_msbuildUnixPath))
{
@@ -99,11 +71,15 @@ namespace GodotTools.Build
if (_msbuildUnixPath.Empty())
{
- throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameMsbuildMono}'");
+ throw new FileNotFoundException($"Cannot find binary for '{BuildManager.PropNameMsbuildMono}'");
}
- }
- return buildTool != GodotSharpBuilds.BuildTool.XBuild ? _msbuildUnixPath : _xbuildUnixPath;
+ return _msbuildUnixPath;
+ }
+ else
+ {
+ throw new IndexOutOfRangeException("Invalid build tool in editor settings");
+ }
}
throw new PlatformNotSupportedException();
@@ -172,7 +148,7 @@ namespace GodotTools.Build
if (outputArray.Count == 0)
return string.Empty;
- var lines = outputArray[1].Split('\n');
+ var lines = outputArray[0].Split('\n');
foreach (string line in lines)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
index 858e852392..70bd552f2f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
@@ -7,7 +7,7 @@ using Path = System.IO.Path;
namespace GodotTools
{
[Serializable]
- public sealed class MonoBuildInfo : Reference // TODO Remove Reference once we have proper serialization
+ public sealed class BuildInfo : Reference // TODO Remove Reference once we have proper serialization
{
public string Solution { get; }
public string Configuration { get; }
@@ -17,7 +17,7 @@ namespace GodotTools
public override bool Equals(object obj)
{
- if (obj is MonoBuildInfo other)
+ if (obj is BuildInfo other)
return other.Solution == Solution && other.Configuration == Configuration;
return false;
@@ -34,11 +34,11 @@ namespace GodotTools
}
}
- private MonoBuildInfo()
+ private BuildInfo()
{
}
- public MonoBuildInfo(string solution, string configuration)
+ public BuildInfo(string solution, string configuration)
{
Solution = solution;
Configuration = configuration;
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
new file mode 100644
index 0000000000..417032da54
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -0,0 +1,259 @@
+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 File = GodotTools.Utils.File;
+
+namespace GodotTools
+{
+ public static class BuildManager
+ {
+ private static readonly List<BuildInfo> BuildsInProgress = new List<BuildInfo>();
+
+ public const string PropNameMsbuildMono = "MSBuild (Mono)";
+ public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
+
+ public const string MsBuildIssuesFileName = "msbuild_issues.csv";
+ public const string MsBuildLogFileName = "msbuild_log.txt";
+
+ public enum BuildTool
+ {
+ MsBuildMono,
+ MsBuildVs
+ }
+
+ private static void RemoveOldIssuesFile(BuildInfo buildInfo)
+ {
+ var issuesFile = GetIssuesFilePath(buildInfo);
+
+ if (!File.Exists(issuesFile))
+ return;
+
+ File.Delete(issuesFile);
+ }
+
+ private static void ShowBuildErrorDialog(string message)
+ {
+ GodotSharpEditor.Instance.ShowErrorDialog(message, "Build error");
+ GodotSharpEditor.Instance.BottomPanel.ShowBuildTab();
+ }
+
+ public static void RestartBuild(BuildTab buildTab) => throw new NotImplementedException();
+ public static void StopBuild(BuildTab buildTab) => throw new NotImplementedException();
+
+ private static string GetLogFilePath(BuildInfo buildInfo)
+ {
+ return Path.Combine(buildInfo.LogsDirPath, MsBuildLogFileName);
+ }
+
+ private static string GetIssuesFilePath(BuildInfo buildInfo)
+ {
+ return Path.Combine(buildInfo.LogsDirPath, MsBuildIssuesFileName);
+ }
+
+ private static void PrintVerbose(string text)
+ {
+ if (Godot.OS.IsStdoutVerbose())
+ Godot.GD.Print(text);
+ }
+
+ public static bool Build(BuildInfo buildInfo)
+ {
+ if (BuildsInProgress.Contains(buildInfo))
+ throw new InvalidOperationException("A build is already in progress");
+
+ BuildsInProgress.Add(buildInfo);
+
+ try
+ {
+ BuildTab buildTab = GodotSharpEditor.Instance.BottomPanel.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 ? BuildTab.BuildResults.Success : BuildTab.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(BuildInfo buildInfo)
+ {
+ if (BuildsInProgress.Contains(buildInfo))
+ throw new InvalidOperationException("A build is already in progress");
+
+ BuildsInProgress.Add(buildInfo);
+
+ try
+ {
+ BuildTab buildTab = GodotSharpEditor.Instance.BottomPanel.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 ? BuildTab.BuildResults.Success : BuildTab.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 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();
+
+ var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ var buildTool = (BuildTool) editorSettings.GetSetting("mono/builds/build_tool");
+
+ using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1))
+ {
+ pr.Step("Building project solution", 0);
+
+ var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, config);
+
+ // Add Godot defines
+ string constants = buildTool == BuildTool.MsBuildVs ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
+
+ foreach (var godotDefine in godotDefines)
+ constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};";
+
+ if (Internal.GodotIsRealTDouble())
+ constants += "GODOT_REAL_T_IS_DOUBLE;";
+
+ constants += buildTool == BuildTool.MsBuildVs ? "\"" : "\\\"";
+
+ 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");
+
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
+
+ if (File.Exists(editorScriptsMetadataPath))
+ File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
+
+ var currentPlayRequest = GodotSharpEditor.Instance.GodotIdeManager.GodotIdeServer.CurrentPlayRequest;
+
+ if (currentPlayRequest != null)
+ {
+ if (currentPlayRequest.Value.HasDebugger)
+ {
+ // Set the environment variable that will tell the player to connect to the IDE debugger
+ // TODO: We should probably add a better way to do this
+ Environment.SetEnvironmentVariable("GODOT_MONO_DEBUGGER_AGENT",
+ "--debugger-agent=transport=dt_socket" +
+ $",address={currentPlayRequest.Value.DebuggerHost}:{currentPlayRequest.Value.DebuggerPort}" +
+ ",server=n");
+ }
+
+ return true; // Requested play from an external editor/IDE which already built the project
+ }
+
+ 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}" :
+ $"{PropNameMsbuildMono}"
+ });
+
+ EditorDef("mono/builds/print_build_output", false);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
index 75fdacc0da..807a20d9a1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
@@ -7,7 +7,7 @@ using Path = System.IO.Path;
namespace GodotTools
{
- public class MonoBuildTab : VBoxContainer
+ public class BuildTab : VBoxContainer
{
public enum BuildResults
{
@@ -55,47 +55,54 @@ namespace GodotTools
}
}
- public MonoBuildInfo BuildInfo { get; private set; }
+ public BuildInfo 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())
+ try
{
- string[] csvColumns = file.GetCsvLine();
+ Error openError = file.Open(csvFile, Godot.File.ModeFlags.Read);
- if (csvColumns.Length == 1 && csvColumns[0].Empty())
+ if (openError != Error.Ok)
return;
- if (csvColumns.Length != 7)
+ while (!file.EofReached())
{
- GD.PushError($"Expected 7 columns, got {csvColumns.Length}");
- continue;
+ 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);
}
-
- 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);
+ }
+ finally
+ {
+ file.Close(); // Disposing it is not enough. We need to call Close()
}
}
}
@@ -192,7 +199,7 @@ namespace GodotTools
ErrorCount = 0;
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void OnBuildExit(BuildResults result)
@@ -200,10 +207,10 @@ namespace GodotTools
BuildExited = true;
BuildResult = result;
- _LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildIssuesFileName));
+ _LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, BuildManager.MsBuildIssuesFileName));
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void OnBuildExecFailed(string cause)
@@ -220,7 +227,7 @@ namespace GodotTools
UpdateIssuesList();
- GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this);
+ GodotSharpEditor.Instance.BottomPanel.RaiseBuildTab(this);
}
public void RestartBuild()
@@ -228,7 +235,7 @@ namespace GodotTools
if (!BuildExited)
throw new InvalidOperationException("Build already started");
- GodotSharpBuilds.RestartBuild(this);
+ BuildManager.RestartBuild(this);
}
public void StopBuild()
@@ -236,7 +243,7 @@ namespace GodotTools
if (!BuildExited)
throw new InvalidOperationException("Build is not in progress");
- GodotSharpBuilds.StopBuild(this);
+ BuildManager.StopBuild(this);
}
public override void _Ready()
@@ -248,11 +255,11 @@ namespace GodotTools
AddChild(issuesList);
}
- private MonoBuildTab()
+ private BuildTab()
{
}
- public MonoBuildTab(MonoBuildInfo buildInfo)
+ public BuildTab(BuildInfo buildInfo)
{
BuildInfo = buildInfo;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index cd9c470969..c021a9051e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -1,15 +1,15 @@
using Godot;
using System;
-using System.Collections.Generic;
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 class CsProjOperations
{
public static string GenerateGameProject(string dir, string name)
{
@@ -26,12 +26,24 @@ namespace GodotTools
public static void AddItem(string projectPath, string itemType, string include)
{
- if (!(bool) Internal.GlobalDef("mono/project/auto_update_project", true))
+ 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)
diff --git a/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
new file mode 100644
index 0000000000..4312ca0230
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/ExternalEditorId.cs
@@ -0,0 +1,11 @@
+namespace GodotTools
+{
+ public enum ExternalEditorId
+ {
+ None,
+ VisualStudio, // TODO (Windows-only)
+ VisualStudioForMac, // Mac-only
+ MonoDevelop,
+ VsCode
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
deleted file mode 100644
index 433a931941..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
+++ /dev/null
@@ -1,396 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-using GodotTools.Build;
-using GodotTools.Internals;
-using GodotTools.Utils;
-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;
- }
-
- private static bool CopyApiAssembly(string srcDir, string dstDir, string assemblyName, ApiAssemblyType apiType)
- {
- // Create destination directory if needed
- if (!Directory.Exists(dstDir))
- {
- try
- {
- Directory.CreateDirectory(dstDir);
- }
- catch (IOException e)
- {
- ShowBuildErrorDialog($"Failed to create destination directory for the API assemblies. Exception message: {e.Message}");
- return false;
- }
- }
-
- string assemblyFile = assemblyName + ".dll";
- string assemblySrc = Path.Combine(srcDir, assemblyFile);
- string assemblyDst = Path.Combine(dstDir, assemblyFile);
-
- if (!File.Exists(assemblyDst) || File.GetLastWriteTime(assemblySrc) > File.GetLastWriteTime(assemblyDst) ||
- Internal.MetadataIsApiAssemblyInvalidated(apiType))
- {
- string xmlFile = $"{assemblyName}.xml";
- string pdbFile = $"{assemblyName}.pdb";
-
- try
- {
- File.Copy(Path.Combine(srcDir, xmlFile), Path.Combine(dstDir, xmlFile));
- }
- catch (IOException e)
- {
- Godot.GD.PushWarning(e.ToString());
- }
-
- try
- {
- File.Copy(Path.Combine(srcDir, pdbFile), Path.Combine(dstDir, pdbFile));
- }
- catch (IOException e)
- {
- Godot.GD.PushWarning(e.ToString());
- }
-
- try
- {
- File.Copy(assemblySrc, assemblyDst);
- }
- catch (IOException e)
- {
- ShowBuildErrorDialog($"Failed to copy {assemblyFile}. Exception message: {e.Message}");
- return false;
- }
-
- Internal.MetadataSetApiAssemblyInvalidated(apiType, false);
- }
-
- return true;
- }
-
- public static bool MakeApiAssembly(ApiAssemblyType apiType, string config)
- {
- string apiName = apiType == ApiAssemblyType.Core ? ApiAssemblyNames.Core : ApiAssemblyNames.Editor;
-
- string editorPrebuiltApiDir = Path.Combine(GodotSharpDirs.DataEditorPrebuiltApiDir, config);
- string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, config);
-
- if (File.Exists(Path.Combine(editorPrebuiltApiDir, $"{apiName}.dll")))
- {
- using (var copyProgress = new EditorProgress("mono_copy_prebuilt_api_assembly", $"Copying prebuilt {apiName} assembly...", 1))
- {
- copyProgress.Step($"Copying {apiName} assembly", 0);
- return CopyApiAssembly(editorPrebuiltApiDir, resAssembliesDir, apiName, apiType);
- }
- }
-
- const string apiSolutionName = ApiAssemblyNames.SolutionName;
-
- using (var pr = new EditorProgress($"mono_build_release_{apiSolutionName}", $"Building {apiSolutionName} solution...", 3))
- {
- pr.Step($"Generating {apiSolutionName} solution", 0);
-
- string apiSlnDir = Path.Combine(GodotSharpDirs.MonoSolutionsDir, _ApiFolderName(ApiAssemblyType.Core));
- string apiSlnFile = Path.Combine(apiSlnDir, $"{apiSolutionName}.sln");
-
- if (!Directory.Exists(apiSlnDir) || !File.Exists(apiSlnFile))
- {
- var bindingsGenerator = new BindingsGenerator();
-
- if (!Godot.OS.IsStdoutVerbose())
- bindingsGenerator.LogPrintEnabled = false;
-
- Error err = bindingsGenerator.GenerateCsApi(apiSlnDir);
- if (err != Error.Ok)
- {
- ShowBuildErrorDialog($"Failed to generate {apiSolutionName} solution. Error: {err}");
- return false;
- }
- }
-
- pr.Step($"Building {apiSolutionName} solution", 1);
-
- if (!BuildApiSolution(apiSlnDir, config))
- return false;
-
- pr.Step($"Copying {apiName} assembly", 2);
-
- // Copy the built assembly to the assemblies directory
- string apiAssemblyDir = Path.Combine(apiSlnDir, apiName, "bin", config);
- if (!CopyApiAssembly(apiAssemblyDir, resAssembliesDir, apiName, apiType))
- return false;
- }
-
- return true;
- }
-
- public static bool BuildProjectBlocking(string config, IEnumerable<string> godotDefines)
- {
- if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
- return true; // No solution to build
-
- string apiConfig = config == "Release" ? "Release" : "Debug";
-
- if (!MakeApiAssembly(ApiAssemblyType.Core, apiConfig))
- return false;
-
- if (!MakeApiAssembly(ApiAssemblyType.Editor, apiConfig))
- return false;
-
- 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
-
- Internal.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}"
- });
-
- Internal.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
index 955574d5fe..7da7cff933 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -2,15 +2,18 @@ using Godot;
using GodotTools.Utils;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
+using GodotTools.Ides;
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
{
+ [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
public class GodotSharpEditor : EditorPlugin, ISerializationListener
{
private EditorSettings editorSettings;
@@ -23,16 +26,17 @@ namespace GodotTools
private ToolButton bottomPanelBtn;
- private MonoDevelopInstance monoDevelopInstance;
- private MonoDevelopInstance visualStudioForMacInstance;
+ public GodotIdeManager GodotIdeManager { get; private set; }
- public MonoBottomPanel MonoBottomPanel { get; private set; }
+ private WeakRef exportPluginWeak; // TODO Use WeakReference once we have proper serialization
+
+ public BottomPanel BottomPanel { get; private set; }
private bool CreateProjectSolution()
{
- using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...", 2)) // TTR("Generating solution...")
+ using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2))
{
- pr.Step("Generating C# project..."); // TTR("Generating C# project...")
+ pr.Step("Generating C# project...".TTR());
string resourceDir = ProjectSettings.GlobalizePath("res://");
@@ -41,7 +45,7 @@ namespace GodotTools
if (name.Empty())
name = "UnnamedProject";
- string guid = CSharpProject.GenerateGameProject(path, name);
+ string guid = CsProjOperations.GenerateGameProject(path, name);
if (guid.Length > 0)
{
@@ -65,96 +69,28 @@ namespace GodotTools
}
catch (IOException e)
{
- ShowErrorDialog($"Failed to save solution. Exception message: {e.Message}"); // TTR
+ ShowErrorDialog("Failed to save solution. Exception message: ".TTR() + e.Message);
return false;
}
- string apiConfig = "Debug";
-
- if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Core, apiConfig))
- return false;
-
- if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Editor, apiConfig))
- 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("Done")
+ pr.Step("Done".TTR());
// Here, after all calls to progress_task_step
CallDeferred(nameof(_RemoveCreateSlnMenuOption));
}
else
{
- ShowErrorDialog("Failed to create C# project."); // TTR
+ ShowErrorDialog("Failed to create C# project.".TTR());
}
return true;
}
}
- private static int _makeApiSolutionsAttempts = 100;
- private static bool _makeApiSolutionsRecursionGuard = false;
-
- private void _MakeApiSolutionsIfNeeded()
- {
- // I'm sick entirely of ProgressDialog
-
- if (Internal.IsMessageQueueFlushing() || Engine.GetMainLoop() == null)
- {
- if (_makeApiSolutionsAttempts == 0) // This better never happen or I swear...
- throw new TimeoutException();
-
- if (Engine.GetMainLoop() != null)
- {
- if (!Engine.GetMainLoop().IsConnected("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded)))
- Engine.GetMainLoop().Connect("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded));
- }
- else
- {
- CallDeferred(nameof(_MakeApiSolutionsIfNeededImpl));
- }
-
- _makeApiSolutionsAttempts--;
- 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.
- if (!_makeApiSolutionsRecursionGuard)
- {
- _makeApiSolutionsRecursionGuard = true;
-
- // Oneshot signals don't play well with ProgressDialog either, so we do it this way instead
- if (Engine.GetMainLoop().IsConnected("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded)))
- Engine.GetMainLoop().Disconnect("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded));
-
- _MakeApiSolutionsIfNeededImpl();
-
- _makeApiSolutionsRecursionGuard = false;
- }
- }
-
- private void _MakeApiSolutionsIfNeededImpl()
- {
- // If the project has a solution and C# project make sure the API assemblies are present and up to date
-
- string api_config = "Debug";
- string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, api_config);
-
- if (!File.Exists(Path.Combine(resAssembliesDir, $"{ApiAssemblyNames.Core}.dll")) ||
- Internal.MetadataIsApiAssemblyInvalidated(ApiAssemblyType.Core))
- {
- if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Core, api_config))
- return;
- }
-
- if (!File.Exists(Path.Combine(resAssembliesDir, $"{ApiAssemblyNames.Editor}.dll")) ||
- Internal.MetadataIsApiAssemblyInvalidated(ApiAssemblyType.Editor))
- {
- if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Editor, api_config))
- return; // Redundant? I don't think so!
- }
- }
-
private void _RemoveCreateSlnMenuOption()
{
menuPopup.RemoveItem(menuPopup.GetItemIndex((int) MenuOptions.CreateSln));
@@ -198,7 +134,7 @@ namespace GodotTools
return; // Failed to create solution
}
- Instance.MonoBottomPanel.BuildProjectPressed();
+ Instance.BottomPanel.BuildProjectPressed();
}
public override void _Notification(int what)
@@ -218,21 +154,12 @@ namespace GodotTools
}
}
- public enum MenuOptions
+ private 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;
@@ -249,11 +176,30 @@ namespace GodotTools
public Error OpenInExternalEditor(Script script, int line, int col)
{
- var editor = (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor");
+ var editor = (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor");
switch (editor)
{
- case ExternalEditor.VsCode:
+ case ExternalEditorId.None:
+ // Tells the caller to fallback to the global external editor settings or the built-in editor
+ return Error.Unavailable;
+ case ExternalEditorId.VisualStudio:
+ throw new NotSupportedException();
+ case ExternalEditorId.VisualStudioForMac:
+ goto case ExternalEditorId.MonoDevelop;
+ case ExternalEditorId.MonoDevelop:
+ {
+ string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
+
+ if (line >= 0)
+ GodotIdeManager.SendOpenFile(scriptPath, line + 1, col);
+ else
+ GodotIdeManager.SendOpenFile(scriptPath);
+
+ break;
+ }
+
+ case ExternalEditorId.VsCode:
{
if (_vsCodePath.Empty() || !File.Exists(_vsCodePath))
{
@@ -338,38 +284,6 @@ namespace GodotTools
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();
}
@@ -379,12 +293,12 @@ namespace GodotTools
public bool OverridesExternalEditor()
{
- return (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditor.None;
+ return (ExternalEditorId) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditorId.None;
}
public override bool Build()
{
- return GodotSharpBuilds.EditorBuildCallback();
+ return BuildManager.EditorBuildCallback();
}
public override void EnablePlugin()
@@ -403,9 +317,9 @@ namespace GodotTools
errorDialog = new AcceptDialog();
editorBaseControl.AddChild(errorDialog);
- MonoBottomPanel = new MonoBottomPanel();
+ BottomPanel = new BottomPanel();
- bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono"); // TTR("Mono")
+ bottomPanelBtn = AddControlToBottomPanel(BottomPanel, "Mono".TTR());
AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"});
@@ -417,7 +331,7 @@ namespace GodotTools
// TODO: Remove or edit this info dialog once Mono support is no longer in alpha
{
- menuPopup.AddItem("About C# support", (int) MenuOptions.AboutCSharp); // TTR("About C# support")
+ menuPopup.AddItem("About C# support".TTR(), (int) MenuOptions.AboutCSharp);
aboutDialog = new AcceptDialog();
editorBaseControl.AddChild(aboutDialog);
aboutDialog.WindowTitle = "Important: C# support is not feature-complete";
@@ -439,20 +353,20 @@ namespace GodotTools
var aboutLabel = new Label();
aboutHBox.AddChild(aboutLabel);
- aboutLabel.RectMinSize = new Vector2(600, 150) * Internal.EditorScale;
+ 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. " +
+ "Projects can be exported to Linux, macOS, Windows and Android, but not yet to iOS, HTML5 or UWP. " +
"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!";
- Internal.EditorDef("mono/editor/show_info_on_start", true);
+ EditorDef("mono/editor/show_info_on_start", true);
// CheckBox in main container
aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"};
@@ -462,13 +376,13 @@ namespace GodotTools
if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
- // Defer this task because EditorProgress calls Main::iterarion() and the main loop is not yet initialized.
- CallDeferred(nameof(_MakeApiSolutionsIfNeeded));
+ // Make sure the existing project has Api assembly references configured correctly
+ CsProjOperations.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
}
else
{
bottomPanelBtn.Hide();
- menuPopup.AddItem("Create C# solution", (int) MenuOptions.CreateSln); // TTR("Create C# solution")
+ menuPopup.AddItem("Create C# solution".TTR(), (int) MenuOptions.CreateSln);
}
menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed));
@@ -483,25 +397,25 @@ namespace GodotTools
AddControlToContainer(CustomControlContainer.Toolbar, buildButton);
// External editor settings
- Internal.EditorDef("mono/editor/external_editor", ExternalEditor.None);
+ EditorDef("mono/editor/external_editor", ExternalEditorId.None);
string settingsHintStr = "Disabled";
if (OS.IsWindows())
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
else if (OS.IsOSX())
{
- settingsHintStr += $",Visual Studio:{(int) ExternalEditor.VisualStudioForMac}" +
- $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",Visual Studio:{(int) ExternalEditorId.VisualStudioForMac}" +
+ $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
else if (OS.IsUnix())
{
- settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" +
- $",Visual Studio Code:{(int) ExternalEditor.VsCode}";
+ settingsHintStr += $",MonoDevelop:{(int) ExternalEditorId.MonoDevelop}" +
+ $",Visual Studio Code:{(int) ExternalEditorId.VsCode}";
}
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
@@ -513,9 +427,32 @@ namespace GodotTools
});
// Export plugin
- AddExportPlugin(new GodotSharpExport());
+ var exportPlugin = new GodotSharpExport();
+ AddExportPlugin(exportPlugin);
+ exportPluginWeak = WeakRef(exportPlugin);
+
+ BuildManager.Initialize();
+
+ GodotIdeManager = new GodotIdeManager();
+ AddChild(GodotIdeManager);
+ }
+
+ 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();
+ }
- GodotSharpBuilds.Initialize();
+ GodotIdeManager?.Dispose();
}
public void OnBeforeSerialize()
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
index b80fe1fab7..4f93ef8530 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
@@ -16,7 +16,7 @@ namespace GodotTools
{
private void AddFile(string srcPath, string dstPath, bool remap = false)
{
- AddFile(dstPath, File.ReadAllBytes(srcPath), remap);
+ AddFile(dstPath.Replace("\\", "/"), File.ReadAllBytes(srcPath), remap);
}
public override void _ExportFile(string path, string type, string[] features)
@@ -65,14 +65,14 @@ namespace GodotTools
string buildConfig = isDebug ? "Debug" : "Release";
string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
- CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
+ CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
AddFile(scriptsMetadataPath, scriptsMetadataPath);
// Turn export features into defines
var godotDefines = features;
- if (!GodotSharpBuilds.BuildProjectBlocking(buildConfig, godotDefines))
+ if (!BuildManager.BuildProjectBlocking(buildConfig, godotDefines))
{
GD.PushError("Failed to build project");
return;
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
index a0ff8a0df1..3c57900873 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
@@ -10,6 +10,7 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
<GodotApiConfiguration>Debug</GodotApiConfiguration>
+ <LangVersion>7</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -39,25 +40,31 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Build\MsBuildFinder.cs" />
+ <Compile Include="ExternalEditorId.cs" />
+ <Compile Include="Ides\GodotIdeManager.cs" />
+ <Compile Include="Ides\GodotIdeServer.cs" />
+ <Compile Include="Ides\MonoDevelop\EditorId.cs" />
+ <Compile Include="Ides\MonoDevelop\Instance.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="MonoDevelopInstance.cs" />
+ <Compile Include="Internals\Globals.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Build\BuildSystem.cs" />
<Compile Include="Utils\Directory.cs" />
<Compile Include="Utils\File.cs" />
+ <Compile Include="Utils\NotifyAwaiter.cs" />
<Compile Include="Utils\OS.cs" />
<Compile Include="GodotSharpEditor.cs" />
- <Compile Include="GodotSharpBuilds.cs" />
+ <Compile Include="BuildManager.cs" />
<Compile Include="HotReloadAssemblyWatcher.cs" />
- <Compile Include="MonoBuildInfo.cs" />
- <Compile Include="MonoBuildTab.cs" />
- <Compile Include="MonoBottomPanel.cs" />
+ <Compile Include="BuildInfo.cs" />
+ <Compile Include="BuildTab.cs" />
+ <Compile Include="BottomPanel.cs" />
<Compile Include="GodotSharpExport.cs" />
- <Compile Include="CSharpProject.cs" />
+ <Compile Include="CsProjOperations.cs" />
<Compile Include="Utils\CollectionExtensions.cs" />
</ItemGroup>
<ItemGroup>
@@ -65,6 +72,10 @@
<Project>{6ce9a984-37b1-4f8a-8fe9-609f05f071b3}</Project>
<Name>GodotTools.BuildLogger</Name>
</ProjectReference>
+ <ProjectReference Include="..\GodotTools.IdeConnection\GodotTools.IdeConnection.csproj">
+ <Project>{92600954-25f0-4291-8e11-1fee9fc4be20}</Project>
+ <Name>GodotTools.IdeConnection</Name>
+ </ProjectReference>
<ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj">
<Project>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</Project>
<Name>GodotTools.ProjectEditor</Name>
@@ -74,8 +85,5 @@
<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
index aa52079cf4..0f6f5ffadc 100644
--- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
@@ -1,5 +1,6 @@
using Godot;
using GodotTools.Internals;
+using static GodotTools.Internals.Globals;
namespace GodotTools
{
@@ -37,7 +38,7 @@ namespace GodotTools
watchTimer = new Timer
{
OneShot = false,
- WaitTime = (float) Internal.EditorDef("mono/assembly_watch_interval_sec", 0.5)
+ WaitTime = (float) EditorDef("mono/assembly_watch_interval_sec", 0.5)
};
watchTimer.Connect("timeout", this, nameof(TimerTimeout));
AddChild(watchTimer);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
new file mode 100644
index 0000000000..9e24138143
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
@@ -0,0 +1,166 @@
+using System;
+using System.IO;
+using Godot;
+using GodotTools.IdeConnection;
+using GodotTools.Internals;
+
+namespace GodotTools.Ides
+{
+ public class GodotIdeManager : Node, ISerializationListener
+ {
+ public GodotIdeServer GodotIdeServer { get; private set; }
+
+ private MonoDevelop.Instance monoDevelInstance;
+ private MonoDevelop.Instance vsForMacInstance;
+
+ private GodotIdeServer GetRunningServer()
+ {
+ if (GodotIdeServer != null && !GodotIdeServer.IsDisposed)
+ return GodotIdeServer;
+ StartServer();
+ return GodotIdeServer;
+ }
+
+ public override void _Ready()
+ {
+ StartServer();
+ }
+
+ public void OnBeforeSerialize()
+ {
+ GodotIdeServer?.Dispose();
+ }
+
+ public void OnAfterDeserialize()
+ {
+ StartServer();
+ }
+
+ private ILogger logger;
+
+ protected ILogger Logger
+ {
+ get => logger ?? (logger = new ConsoleLogger());
+ set => logger = value;
+ }
+
+ private void StartServer()
+ {
+ GodotIdeServer?.Dispose();
+ GodotIdeServer = new GodotIdeServer(LaunchIde,
+ OS.GetExecutablePath(),
+ ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir));
+
+ GodotIdeServer.Logger = Logger;
+
+ GodotIdeServer.StartServer();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ GodotIdeServer?.Dispose();
+ }
+
+ private void LaunchIde()
+ {
+ var editor = (ExternalEditorId) GodotSharpEditor.Instance.GetEditorInterface()
+ .GetEditorSettings().GetSetting("mono/editor/external_editor");
+
+ switch (editor)
+ {
+ case ExternalEditorId.None:
+ case ExternalEditorId.VisualStudio:
+ case ExternalEditorId.VsCode:
+ throw new NotSupportedException();
+ case ExternalEditorId.VisualStudioForMac:
+ goto case ExternalEditorId.MonoDevelop;
+ case ExternalEditorId.MonoDevelop:
+ {
+ MonoDevelop.Instance GetMonoDevelopInstance(string solutionPath)
+ {
+ if (Utils.OS.IsOSX() && editor == ExternalEditorId.VisualStudioForMac)
+ {
+ vsForMacInstance = vsForMacInstance ??
+ new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.VisualStudioForMac);
+ return vsForMacInstance;
+ }
+
+ monoDevelInstance = monoDevelInstance ??
+ new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.MonoDevelop);
+ return monoDevelInstance;
+ }
+
+ try
+ {
+ var instance = GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath);
+
+ if (!instance.IsRunning)
+ instance.Execute();
+ }
+ catch (FileNotFoundException)
+ {
+ string editorName = editor == ExternalEditorId.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
+ GD.PushError($"Cannot find code editor: {editorName}");
+ }
+
+ break;
+ }
+
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private void WriteMessage(string id, params string[] arguments)
+ {
+ GetRunningServer().WriteMessage(new Message(id, arguments));
+ }
+
+ public void SendOpenFile(string file)
+ {
+ WriteMessage("OpenFile", file);
+ }
+
+ public void SendOpenFile(string file, int line)
+ {
+ WriteMessage("OpenFile", file, line.ToString());
+ }
+
+ public void SendOpenFile(string file, int line, int column)
+ {
+ WriteMessage("OpenFile", file, line.ToString(), column.ToString());
+ }
+
+ private class GodotLogger : ILogger
+ {
+ public void LogDebug(string message)
+ {
+ if (OS.IsStdoutVerbose())
+ Console.WriteLine(message);
+ }
+
+ public void LogInfo(string message)
+ {
+ if (OS.IsStdoutVerbose())
+ Console.WriteLine(message);
+ }
+
+ public void LogWarning(string message)
+ {
+ GD.PushWarning(message);
+ }
+
+ public void LogError(string message)
+ {
+ GD.PushError(message);
+ }
+
+ public void LogError(string message, Exception e)
+ {
+ GD.PushError(message + "\n" + e);
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
new file mode 100644
index 0000000000..309b917c71
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeConnection;
+using GodotTools.Internals;
+using GodotTools.Utils;
+using Directory = System.IO.Directory;
+using File = System.IO.File;
+using Thread = System.Threading.Thread;
+
+namespace GodotTools.Ides
+{
+ public class GodotIdeServer : GodotIdeBase
+ {
+ private readonly TcpListener listener;
+ private readonly FileStream metaFile;
+ private readonly Action launchIdeAction;
+ private readonly NotifyAwaiter<bool> clientConnectedAwaiter = new NotifyAwaiter<bool>();
+
+ private async Task<bool> AwaitClientConnected()
+ {
+ return await clientConnectedAwaiter.Reset();
+ }
+
+ public GodotIdeServer(Action launchIdeAction, string editorExecutablePath, string projectMetadataDir)
+ : base(projectMetadataDir)
+ {
+ messageHandlers = InitializeMessageHandlers();
+
+ this.launchIdeAction = launchIdeAction;
+
+ // Make sure the directory exists
+ Directory.CreateDirectory(projectMetadataDir);
+
+ // The Godot editor's file system thread can keep the file open for writing, so we are forced to allow write sharing...
+ const FileShare metaFileShare = FileShare.ReadWrite;
+
+ metaFile = File.Open(MetaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
+
+ listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
+ listener.Start();
+
+ int port = ((IPEndPoint) listener.Server.LocalEndPoint).Port;
+ using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
+ {
+ metaFileWriter.WriteLine(port);
+ metaFileWriter.WriteLine(editorExecutablePath);
+ }
+
+ StartServer();
+ }
+
+ public void StartServer()
+ {
+ var serverThread = new Thread(RunServerThread) {Name = "Godot Ide Connection Server"};
+ serverThread.Start();
+ }
+
+ private void RunServerThread()
+ {
+ SynchronizationContext.SetSynchronizationContext(Godot.Dispatcher.SynchronizationContext);
+
+ try
+ {
+ while (!IsDisposed)
+ {
+ TcpClient tcpClient = listener.AcceptTcpClient();
+
+ Logger.LogInfo("Connection open with Ide Client");
+
+ lock (ConnectionLock)
+ {
+ Connection = new GodotIdeConnectionServer(tcpClient, HandleMessage);
+ Connection.Logger = Logger;
+ }
+
+ Connected += () => clientConnectedAwaiter.SetResult(true);
+
+ Connection.Start();
+ }
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed && !(e is SocketException se && se.SocketErrorCode == SocketError.Interrupted))
+ throw;
+ }
+ }
+
+ public async void WriteMessage(Message message)
+ {
+ async Task LaunchIde()
+ {
+ if (IsConnected)
+ return;
+
+ launchIdeAction();
+ await Task.WhenAny(Task.Delay(10000), AwaitClientConnected());
+ }
+
+ await LaunchIde();
+
+ if (!IsConnected)
+ {
+ Logger.LogError("Cannot write message: Godot Ide Server not connected");
+ return;
+ }
+
+ Connection.WriteMessage(message);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ listener?.Stop();
+
+ metaFile?.Dispose();
+
+ File.Delete(MetaFilePath);
+ }
+ }
+
+ protected virtual bool HandleMessage(Message message)
+ {
+ if (messageHandlers.TryGetValue(message.Id, out var action))
+ {
+ action(message.Arguments);
+ return true;
+ }
+
+ return false;
+ }
+
+ private readonly Dictionary<string, Action<string[]>> messageHandlers;
+
+ private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
+ {
+ return new Dictionary<string, Action<string[]>>
+ {
+ ["Play"] = args =>
+ {
+ switch (args.Length)
+ {
+ case 0:
+ Play();
+ return;
+ case 2:
+ Play(debuggerHost: args[0], debuggerPort: int.Parse(args[1]));
+ return;
+ default:
+ throw new ArgumentException();
+ }
+ },
+ ["ReloadScripts"] = args => ReloadScripts()
+ };
+ }
+
+ private void DispatchToMainThread(Action action)
+ {
+ var d = new SendOrPostCallback(state => action());
+ Godot.Dispatcher.SynchronizationContext.Post(d, null);
+ }
+
+ private void Play()
+ {
+ DispatchToMainThread(() =>
+ {
+ CurrentPlayRequest = new PlayRequest();
+ Internal.EditorRunPlay();
+ CurrentPlayRequest = null;
+ });
+ }
+
+ private void Play(string debuggerHost, int debuggerPort)
+ {
+ DispatchToMainThread(() =>
+ {
+ CurrentPlayRequest = new PlayRequest(debuggerHost, debuggerPort);
+ Internal.EditorRunPlay();
+ CurrentPlayRequest = null;
+ });
+ }
+
+ private void ReloadScripts()
+ {
+ DispatchToMainThread(Internal.ScriptEditorDebugger_ReloadScripts);
+ }
+
+ public PlayRequest? CurrentPlayRequest { get; private set; }
+
+ public struct PlayRequest
+ {
+ public bool HasDebugger { get; }
+ public string DebuggerHost { get; }
+ public int DebuggerPort { get; }
+
+ public PlayRequest(string debuggerHost, int debuggerPort)
+ {
+ HasDebugger = true;
+ DebuggerHost = debuggerHost;
+ DebuggerPort = debuggerPort;
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs
new file mode 100644
index 0000000000..1dfc91d6d1
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/EditorId.cs
@@ -0,0 +1,8 @@
+namespace GodotTools.Ides.MonoDevelop
+{
+ public enum EditorId
+ {
+ MonoDevelop = 0,
+ VisualStudioForMac = 1
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
index 0c8d86e799..1fdccf5bbd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
@@ -1,26 +1,22 @@
-using GodotTools.Core;
using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using GodotTools.Internals;
+using GodotTools.Utils;
-namespace GodotTools
+namespace GodotTools.Ides.MonoDevelop
{
- public class MonoDevelopInstance
+ public class Instance
{
- public enum EditorId
- {
- MonoDevelop = 0,
- VisualStudioForMac = 1
- }
-
private readonly string solutionFile;
private readonly EditorId editorId;
private Process process;
- public void Execute(params string[] files)
+ public bool IsRunning => process != null && !process.HasExited;
+
+ public void Execute()
{
bool newWindow = process == null || process.HasExited;
@@ -28,9 +24,9 @@ namespace GodotTools
string command;
- if (Utils.OS.IsOSX())
+ if (OS.IsOSX())
{
- string bundleId = CodeEditorBundleIds[editorId];
+ string bundleId = BundleIds[editorId];
if (Internal.IsOsxAppBundleInstalled(bundleId))
{
@@ -47,12 +43,12 @@ namespace GodotTools
}
else
{
- command = CodeEditorPaths[editorId];
+ command = OS.PathWhich(ExecutableNames[editorId]);
}
}
else
{
- command = CodeEditorPaths[editorId];
+ command = OS.PathWhich(ExecutableNames[editorId]);
}
args.Add("--ipc-tcp");
@@ -60,15 +56,8 @@ namespace GodotTools
if (newWindow)
args.Add("\"" + Path.GetFullPath(solutionFile) + "\"");
- foreach (var file in files)
- {
- int semicolonIndex = file.IndexOf(';');
-
- string filePath = semicolonIndex < 0 ? file : file.Substring(0, semicolonIndex);
- string cursor = semicolonIndex < 0 ? string.Empty : file.Substring(semicolonIndex);
-
- args.Add("\"" + Path.GetFullPath(filePath.NormalizePath()) + cursor + "\"");
- }
+ if (command == null)
+ throw new FileNotFoundException();
if (newWindow)
{
@@ -76,7 +65,7 @@ namespace GodotTools
{
FileName = command,
Arguments = string.Join(" ", args),
- UseShellExecute = false
+ UseShellExecute = true
});
}
else
@@ -85,42 +74,42 @@ namespace GodotTools
{
FileName = command,
Arguments = string.Join(" ", args),
- UseShellExecute = false
+ UseShellExecute = true
})?.Dispose();
}
}
- public MonoDevelopInstance(string solutionFile, EditorId editorId)
+ public Instance(string solutionFile, EditorId editorId)
{
- if (editorId == EditorId.VisualStudioForMac && !Utils.OS.IsOSX())
+ if (editorId == EditorId.VisualStudioForMac && !OS.IsOSX())
throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
this.solutionFile = solutionFile;
this.editorId = editorId;
}
- private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorPaths;
- private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorBundleIds;
+ private static readonly IReadOnlyDictionary<EditorId, string> ExecutableNames;
+ private static readonly IReadOnlyDictionary<EditorId, string> BundleIds;
- static MonoDevelopInstance()
+ static Instance()
{
- if (Utils.OS.IsOSX())
+ if (OS.IsOSX())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = new Dictionary<EditorId, string>
{
// Rely on PATH
{EditorId.MonoDevelop, "monodevelop"},
{EditorId.VisualStudioForMac, "VisualStudio"}
};
- CodeEditorBundleIds = new Dictionary<EditorId, string>
+ BundleIds = new Dictionary<EditorId, string>
{
// TODO EditorId.MonoDevelop
{EditorId.VisualStudioForMac, "com.microsoft.visual-studio"}
};
}
- else if (Utils.OS.IsWindows())
+ else if (OS.IsWindows())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = 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
@@ -129,9 +118,9 @@ namespace GodotTools
{EditorId.MonoDevelop, "MonoDevelop.exe"}
};
}
- else if (Utils.OS.IsUnix())
+ else if (OS.IsUnix())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = new Dictionary<EditorId, string>
{
// Rely on PATH
{EditorId.MonoDevelop, "monodevelop"}
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/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 5c7ce832cd..7783576910 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -10,13 +10,8 @@ namespace GodotTools.Internals
public const string CSharpLanguageType = "CSharpScript";
public const string CSharpLanguageExtension = "cs";
- 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);
+ public static string UpdateApiAssembliesFromPrebuilt() =>
+ internal_UpdateApiAssembliesFromPrebuilt();
public static string FullTemplatesDir =>
internal_FullTemplatesDir();
@@ -25,14 +20,6 @@ namespace GodotTools.Internals
public static bool IsOsxAppBundleInstalled(string bundleId) => internal_IsOsxAppBundleInstalled(bundleId);
- public static bool MetadataIsApiAssemblyInvalidated(ApiAssemblyType apiType) =>
- internal_MetadataIsApiAssemblyInvalidated(apiType);
-
- public static void MetadataSetApiAssemblyInvalidated(ApiAssemblyType apiType, bool invalidated) =>
- internal_MetadataSetApiAssemblyInvalidated(apiType, invalidated);
-
- public static bool IsMessageQueueFlushing() => internal_IsMessageQueueFlushing();
-
public static bool GodotIs32Bits() => internal_GodotIs32Bits();
public static bool GodotIsRealTDouble() => internal_GodotIsRealTDouble();
@@ -59,16 +46,16 @@ namespace GodotTools.Internals
public static string MonoWindowsInstallRoot => internal_MonoWindowsInstallRoot();
- // Internal Calls
+ public static void EditorRunPlay() => internal_EditorRunPlay();
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern float internal_EditorScale();
+ public static void EditorRunStop() => internal_EditorRunStop();
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern object internal_GlobalDef(string setting, object defaultValue, bool restartIfChanged);
+ public static void ScriptEditorDebugger_ReloadScripts() => internal_ScriptEditorDebugger_ReloadScripts();
+
+ // Internal Calls
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern object internal_EditorDef(string setting, object defaultValue, bool restartIfChanged);
+ private static extern string internal_UpdateApiAssembliesFromPrebuilt();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_FullTemplatesDir();
@@ -80,15 +67,6 @@ namespace GodotTools.Internals
private static extern bool internal_IsOsxAppBundleInstalled(string bundleId);
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern bool internal_MetadataIsApiAssemblyInvalidated(ApiAssemblyType apiType);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_MetadataSetApiAssemblyInvalidated(ApiAssemblyType apiType, bool invalidated);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern bool internal_IsMessageQueueFlushing();
-
- [MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool internal_GodotIs32Bits();
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -123,5 +101,14 @@ namespace GodotTools.Internals
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoWindowsInstallRoot();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_EditorRunPlay();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_EditorRunStop();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void internal_ScriptEditorDebugger_ReloadScripts();
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
index 3ae6c10bbf..e3c2c822a5 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
namespace GodotTools.Utils
{
@@ -10,11 +11,19 @@ namespace GodotTools.Utils
{
foreach (T elem in enumerable)
{
- if (predicate(elem) != null)
- return elem;
+ T result = predicate(elem);
+ if (result != null)
+ return result;
}
return orElse;
}
+
+ public static IEnumerable<string> EnumerateLines(this TextReader textReader)
+ {
+ string line;
+ while ((line = textReader.ReadLine()) != null)
+ yield return line;
+ }
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs
new file mode 100644
index 0000000000..700b786752
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace GodotTools.Utils
+{
+ public sealed class NotifyAwaiter<T> : INotifyCompletion
+ {
+ private Action continuation;
+ private Exception exception;
+ private T result;
+
+ public bool IsCompleted { get; private set; }
+
+ public T GetResult()
+ {
+ if (exception != null)
+ throw exception;
+ return result;
+ }
+
+ public void OnCompleted(Action continuation)
+ {
+ if (this.continuation != null)
+ throw new InvalidOperationException("This awaiter has already been listened");
+ this.continuation = continuation;
+ }
+
+ public void SetResult(T result)
+ {
+ if (IsCompleted)
+ throw new InvalidOperationException("This awaiter is already completed");
+
+ IsCompleted = true;
+ this.result = result;
+
+ continuation?.Invoke();
+ }
+
+ public void SetException(Exception exception)
+ {
+ if (IsCompleted)
+ throw new InvalidOperationException("This awaiter is already completed");
+
+ IsCompleted = true;
+ this.exception = exception;
+
+ continuation?.Invoke();
+ }
+
+ public NotifyAwaiter<T> Reset()
+ {
+ continuation = null;
+ exception = null;
+ result = default(T);
+ IsCompleted = false;
+ return this;
+ }
+
+ public NotifyAwaiter<T> GetAwaiter()
+ {
+ return this;
+ }
+ }
+}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 45037bf637..74710db224 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -279,7 +279,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
Vector<String> link_target_parts = link_target.split(".");
if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) {
- ERR_PRINTS("Invalid reference format: " + tag);
+ ERR_PRINTS("Invalid reference format: '" + tag + "'.");
xml_output.append("<c>");
xml_output.append(tag);
@@ -375,7 +375,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any
xml_output.append("\"/>");
} else {
- ERR_PRINTS("Cannot resolve enum reference in documentation: " + link_target);
+ ERR_PRINTS("Cannot resolve enum reference in documentation: '" + link_target + "'.");
xml_output.append("<c>");
xml_output.append(link_target);
@@ -424,7 +424,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_iconst->proxy_name);
xml_output.append("\"/>");
} else {
- ERR_PRINTS("Cannot resolve global constant reference in documentation: " + link_target);
+ ERR_PRINTS("Cannot resolve global constant reference in documentation: '" + link_target + "'.");
xml_output.append("<c>");
xml_output.append(link_target);
@@ -464,7 +464,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_iconst->proxy_name);
xml_output.append("\"/>");
} else {
- ERR_PRINTS("Cannot resolve constant reference in documentation: " + link_target);
+ ERR_PRINTS("Cannot resolve constant reference in documentation: '" + link_target + "'.");
xml_output.append("<c>");
xml_output.append(link_target);
@@ -534,7 +534,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(target_itype->proxy_name);
xml_output.append("\"/>");
} else {
- ERR_PRINTS("Cannot resolve type reference in documentation: " + tag);
+ ERR_PRINTS("Cannot resolve type reference in documentation: '" + tag + "'.");
xml_output.append("<c>");
xml_output.append(tag);
@@ -812,7 +812,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
CRASH_COND(enum_class_name != "Variant"); // Hard-coded...
- _log("Declaring global enum `%s` inside static class `%s`\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data());
+ _log("Declaring global enum '%s' inside static class '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data());
p_output.append("\n" INDENT1 "public static partial class ");
p_output.append(enum_class_name);
@@ -1083,7 +1083,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
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");
+ ERR_PRINT("Generation of the Core API C# project failed.");
return proj_err;
}
@@ -1094,7 +1094,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
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");
+ ERR_PRINT("Generation of the Editor API C# project failed.");
return proj_err;
}
@@ -1112,7 +1112,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// FIXME: There are some members that hide other inherited members.
// - In the case of both members being the same kind, the new one must be declared
-// explicitly as `new` to avoid the warning (and we must print a message about it).
+// explicitly as 'new' to avoid the warning (and we must print a message about it).
// - In the case of both members being of a different kind, then the new one must
// be renamed to avoid the name collision (and we must print a warning about it).
// - Csc warning e.g.:
@@ -1186,7 +1186,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(obj_types[itype.base_name].proxy_name);
output.append("\n");
} else {
- ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class " + itype.name);
+ ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class '" + itype.name + "'.");
return ERR_INVALID_DATA;
}
}
@@ -1273,11 +1273,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) {
const PropertyInterface &iprop = E->get();
Error prop_err = _generate_cs_property(itype, iprop, output);
- if (prop_err != OK) {
- ERR_EXPLAIN("Failed to generate property '" + iprop.cname.operator String() +
- "' for class '" + itype.name + "'");
- ERR_FAIL_V(prop_err);
- }
+ ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err,
+ "Failed to generate property '" + iprop.cname.operator String() +
+ "' for class '" + itype.name + "'.");
}
}
@@ -1340,10 +1338,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
Error method_err = _generate_cs_method(itype, imethod, method_bind_count, output);
- if (method_err != OK) {
- ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
- ERR_FAIL_V(method_err);
- }
+ ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
+ "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
}
if (itype.is_singleton) {
@@ -1626,7 +1622,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (p_imethod.is_deprecated) {
if (p_imethod.deprecation_message.empty())
- WARN_PRINTS("An empty deprecation message is discouraged. Method: " + p_imethod.proxy_name);
+ WARN_PRINTS("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'.");
p_output.append(MEMBER_BEGIN "[Obsolete(\"");
p_output.append(p_imethod.deprecation_message);
@@ -1708,8 +1704,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
Error BindingsGenerator::generate_glue(const String &p_output_dir) {
bool dir_exists = DirAccess::exists(p_output_dir);
- ERR_EXPLAIN("The output directory does not exist.");
- ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);
+ ERR_FAIL_COND_V_MSG(!dir_exists, ERR_FILE_BAD_PATH, "The output directory does not exist.");
StringBuilder output;
@@ -1742,10 +1737,8 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
Error method_err = _generate_glue_method(itype, imethod, output);
- if (method_err != OK) {
- ERR_EXPLAIN("Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'");
- ERR_FAIL_V(method_err);
- }
+ ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
+ "Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
}
if (itype.is_singleton) {
@@ -1792,6 +1785,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.append("uint32_t get_bindings_version() { return ");
output.append(String::num_uint64(BINDINGS_GENERATOR_VERSION) + "; }\n");
+ output.append("uint32_t get_cs_glue_version() { return ");
+ output.append(String::num_uint64(CS_GLUE_VERSION) + "; }\n");
+
output.append("\nvoid register_generated_icalls() " OPEN_BLOCK);
output.append("\tgodot_register_glue_header_icalls();\n");
@@ -1879,8 +1875,7 @@ Error BindingsGenerator::_save_file(const String &p_path, const StringBuilder &p
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_EXPLAIN("Cannot open file: " + p_path);
- ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
+ ERR_FAIL_COND_V_MSG(!file, ERR_FILE_CANT_WRITE, "Cannot open file: '" + p_path + "'.");
file->store_string(p_content.as_string());
file->close();
@@ -2091,7 +2086,7 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol
if (found)
return found;
- ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_typeref.cname.operator String());
+ ERR_PRINTS(String() + "Type not found. Creating placeholder: '" + p_typeref.cname.operator String() + "'.");
const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname);
@@ -2175,13 +2170,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
}
if (!ClassDB::is_class_exposed(type_cname)) {
- _log("Ignoring type `%s` because it's not exposed\n", String(type_cname).utf8().get_data());
+ _log("Ignoring type '%s' because it's not exposed\n", String(type_cname).utf8().get_data());
class_list.pop_front();
continue;
}
if (!ClassDB::is_class_enabled(type_cname)) {
- _log("Ignoring type `%s` because it's not enabled\n", String(type_cname).utf8().get_data());
+ _log("Ignoring type '%s' because it's not enabled\n", String(type_cname).utf8().get_data());
class_list.pop_front();
continue;
}
@@ -2240,7 +2235,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the property and its enclosing type from sharing the same name
if (iprop.proxy_name == itype.proxy_name) {
- _log("Name of property `%s` is ambiguous with the name of its enclosing class `%s`. Renaming property to `%s_`\n",
+ _log("Name of property '%s' is ambiguous with the name of its enclosing class '%s'. Renaming property to '%s_'\n",
iprop.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), iprop.proxy_name.utf8().get_data());
iprop.proxy_name += "_";
@@ -2298,28 +2293,26 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.is_vararg = m && m->is_vararg();
if (!m && !imethod.is_virtual) {
- if (virtual_method_list.find(method_info)) {
- // A virtual method without the virtual flag. This is a special case.
-
- // There is no method bind, so let's fallback to Godot's object.Call(string, params)
- imethod.requires_object_call = true;
-
- // The method Object.free is registered as a virtual method, but without the virtual flag.
- // This is because this method is not supposed to be overridden, but called.
- // We assume the return type is void.
- imethod.return_type.cname = name_cache.type_void;
-
- // Actually, more methods like this may be added in the future,
- // which could actually will return something different.
- // Let's put this to notify us if that ever happens.
- if (itype.cname != name_cache.type_Object || imethod.name != "free") {
- ERR_PRINTS("Notification: New unexpected virtual non-overridable method found.\n"
- "We only expected Object.free, but found " +
- itype.name + "." + imethod.name);
- }
- } else {
- ERR_EXPLAIN("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
- ERR_FAIL();
+ ERR_FAIL_COND_MSG(!virtual_method_list.find(method_info),
+ "Missing MethodBind for non-virtual method: '" + itype.name + "." + imethod.name + "'.");
+
+ // A virtual method without the virtual flag. This is a special case.
+
+ // There is no method bind, so let's fallback to Godot's object.Call(string, params)
+ imethod.requires_object_call = true;
+
+ // The method Object.free is registered as a virtual method, but without the virtual flag.
+ // This is because this method is not supposed to be overridden, but called.
+ // We assume the return type is void.
+ imethod.return_type.cname = name_cache.type_void;
+
+ // Actually, more methods like this may be added in the future,
+ // which could actually will return something different.
+ // Let's put this to notify us if that ever happens.
+ if (itype.cname != name_cache.type_Object || imethod.name != "free") {
+ ERR_PRINTS("Notification: New unexpected virtual non-overridable method found."
+ " We only expected Object.free, but found '" +
+ itype.name + "." + imethod.name + "'.");
}
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
imethod.return_type.cname = return_info.class_name;
@@ -2328,8 +2321,8 @@ void BindingsGenerator::_populate_object_type_interfaces() {
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);
+ 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();
}
@@ -2394,7 +2387,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// Prevent the method and its enclosing type from sharing the same name
if (imethod.proxy_name == itype.proxy_name) {
- _log("Name of method `%s` is ambiguous with the name of its enclosing class `%s`. Renaming method to `%s_`\n",
+ _log("Name of method '%s' is ambiguous with the name of its enclosing class '%s'. Renaming method to '%s_'\n",
imethod.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), imethod.proxy_name.utf8().get_data());
imethod.proxy_name += "_";
@@ -2880,8 +2873,7 @@ void BindingsGenerator::_populate_global_constants() {
if (global_constants_count > 0) {
Map<String, DocData::ClassDoc>::Element *match = EditorHelp::get_doc_data()->class_list.find("@GlobalScope");
- ERR_EXPLAIN("Could not find `@GlobalScope` in DocData");
- CRASH_COND(!match);
+ CRASH_COND_MSG(!match, "Could not find '@GlobalScope' in DocData.");
const DocData::ClassDoc &global_scope_doc = match->value();
@@ -2935,7 +2927,7 @@ void BindingsGenerator::_populate_global_constants() {
// HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'.
if (ienum.cname == name_cache.enum_Error) {
if (prefix_length > 0) { // Just in case it ever changes
- ERR_PRINTS("Prefix for enum 'Error' is not empty");
+ ERR_PRINTS("Prefix for enum '" _STR(Error) "' is not empty.");
}
prefix_length = 1; // 'ERR_'
@@ -3024,7 +3016,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
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)");
+ ERR_PRINTS(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue').");
}
--options_left;
@@ -3035,7 +3027,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cs_dir_path = path_elem->get();
elem = elem->next();
} else {
- ERR_PRINTS(generate_cs_glue_option + ": No output directory specified");
+ ERR_PRINTS(generate_cs_glue_option + ": No output directory specified.");
}
--options_left;
@@ -3046,7 +3038,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
cpp_dir_path = path_elem->get();
elem = elem->next();
} else {
- ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified");
+ ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified.");
}
--options_left;
@@ -3061,20 +3053,20 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
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");
+ 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");
+ 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");
+ ERR_PRINTS(generate_cs_glue_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");
+ 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 8be51a6c55..6f0c297575 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -147,7 +147,7 @@ class BindingsGenerator {
bool requires_object_call;
/**
- * Determines if the method visibility is `internal` (visible only to files in the same assembly).
+ * Determines if the method visibility is 'internal' (visible only to files in the same assembly).
* Currently, we only use this for methods that are not meant to be exposed,
* but are required by properties as getters or setters.
* Methods that are not meant to be exposed are those that begin with underscore and are not virtual.
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index d88b08c646..0e6c58c9d7 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -81,16 +81,14 @@ bool generate_api_solution(const String &p_solution_dir, const String &p_core_pr
_GDMONO_SCOPE_DOMAIN_(temp_domain);
- GDMonoAssembly *tools_project_editor_assembly = NULL;
+ GDMonoAssembly *tools_project_editor_asm = NULL;
- if (!GDMono::get_singleton()->load_assembly("GodotTools.ProjectEditor", &tools_project_editor_assembly)) {
- ERR_EXPLAIN("Failed to load assembly: 'GodotTools.ProjectEditor'");
- ERR_FAIL_V(false);
- }
+ bool assembly_loaded = GDMono::get_singleton()->load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_asm);
+ ERR_FAIL_COND_V_MSG(!assembly_loaded, false, "Failed to load assembly: '" TOOLS_PROJECT_EDITOR_ASM_NAME "'.");
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);
+ tools_project_editor_asm);
}
}
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index a3b5b450ef..5a84d9e3b8 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -30,7 +30,6 @@
#include "editor_internal_calls.h"
-#include "core/message_queue.h"
#include "core/os/os.h"
#include "core/version.h"
#include "editor/editor_node.h"
@@ -231,24 +230,34 @@ uint32_t godot_icall_GodotSharpExport_GetExportedAssemblyDependencies(MonoString
return GodotSharpExport::get_exported_assembly_dependencies(project_dll_name, project_dll_src_path, build_config, custom_lib_dir, dependencies);
}
-float godot_icall_Internal_EditorScale() {
+float godot_icall_Globals_EditorScale() {
return EDSCALE;
}
-MonoObject *godot_icall_Internal_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) {
+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_Internal_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) {
+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 = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed);
+ 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);
@@ -262,25 +271,13 @@ MonoString *godot_icall_Internal_SimplifyGodotPath(MonoString *p_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;
+ return (MonoBoolean)osx_is_app_bundle_installed(bundle_id);
#else
(void)p_bundle_id; // UNUSED
return (MonoBoolean) false;
#endif
}
-MonoBoolean godot_icall_Internal_MetadataIsApiAssemblyInvalidated(int32_t p_api_type) {
- return GDMono::get_singleton()->metadata_is_api_assembly_invalidated((APIAssembly::Type)p_api_type);
-}
-
-void godot_icall_Internal_MetadataSetApiAssemblyInvalidated(int32_t p_api_type, MonoBoolean p_invalidated) {
- GDMono::get_singleton()->metadata_set_api_assembly_invalidated((APIAssembly::Type)p_api_type, (bool)p_invalidated);
-}
-
-MonoBoolean godot_icall_Internal_IsMessageQueueFlushing() {
- return (MonoBoolean)MessageQueue::get_singleton()->is_flushing();
-}
-
MonoBoolean godot_icall_Internal_GodotIs32Bits() {
return sizeof(void *) == 4;
}
@@ -353,6 +350,21 @@ MonoString *godot_icall_Internal_MonoWindowsInstallRoot() {
#endif
}
+void godot_icall_Internal_EditorRunPlay() {
+ EditorNode::get_singleton()->run_play();
+}
+
+void godot_icall_Internal_EditorRunStop() {
+ EditorNode::get_singleton()->run_stop();
+}
+
+void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() {
+ ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
+ if (sed) {
+ sed->reload_scripts();
+ }
+}
+
MonoString *godot_icall_Utils_OS_GetPlatformName() {
String os_name = OS::get_singleton()->get_name();
return GDMonoMarshal::mono_string_from_godot(os_name);
@@ -402,15 +414,10 @@ void register_editor_internal_calls() {
mono_add_internal_call("GodotTools.GodotSharpExport::internal_GetExportedAssemblyDependencies", (void *)godot_icall_GodotSharpExport_GetExportedAssemblyDependencies);
// Internals
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorScale", (void *)godot_icall_Internal_EditorScale);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GlobalDef", (void *)godot_icall_Internal_GlobalDef);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorDef", (void *)godot_icall_Internal_EditorDef);
+ 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_MetadataIsApiAssemblyInvalidated", (void *)godot_icall_Internal_MetadataIsApiAssemblyInvalidated);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_MetadataSetApiAssemblyInvalidated", (void *)godot_icall_Internal_MetadataSetApiAssemblyInvalidated);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_IsMessageQueueFlushing", (void *)godot_icall_Internal_IsMessageQueueFlushing);
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);
@@ -423,6 +430,15 @@ void register_editor_internal_calls() {
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);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
+
+ // 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/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 020bb70a08..80a7335b1d 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -85,18 +85,12 @@ Error GodotSharpExport::get_assembly_dependencies(GDMonoAssembly *p_assembly, co
}
}
- if (!ref_assembly) {
- ERR_EXPLAIN("Cannot load assembly (refonly): " + ref_name);
- ERR_FAIL_V(ERR_CANT_RESOLVE);
- }
+ ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
r_dependencies[ref_name] = ref_assembly->get_path();
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);
- }
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
return OK;
@@ -113,8 +107,7 @@ Error GodotSharpExport::get_exported_assembly_dependencies(const String &p_proje
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);
+ ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + p_project_dll_name + "'.");
Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_lib_dir);
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
index dfb652a7aa..dcb0ca5a80 100644
--- a/modules/mono/editor/script_class_parser.cpp
+++ b/modules/mono/editor/script_class_parser.cpp
@@ -162,8 +162,8 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
error = true;
return TK_ERROR;
} else if (code[idx] == begin_str) {
- if (verbatim && code[idx + 1] == '"') { // `""` is verbatim string's `\"`
- idx += 2; // skip next `"` as well
+ if (verbatim && code[idx + 1] == '"') { // '""' is verbatim string's '\"'
+ idx += 2; // skip next '"' as well
continue;
}
@@ -590,7 +590,7 @@ Error ScriptClassParser::parse(const String &p_code) {
name = String(value);
} else if (tk == TK_CURLY_BRACKET_OPEN) {
if (name.empty()) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword `struct`, found " + get_token_name(TK_CURLY_BRACKET_OPEN);
+ error_str = "Expected " + get_token_name(TK_IDENTIFIER) + " after keyword 'struct', found " + get_token_name(TK_CURLY_BRACKET_OPEN);
error = true;
return ERR_PARSE_ERROR;
}
@@ -657,12 +657,12 @@ Error ScriptClassParser::parse_file(const String &p_filepath) {
String source;
Error ferr = read_all_file_utf8(p_filepath, source);
- if (ferr != OK) {
- if (ferr == ERR_INVALID_DATA) {
- ERR_EXPLAIN("File '" + p_filepath + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
- }
- ERR_FAIL_V(ferr);
- }
+
+ ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
+ ferr == ERR_INVALID_DATA ?
+ "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded."
+ " Please ensure that scripts are saved in valid UTF-8 unicode." :
+ "Failed to read file: '" + p_filepath + "'.");
return parse(source);
}
diff --git a/modules/mono/glue/Managed/Files/AABB.cs b/modules/mono/glue/Managed/Files/AABB.cs
index a2ebbc0736..98a73382f4 100644
--- a/modules/mono/glue/Managed/Files/AABB.cs
+++ b/modules/mono/glue/Managed/Files/AABB.cs
@@ -5,6 +5,7 @@
// file: core/variant_call.cpp
// commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685
using System;
+using System.Runtime.InteropServices;
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
@@ -13,6 +14,8 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
public struct AABB : IEquatable<AABB>
{
private Vector3 _position;
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index 9cc31a0557..0eb76e9c63 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -8,43 +8,10 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Basis : IEquatable<Basis>
{
- private static readonly Basis identity = new Basis
- (
- 1f, 0f, 0f,
- 0f, 1f, 0f,
- 0f, 0f, 1f
- );
-
- private static readonly Basis[] orthoBases = {
- new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
- new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
- new Basis(-1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f),
- new Basis(0f, 1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f),
- new Basis(1f, 0f, 0f, 0f, 0f, -1f, 0f, 1f, 0f),
- new Basis(0f, 0f, 1f, 1f, 0f, 0f, 0f, 1f, 0f),
- new Basis(-1f, 0f, 0f, 0f, 0f, 1f, 0f, 1f, 0f),
- new Basis(0f, 0f, -1f, -1f, 0f, 0f, 0f, 1f, 0f),
- new Basis(1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, -1f),
- new Basis(0f, 1f, 0f, 1f, 0f, 0f, 0f, 0f, -1f),
- new Basis(-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, -1f),
- new Basis(0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, -1f),
- new Basis(1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f),
- new Basis(0f, 0f, -1f, 1f, 0f, 0f, 0f, -1f, 0f),
- new Basis(-1f, 0f, 0f, 0f, 0f, -1f, 0f, -1f, 0f),
- new Basis(0f, 0f, 1f, -1f, 0f, 0f, 0f, -1f, 0f),
- new Basis(0f, 0f, 1f, 0f, 1f, 0f, -1f, 0f, 0f),
- new Basis(0f, -1f, 0f, 0f, 0f, 1f, -1f, 0f, 0f),
- new Basis(0f, 0f, -1f, 0f, -1f, 0f, -1f, 0f, 0f),
- new Basis(0f, 1f, 0f, 0f, 0f, -1f, -1f, 0f, 0f),
- new Basis(0f, 0f, 1f, 0f, -1f, 0f, 1f, 0f, 0f),
- new Basis(0f, 1f, 0f, 0f, 0f, 1f, 1f, 0f, 0f),
- new Basis(0f, 0f, -1f, 0f, 1f, 0f, 1f, 0f, 0f),
- new Basis(0f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f)
- };
-
// NOTE: x, y and z are public-only. Use Column0, Column1 and Column2 internally.
/// <summary>
@@ -63,7 +30,6 @@ namespace Godot
/// </summary>
public Vector3 y
{
-
get => Column1;
set => Column1 = value;
}
@@ -74,7 +40,6 @@ namespace Godot
/// </summary>
public Vector3 z
{
-
get => Column2;
set => Column2 = value;
}
@@ -114,8 +79,6 @@ namespace Godot
}
}
- public static Basis Identity => identity;
-
public Vector3 Scale
{
get
@@ -225,7 +188,7 @@ namespace Godot
return orthonormalizedBasis.Quat();
}
- internal void SetQuantScale(Quat quat, Vector3 scale)
+ internal void SetQuatScale(Quat quat, Vector3 scale)
{
SetDiagonal(scale);
Rotate(quat);
@@ -241,7 +204,6 @@ namespace Godot
Row0 = new Vector3(diagonal.x, 0, 0);
Row1 = new Vector3(0, diagonal.y, 0);
Row2 = new Vector3(0, 0, diagonal.z);
-
}
public real_t Determinant()
@@ -361,7 +323,7 @@ namespace Godot
for (int i = 0; i < 24; i++)
{
- if (orthoBases[i] == orth)
+ if (orth == _orthoBases[i])
return i;
}
@@ -531,6 +493,43 @@ namespace Godot
}
}
+ private static readonly Basis[] _orthoBases = {
+ new Basis(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f),
+ new Basis(0f, -1f, 0f, 1f, 0f, 0f, 0f, 0f, 1f),
+ new Basis(-1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f),
+ new Basis(0f, 1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f),
+ new Basis(1f, 0f, 0f, 0f, 0f, -1f, 0f, 1f, 0f),
+ new Basis(0f, 0f, 1f, 1f, 0f, 0f, 0f, 1f, 0f),
+ new Basis(-1f, 0f, 0f, 0f, 0f, 1f, 0f, 1f, 0f),
+ new Basis(0f, 0f, -1f, -1f, 0f, 0f, 0f, 1f, 0f),
+ new Basis(1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, -1f),
+ new Basis(0f, 1f, 0f, 1f, 0f, 0f, 0f, 0f, -1f),
+ new Basis(-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, -1f),
+ new Basis(0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, -1f),
+ new Basis(1f, 0f, 0f, 0f, 0f, 1f, 0f, -1f, 0f),
+ new Basis(0f, 0f, -1f, 1f, 0f, 0f, 0f, -1f, 0f),
+ new Basis(-1f, 0f, 0f, 0f, 0f, -1f, 0f, -1f, 0f),
+ new Basis(0f, 0f, 1f, -1f, 0f, 0f, 0f, -1f, 0f),
+ new Basis(0f, 0f, 1f, 0f, 1f, 0f, -1f, 0f, 0f),
+ new Basis(0f, -1f, 0f, 0f, 0f, 1f, -1f, 0f, 0f),
+ new Basis(0f, 0f, -1f, 0f, -1f, 0f, -1f, 0f, 0f),
+ new Basis(0f, 1f, 0f, 0f, 0f, -1f, -1f, 0f, 0f),
+ new Basis(0f, 0f, 1f, 0f, -1f, 0f, 1f, 0f, 0f),
+ new Basis(0f, 1f, 0f, 0f, 0f, 1f, 1f, 0f, 0f),
+ new Basis(0f, 0f, -1f, 0f, 1f, 0f, 1f, 0f, 0f),
+ new Basis(0f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f)
+ };
+
+ private static readonly Basis _identity = new Basis(1, 0, 0, 0, 1, 0, 0, 0, 1);
+ private static readonly Basis _flipX = new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1);
+ private static readonly Basis _flipY = new Basis(1, 0, 0, 0, -1, 0, 0, 0, 1);
+ private static readonly Basis _flipZ = new Basis(1, 0, 0, 0, 1, 0, 0, 0, -1);
+
+ public static Basis Identity { get { return _identity; } }
+ public static Basis FlipX { get { return _flipX; } }
+ public static Basis FlipY { get { return _flipY; } }
+ public static Basis FlipZ { get { return _flipZ; } }
+
public Basis(Quat quat)
{
real_t s = 2.0f / quat.LengthSquared;
diff --git a/modules/mono/glue/Managed/Files/Color.cs b/modules/mono/glue/Managed/Files/Color.cs
index 84ff19fc54..3a52a1a13b 100644
--- a/modules/mono/glue/Managed/Files/Color.cs
+++ b/modules/mono/glue/Managed/Files/Color.cs
@@ -1,7 +1,10 @@
using System;
+using System.Runtime.InteropServices;
namespace Godot
{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
public struct Color : IEquatable<Color>
{
public float r;
@@ -13,7 +16,11 @@ namespace Godot
{
get
{
- return (int)(r * 255.0f);
+ return (int)Math.Round(r * 255.0f);
+ }
+ set
+ {
+ r = value / 255.0f;
}
}
@@ -21,7 +28,11 @@ namespace Godot
{
get
{
- return (int)(g * 255.0f);
+ return (int)Math.Round(g * 255.0f);
+ }
+ set
+ {
+ g = value / 255.0f;
}
}
@@ -29,7 +40,11 @@ namespace Godot
{
get
{
- return (int)(b * 255.0f);
+ return (int)Math.Round(b * 255.0f);
+ }
+ set
+ {
+ b = value / 255.0f;
}
}
@@ -37,7 +52,11 @@ namespace Godot
{
get
{
- return (int)(a * 255.0f);
+ return (int)Math.Round(a * 255.0f);
+ }
+ set
+ {
+ a = value / 255.0f;
}
}
@@ -71,7 +90,7 @@ namespace Godot
}
set
{
- this = FromHsv(value, s, v);
+ this = FromHsv(value, s, v, a);
}
}
@@ -88,7 +107,7 @@ namespace Godot
}
set
{
- this = FromHsv(h, value, v);
+ this = FromHsv(h, value, v, a);
}
}
@@ -100,7 +119,7 @@ namespace Godot
}
set
{
- this = FromHsv(h, s, value);
+ this = FromHsv(h, s, value, a);
}
}
@@ -163,12 +182,12 @@ namespace Godot
}
}
- public static void ToHsv(Color color, out float hue, out float saturation, out float value)
+ public void ToHsv(out float hue, out float saturation, out float value)
{
- int max = Mathf.Max(color.r8, Mathf.Max(color.g8, color.b8));
- int min = Mathf.Min(color.r8, Mathf.Min(color.g8, color.b8));
+ float max = (float)Mathf.Max(r, Mathf.Max(g, b));
+ float min = (float)Mathf.Min(r, Mathf.Min(g, b));
- int delta = max - min;
+ float delta = max - min;
if (delta == 0)
{
@@ -176,12 +195,12 @@ namespace Godot
}
else
{
- if (color.r == max)
- hue = (color.g - color.b) / delta; // Between yellow & magenta
- else if (color.g == max)
- hue = 2 + (color.b - color.r) / delta; // Between cyan & yellow
+ if (r == max)
+ hue = (g - b) / delta; // Between yellow & magenta
+ else if (g == max)
+ hue = 2 + (b - r) / delta; // Between cyan & yellow
else
- hue = 4 + (color.r - color.g) / delta; // Between magenta & cyan
+ hue = 4 + (r - g) / delta; // Between magenta & cyan
hue /= 6.0f;
@@ -190,7 +209,7 @@ namespace Godot
}
saturation = max == 0 ? 0 : 1f - 1f * min / max;
- value = max / 255f;
+ value = max;
}
public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f)
@@ -254,7 +273,8 @@ namespace Godot
return new Color(
(r + 0.5f) % 1.0f,
(g + 0.5f) % 1.0f,
- (b + 0.5f) % 1.0f
+ (b + 0.5f) % 1.0f,
+ a
);
}
@@ -272,7 +292,8 @@ namespace Godot
return new Color(
1.0f - r,
1.0f - g,
- 1.0f - b
+ 1.0f - b,
+ a
);
}
@@ -375,7 +396,7 @@ namespace Godot
return c;
}
- public string ToHtml(bool include_alpha = true)
+ public string ToHtml(bool includeAlpha = true)
{
var txt = string.Empty;
@@ -383,7 +404,7 @@ namespace Godot
txt += ToHex32(g);
txt += ToHex32(b);
- if (include_alpha)
+ if (includeAlpha)
txt = ToHex32(a) + txt;
return txt;
@@ -465,13 +486,13 @@ namespace Godot
for (int i = 0; i < 2; i++)
{
- char[] c = { (char)0, (char)0 };
+ char c;
int lv = v & 0xF;
if (lv < 10)
- c[0] = (char)('0' + lv);
+ c = (char)('0' + lv);
else
- c[0] = (char)('a' + lv - 10);
+ c = (char)('a' + lv - 10);
v >>= 4;
ret = c + ret;
@@ -490,12 +511,17 @@ namespace Godot
bool alpha;
- if (color.Length == 8)
- alpha = true;
- else if (color.Length == 6)
- alpha = false;
- else
- return false;
+ switch (color.Length)
+ {
+ case 8:
+ alpha = true;
+ break;
+ case 6:
+ alpha = false;
+ break;
+ default:
+ return false;
+ }
if (alpha)
{
diff --git a/modules/mono/glue/Managed/Files/Colors.cs b/modules/mono/glue/Managed/Files/Colors.cs
index bc2a1a3bd7..f41f5e9fc8 100644
--- a/modules/mono/glue/Managed/Files/Colors.cs
+++ b/modules/mono/glue/Managed/Files/Colors.cs
@@ -141,6 +141,7 @@ namespace Godot
{"teal", new Color(0.00f, 0.50f, 0.50f)},
{"thistle", new Color(0.85f, 0.75f, 0.85f)},
{"tomato", new Color(1.00f, 0.39f, 0.28f)},
+ {"transparent", new Color(1.00f, 1.00f, 1.00f, 0.00f)},
{"turquoise", new Color(0.25f, 0.88f, 0.82f)},
{"violet", new Color(0.93f, 0.51f, 0.93f)},
{"webgreen", new Color(0.00f, 0.50f, 0.00f)},
@@ -187,7 +188,7 @@ namespace Godot
public static Color DarkOrchid { get { return namedColors["darkorchid"]; } }
public static Color DarkRed { get { return namedColors["darkred"]; } }
public static Color DarkSalmon { get { return namedColors["darksalmon"]; } }
- public static Color DarkSeagreen { get { return namedColors["darkseagreen"]; } }
+ public static Color DarkSeaGreen { get { return namedColors["darkseagreen"]; } }
public static Color DarkSlateBlue { get { return namedColors["darkslateblue"]; } }
public static Color DarkSlateGray { get { return namedColors["darkslategray"]; } }
public static Color DarkTurquoise { get { return namedColors["darkturquoise"]; } }
@@ -288,6 +289,7 @@ namespace Godot
public static Color Teal { get { return namedColors["teal"]; } }
public static Color Thistle { get { return namedColors["thistle"]; } }
public static Color Tomato { get { return namedColors["tomato"]; } }
+ public static Color Transparent { get { return namedColors["transparent"]; } }
public static Color Turquoise { get { return namedColors["turquoise"]; } }
public static Color Violet { get { return namedColors["violet"]; } }
public static Color WebGreen { get { return namedColors["webgreen"]; } }
diff --git a/modules/mono/glue/Managed/Files/Dispatcher.cs b/modules/mono/glue/Managed/Files/Dispatcher.cs
new file mode 100644
index 0000000000..072e0f20ff
--- /dev/null
+++ b/modules/mono/glue/Managed/Files/Dispatcher.cs
@@ -0,0 +1,13 @@
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public static class Dispatcher
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern GodotTaskScheduler godot_icall_DefaultGodotTaskScheduler();
+
+ public static GodotSynchronizationContext SynchronizationContext =>
+ godot_icall_DefaultGodotTaskScheduler().Context;
+ }
+}
diff --git a/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs b/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
index e727781d63..4b5e3f8761 100644
--- a/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
+++ b/modules/mono/glue/Managed/Files/GodotSynchronizationContext.cs
@@ -6,17 +6,16 @@ namespace Godot
{
public class GodotSynchronizationContext : SynchronizationContext
{
- private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
+ private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
public override void Post(SendOrPostCallback d, object state)
{
- queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
+ _queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
}
public void ExecutePendingContinuations()
{
- KeyValuePair<SendOrPostCallback, object> workItem;
- while (queue.TryTake(out workItem))
+ while (_queue.TryTake(out var workItem))
{
workItem.Key(workItem.Value);
}
diff --git a/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs b/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
index 9a40fef5a9..8eaeea50dc 100644
--- a/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
+++ b/modules/mono/glue/Managed/Files/GodotTaskScheduler.cs
@@ -8,7 +8,7 @@ namespace Godot
{
public class GodotTaskScheduler : TaskScheduler
{
- private GodotSynchronizationContext Context { get; set; }
+ internal GodotSynchronizationContext Context { get; }
private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
public GodotTaskScheduler()
@@ -28,14 +28,10 @@ namespace Godot
protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
if (SynchronizationContext.Current != Context)
- {
return false;
- }
if (taskWasPreviouslyQueued)
- {
TryDequeue(task);
- }
return TryExecuteTask(task);
}
@@ -52,7 +48,8 @@ namespace Godot
{
lock (_tasks)
{
- return _tasks.ToArray();
+ foreach (Task task in _tasks)
+ yield return task;
}
}
diff --git a/modules/mono/glue/Managed/Files/Mathf.cs b/modules/mono/glue/Managed/Files/Mathf.cs
index 2d8c63fe7f..ce34cd6a99 100644
--- a/modules/mono/glue/Managed/Files/Mathf.cs
+++ b/modules/mono/glue/Managed/Files/Mathf.cs
@@ -158,6 +158,11 @@ namespace Godot
public static bool IsEqualApprox(real_t a, real_t b)
{
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b) {
+ return true;
+ }
+ // Then check for approximate equality.
real_t tolerance = Epsilon * Abs(a);
if (tolerance < Epsilon) {
tolerance = Epsilon;
@@ -185,6 +190,12 @@ namespace Godot
return from + (to - from) * weight;
}
+ public static real_t LerpAngle(real_t from, real_t to, real_t weight) {
+ real_t difference = (to - from) % Mathf.Tau;
+ real_t distance = ((2 * difference) % Mathf.Tau) - difference;
+ return from + distance * weight;
+ }
+
public static real_t Log(real_t s)
{
return (real_t)Math.Log(s);
@@ -330,14 +341,14 @@ namespace Godot
public static int Wrap(int value, int min, int max)
{
- int rng = max - min;
- return rng != 0 ? min + ((value - min) % rng + rng) % rng : min;
+ int range = max - min;
+ return range == 0 ? min : min + ((value - min) % range + range) % range;
}
public static real_t Wrap(real_t value, real_t min, real_t max)
{
- real_t rng = max - min;
- return !IsEqualApprox(rng, default(real_t)) ? min + ((value - min) % rng + rng) % rng : min;
+ real_t range = max - min;
+ return IsZeroApprox(range) ? min : min + ((value - min) % range + range) % range;
}
}
}
diff --git a/modules/mono/glue/Managed/Files/MathfEx.cs b/modules/mono/glue/Managed/Files/MathfEx.cs
index b96f01bc2e..6cffc7f01d 100644
--- a/modules/mono/glue/Managed/Files/MathfEx.cs
+++ b/modules/mono/glue/Managed/Files/MathfEx.cs
@@ -48,7 +48,12 @@ namespace Godot
public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance)
{
+ // Check for exact equality first, required to handle "infinity" values.
+ if (a == b) {
+ return true;
+ }
+ // Then check for approximate equality.
return Abs(a - b) < tolerance;
}
}
-} \ No newline at end of file
+}
diff --git a/modules/mono/glue/Managed/Files/NodePath.cs b/modules/mono/glue/Managed/Files/NodePath.cs
index 94a4ed1de9..4de4e1e6a9 100644
--- a/modules/mono/glue/Managed/Files/NodePath.cs
+++ b/modules/mono/glue/Managed/Files/NodePath.cs
@@ -55,7 +55,7 @@ namespace Godot
get { return ptr; }
}
- public NodePath() : this(string.Empty) { }
+ public NodePath() : this(string.Empty) {}
public NodePath(string path)
{
diff --git a/modules/mono/glue/Managed/Files/Plane.cs b/modules/mono/glue/Managed/Files/Plane.cs
index e16d4315be..a13161d2e6 100644
--- a/modules/mono/glue/Managed/Files/Plane.cs
+++ b/modules/mono/glue/Managed/Files/Plane.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.InteropServices;
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
@@ -7,6 +8,8 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
public struct Plane : IEquatable<Plane>
{
private Vector3 _normal;
diff --git a/modules/mono/glue/Managed/Files/Quat.cs b/modules/mono/glue/Managed/Files/Quat.cs
index 0d4349084a..845c7c730e 100644
--- a/modules/mono/glue/Managed/Files/Quat.cs
+++ b/modules/mono/glue/Managed/Files/Quat.cs
@@ -8,6 +8,7 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Quat : IEquatable<Quat>
{
@@ -95,6 +96,7 @@ namespace Godot
return this / Length;
}
+ [Obsolete("Set is deprecated. Use the Quat(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y, real_t z, real_t w)
{
this.x = x;
@@ -103,16 +105,19 @@ namespace Godot
this.w = w;
}
+ [Obsolete("Set is deprecated. Use the Quat(" + nameof(Quat) + ") constructor instead.", error: true)]
public void Set(Quat q)
{
this = q;
}
+ [Obsolete("SetAxisAngle is deprecated. Use the Quat(" + nameof(Vector3) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void SetAxisAngle(Vector3 axis, real_t angle)
{
this = new Quat(axis, angle);
}
+ [Obsolete("SetEuler is deprecated. Use the Quat(" + nameof(Vector3) + ") constructor instead.", error: true)]
public void SetEuler(Vector3 eulerYXZ)
{
this = new Quat(eulerYXZ);
@@ -229,9 +234,9 @@ namespace Godot
public Quat(Vector3 eulerYXZ)
{
- real_t half_a1 = eulerYXZ.y * (real_t)0.5;
- real_t half_a2 = eulerYXZ.x * (real_t)0.5;
- real_t half_a3 = eulerYXZ.z * (real_t)0.5;
+ real_t half_a1 = eulerYXZ.y * 0.5f;
+ real_t half_a2 = eulerYXZ.x * 0.5f;
+ real_t half_a3 = eulerYXZ.z * 0.5f;
// R = Y(a1).X(a2).Z(a3) convention for Euler angles.
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
@@ -246,7 +251,7 @@ namespace Godot
x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
- z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
+ z = cos_a1 * cos_a2 * sin_a3 - sin_a1 * sin_a2 * cos_a3;
w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
}
diff --git a/modules/mono/glue/Managed/Files/Rect2.cs b/modules/mono/glue/Managed/Files/Rect2.cs
index 888f300347..99542d0c0a 100644
--- a/modules/mono/glue/Managed/Files/Rect2.cs
+++ b/modules/mono/glue/Managed/Files/Rect2.cs
@@ -8,6 +8,7 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Rect2 : IEquatable<Rect2>
{
@@ -156,13 +157,13 @@ namespace Godot
public bool Intersects(Rect2 b)
{
- if (_position.x > b._position.x + b._size.x)
+ if (_position.x >= b._position.x + b._size.x)
return false;
- if (_position.x + _size.x < b._position.x)
+ if (_position.x + _size.x <= b._position.x)
return false;
- if (_position.y > b._position.y + b._size.y)
+ if (_position.y >= b._position.y + b._size.y)
return false;
- if (_position.y + _size.y < b._position.y)
+ if (_position.y + _size.y <= b._position.y)
return false;
return true;
diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs
index b43034fbb5..6045c83e95 100644
--- a/modules/mono/glue/Managed/Files/StringExtensions.cs
+++ b/modules/mono/glue/Managed/Files/StringExtensions.cs
@@ -98,6 +98,66 @@ namespace Godot
}
// <summary>
+ // Return the amount of substrings in string.
+ // </summary>
+ public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0)
+ {
+ if (what.Length == 0)
+ {
+ return 0;
+ }
+
+ int len = instance.Length;
+ int slen = what.Length;
+
+ if (len < slen)
+ {
+ return 0;
+ }
+
+ string str;
+
+ if (from >= 0 && to >= 0)
+ {
+ if (to == 0)
+ {
+ to = len;
+ }
+ else if (from >= to)
+ {
+ return 0;
+ }
+ if (from == 0 && to == len)
+ {
+ str = instance;
+ }
+ else
+ {
+ str = instance.Substring(from, to - from);
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ int c = 0;
+ int idx;
+
+ do
+ {
+ idx = str.IndexOf(what, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ if (idx != -1)
+ {
+ str = str.Substring(idx + slen);
+ ++c;
+ }
+ } while (idx != -1);
+
+ return c;
+ }
+
+ // <summary>
// Return a copy of the string with special characters escaped using the C language standard.
// </summary>
public static string CEscape(this string instance)
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
index bd79144873..cc4d26158d 100644
--- a/modules/mono/glue/Managed/Files/Transform.cs
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -8,6 +8,7 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Transform : IEquatable<Transform>
{
@@ -33,7 +34,7 @@ namespace Godot
Vector3 destinationLocation = transform.origin;
var interpolated = new Transform();
- interpolated.basis.SetQuantScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
+ interpolated.basis.SetQuatScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
interpolated.origin = sourceLocation.LinearInterpolate(destinationLocation, c);
return interpolated;
diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs
index 33ff286769..814332dc07 100644
--- a/modules/mono/glue/Managed/Files/Transform2D.cs
+++ b/modules/mono/glue/Managed/Files/Transform2D.cs
@@ -8,6 +8,7 @@ using real_t = System.Single;
namespace Godot
{
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Transform2D : IEquatable<Transform2D>
{
@@ -98,6 +99,8 @@ namespace Godot
return x[columnIndex];
case 1:
return y[columnIndex];
+ case 2:
+ return origin[columnIndex];
default:
throw new IndexOutOfRangeException();
}
@@ -112,6 +115,9 @@ namespace Godot
case 1:
y[columnIndex] = value;
return;
+ case 2:
+ origin[columnIndex] = value;
+ return;
default:
throw new IndexOutOfRangeException();
}
@@ -136,7 +142,7 @@ namespace Godot
inv[0] *= new Vector2(detInv, -detInv);
inv[1] *= new Vector2(-detInv, detInv);
- inv[2] = BasisXform(-inv[2]);
+ inv[2] = inv.BasisXform(-inv[2]);
return inv;
}
diff --git a/modules/mono/glue/Managed/Files/Vector2.cs b/modules/mono/glue/Managed/Files/Vector2.cs
index a7f26283a7..0daa94057e 100644
--- a/modules/mono/glue/Managed/Files/Vector2.cs
+++ b/modules/mono/glue/Managed/Files/Vector2.cs
@@ -14,9 +14,19 @@ using real_t = System.Single;
namespace Godot
{
+ /// <summary>
+ /// 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
+ /// </summary>
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector2 : IEquatable<Vector2>
{
+ public enum Axis
+ {
+ X = 0,
+ Y
+ }
+
public real_t x;
public real_t y;
@@ -201,6 +211,22 @@ namespace Godot
return v;
}
+ public Vector2 PosMod(real_t mod)
+ {
+ Vector2 v;
+ v.x = Mathf.PosMod(x, mod);
+ v.y = Mathf.PosMod(y, mod);
+ return v;
+ }
+
+ public Vector2 PosMod(Vector2 modv)
+ {
+ Vector2 v;
+ v.x = Mathf.PosMod(x, modv.x);
+ v.y = Mathf.PosMod(y, modv.y);
+ return v;
+ }
+
public Vector2 Project(Vector2 onNormal)
{
return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@@ -222,17 +248,27 @@ namespace Godot
return new Vector2(Mathf.Round(x), Mathf.Round(y));
}
+ [Obsolete("Set is deprecated. Use the Vector2(" + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y)
{
this.x = x;
this.y = y;
}
+ [Obsolete("Set is deprecated. Use the Vector2(" + nameof(Vector2) + ") constructor instead.", error: true)]
public void Set(Vector2 v)
{
x = v.x;
y = v.y;
}
+ public Vector2 Sign()
+ {
+ Vector2 v;
+ v.x = Mathf.Sign(x);
+ v.y = Mathf.Sign(y);
+ return v;
+ }
+
public Vector2 Slerp(Vector2 b, real_t t)
{
real_t theta = AngleTo(b);
@@ -262,7 +298,7 @@ namespace Godot
private static readonly Vector2 _up = new Vector2(0, -1);
private static readonly Vector2 _down = new Vector2(0, 1);
- private static readonly Vector2 _right = new Vector2(1, 0);
+ private static readonly Vector2 _right = new Vector2(1, 0);
private static readonly Vector2 _left = new Vector2(-1, 0);
public static Vector2 Zero { get { return _zero; } }
@@ -343,6 +379,20 @@ namespace Godot
return left;
}
+ public static Vector2 operator %(Vector2 vec, real_t divisor)
+ {
+ vec.x %= divisor;
+ vec.y %= divisor;
+ return vec;
+ }
+
+ public static Vector2 operator %(Vector2 vec, Vector2 divisorv)
+ {
+ vec.x %= divisorv.x;
+ vec.y %= divisorv.y;
+ return vec;
+ }
+
public static bool operator ==(Vector2 left, Vector2 right)
{
return left.Equals(right);
diff --git a/modules/mono/glue/Managed/Files/Vector3.cs b/modules/mono/glue/Managed/Files/Vector3.cs
index 16803ae55c..9076dbd3b0 100644
--- a/modules/mono/glue/Managed/Files/Vector3.cs
+++ b/modules/mono/glue/Managed/Files/Vector3.cs
@@ -14,6 +14,10 @@ using real_t = System.Single;
namespace Godot
{
+ /// <summary>
+ /// 3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
+ /// </summary>
+ [Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Vector3 : IEquatable<Vector3>
{
@@ -224,6 +228,24 @@ namespace Godot
);
}
+ public Vector3 PosMod(real_t mod)
+ {
+ Vector3 v;
+ v.x = Mathf.PosMod(x, mod);
+ v.y = Mathf.PosMod(y, mod);
+ v.z = Mathf.PosMod(z, mod);
+ return v;
+ }
+
+ public Vector3 PosMod(Vector3 modv)
+ {
+ Vector3 v;
+ v.x = Mathf.PosMod(x, modv.x);
+ v.y = Mathf.PosMod(y, modv.y);
+ v.z = Mathf.PosMod(z, modv.z);
+ return v;
+ }
+
public Vector3 Project(Vector3 onNormal)
{
return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@@ -248,12 +270,14 @@ namespace Godot
return new Basis(axis, phi).Xform(this);
}
+ [Obsolete("Set is deprecated. Use the Vector3(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y, real_t z)
{
this.x = x;
this.y = y;
this.z = z;
}
+ [Obsolete("Set is deprecated. Use the Vector3(" + nameof(Vector3) + ") constructor instead.", error: true)]
public void Set(Vector3 v)
{
x = v.x;
@@ -261,6 +285,15 @@ namespace Godot
z = v.z;
}
+ public Vector3 Sign()
+ {
+ Vector3 v;
+ v.x = Mathf.Sign(x);
+ v.y = Mathf.Sign(y);
+ v.z = Mathf.Sign(z);
+ return v;
+ }
+
public Vector3 Slerp(Vector3 b, real_t t)
{
real_t theta = AngleTo(b);
@@ -394,6 +427,22 @@ namespace Godot
return left;
}
+ public static Vector3 operator %(Vector3 vec, real_t divisor)
+ {
+ vec.x %= divisor;
+ vec.y %= divisor;
+ vec.z %= divisor;
+ return vec;
+ }
+
+ public static Vector3 operator %(Vector3 vec, Vector3 divisorv)
+ {
+ vec.x %= divisorv.x;
+ vec.y %= divisorv.y;
+ vec.z %= divisorv.z;
+ return vec;
+ }
+
public static bool operator ==(Vector3 left, Vector3 right)
{
return left.Equals(right);
diff --git a/modules/mono/glue/Managed/Managed.csproj b/modules/mono/glue/Managed/Managed.csproj
index 61f738922b..c8eca71199 100644
--- a/modules/mono/glue/Managed/Managed.csproj
+++ b/modules/mono/glue/Managed/Managed.csproj
@@ -1,4 +1,4 @@
-<?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>
@@ -8,6 +8,7 @@
<RootNamespace>Managed</RootNamespace>
<AssemblyName>Managed</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <LangVersion>7</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
@@ -37,4 +38,4 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 7c30092855..8b9a1380d8 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -167,7 +167,7 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
int line;
Error err = VariantParser::parse(&ss, ret, errs, line);
if (err != OK) {
- String err_str = "Parse error at line " + itos(line) + ": " + errs;
+ String err_str = "Parse error at line " + itos(line) + ": " + errs + ".";
ERR_PRINTS(err_str);
ret = err_str;
}
@@ -193,8 +193,7 @@ MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_object
PoolByteArray barr;
int len;
Error err = encode_variant(var, NULL, len, p_full_objects);
- ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
- ERR_FAIL_COND_V(err != OK, NULL);
+ ERR_FAIL_COND_V_MSG(err != OK, NULL, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
barr.resize(len);
{
@@ -211,6 +210,10 @@ MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
return GDMonoMarshal::mono_string_from_godot(vars);
}
+MonoObject *godot_icall_DefaultGodotTaskScheduler() {
+ return GDMonoUtils::mono_cache.task_scheduler_handle->get_target();
+}
+
void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_bytes2var", (void *)godot_icall_GD_bytes2var);
mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
@@ -234,6 +237,9 @@ void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str);
+
+ // Dispatcher
+ mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h
index d4e20e2887..a34c0bc50f 100644
--- a/modules/mono/glue/gd_glue.h
+++ b/modules/mono/glue/gd_glue.h
@@ -75,6 +75,8 @@ MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_object
MonoString *godot_icall_GD_var2str(MonoObject *p_var);
+MonoObject *godot_icall_DefaultGodotTaskScheduler();
+
// Register internal calls
void godot_register_gd_icalls();
diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h
index 4ad4088514..4c17a6ec9d 100644
--- a/modules/mono/godotsharp_defs.h
+++ b/modules/mono/godotsharp_defs.h
@@ -39,8 +39,8 @@
#define API_SOLUTION_NAME "GodotSharp"
#define CORE_API_ASSEMBLY_NAME "GodotSharp"
#define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor"
-#define TOOLS_ASSEMBLY_NAME "GodotTools"
-#define TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME "GodotTools.ProjectEditor"
+#define TOOLS_ASM_NAME "GodotTools"
+#define TOOLS_PROJECT_EDITOR_ASM_NAME "GodotTools.ProjectEditor"
#define BINDINGS_CLASS_NATIVECALLS "NativeCalls"
#define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls"
diff --git a/modules/mono/icons/icon_c_#.svg b/modules/mono/icons/icon_c_#.svg
new file mode 100644
index 0000000000..69664ca553
--- /dev/null
+++ b/modules/mono/icons/icon_c_#.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path d="m6 1046.4c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-0.55228 0-1-0.4478-1-1 0-0.5523 0.44772-1 1-1h1v-2zm1-9-0.56445 2.2578c-0.23643 0.076-0.46689 0.1692-0.68945 0.2793l-1.9883-1.1933-1.4141 1.414 1.1953 1.9942c-0.11191 0.2211-0.20723 0.4502-0.28516 0.6855l-2.2539 0.5625v2h5.2715c-0.17677-0.3037-0.27041-0.6486-0.27148-1 9.6e-6 -1.1046 0.89543-2 2-2s2 0.8954 2 2c-4.817e-4 0.3512-0.093442 0.6961-0.26953 1h5.2695v-2l-2.2578-0.5645c-0.07594-0.2357-0.1693-0.4655-0.2793-0.6875l1.1934-1.9902-1.4141-1.414-1.9941 1.1953c-0.22113-0.1119-0.45028-0.2073-0.68555-0.2852l-0.5625-2.2539zm4 9c-0.71466-1e-4 -1.3751 0.3811-1.7324 1-0.35727 0.6188-0.35727 1.3812 0 2 0.35733 0.6189 1.0178 1.0001 1.7324 1h-2v2h2c0.71466 1e-4 1.3751-0.3811 1.7324-1 0.35727-0.6188 0.35727-1.3812 0-2-0.35733-0.6189-1.0178-1.0001-1.7324-1h2v-2z" fill="#e0e0e0"/>
+</g>
+</svg>
diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h
new file mode 100644
index 0000000000..c5cc244aec
--- /dev/null
+++ b/modules/mono/mono_gd/android_mono_config.h
@@ -0,0 +1,43 @@
+/*************************************************************************/
+/* android_mono_config.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 ANDROID_MONO_CONFIG_H
+#define ANDROID_MONO_CONFIG_H
+
+#ifdef ANDROID_ENABLED
+
+#include "core/ustring.h"
+
+// This function is defined in an auto-generated source file
+String get_godot_android_mono_config();
+
+#endif // ANDROID_ENABLED
+
+#endif // ANDROID_MONO_CONFIG_H
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 06fbae019c..915a01af7e 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -44,7 +44,6 @@
#include "core/project_settings.h"
#include "../csharp_script.h"
-#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_dirs.h"
#include "../utils/path_utils.h"
#include "gd_mono_class.h"
@@ -56,13 +55,9 @@
#endif
#ifdef ANDROID_ENABLED
-#include "android_mono_config.gen.h"
+#include "android_mono_config.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."
-
GDMono *GDMono::singleton = NULL;
namespace {
@@ -269,7 +264,7 @@ void GDMono::initialize() {
#ifdef WINDOWS_ENABLED
if (assembly_rootdir.empty() || config_dir.empty()) {
- ERR_PRINT("Cannot find Mono in the registry");
+ ERR_PRINT("Cannot find Mono in the registry.");
// Assertion: if they are not set, then they weren't found in the registry
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
}
@@ -287,6 +282,18 @@ void GDMono::initialize() {
add_mono_shared_libs_dir_to_path();
+ {
+ PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM,
+ vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR));
+ unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP);
+ ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop);
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ // Unhandled exceptions should not terminate the editor
+ unhandled_exception_policy = POLICY_LOG_ERROR;
+ }
+ }
+
GDMonoAssembly::initialize();
gdmono_profiler_init();
@@ -304,32 +311,20 @@ void GDMono::initialize() {
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;
- }
- }
+ // Export templates only load the Mono runtime if the project uses it
+ if (!DirAccess::exists("res://.mono"))
+ return;
+#endif
- if (!found)
- return; // mscorlib is missing, do not initialize mono
+#if !defined(WINDOWS_ENABLED) && !defined(NO_MONO_THREADS_SUSPEND_WORKAROUND)
+ // FIXME: Temporary workaround. See: https://github.com/godotengine/godot/issues/29812
+ if (!OS::get_singleton()->has_environment("MONO_THREADS_SUSPEND")) {
+ OS::get_singleton()->set_environment("MONO_THREADS_SUSPEND", "preemptive");
}
#endif
root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319");
-
- ERR_EXPLAIN("Mono: Failed to initialize runtime");
- ERR_FAIL_NULL(root_domain);
+ ERR_FAIL_NULL_MSG(root_domain, "Mono: Failed to initialize runtime.");
GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread());
@@ -340,11 +335,11 @@ void GDMono::initialize() {
print_verbose("Mono: Runtime initialized");
// mscorlib assembly MUST be present at initialization
- ERR_EXPLAIN("Mono: Failed to load mscorlib assembly");
- ERR_FAIL_COND(!_load_corlib_assembly());
+ bool corlib_loaded = _load_corlib_assembly();
+ ERR_FAIL_COND_MSG(!corlib_loaded, "Mono: Failed to load mscorlib assembly.");
- ERR_EXPLAIN("Mono: Failed to load scripts domain");
- ERR_FAIL_COND(_load_scripts_domain() != OK);
+ Error domain_load_err = _load_scripts_domain();
+ ERR_FAIL_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
#ifdef DEBUG_ENABLED
bool debugger_attached = _wait_for_debugger_msecs(500);
@@ -354,90 +349,93 @@ 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 tools and project assemblies
-
-#if defined(TOOLS_ENABLED)
- ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies");
- ERR_FAIL_COND(!_load_tools_assemblies());
-#endif
+ print_verbose("Mono: INITIALIZED");
+}
- _load_project_assembly();
+void GDMono::initialize_load_assemblies() {
- } 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)
+#ifndef MONO_GLUE_ENABLED
+ CRASH_NOW_MSG("Mono: This binary was built with 'mono_glue=no'; cannot load assemblies.");
#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)
+ bool tool_assemblies_loaded = _load_tools_assemblies();
+ CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
+#endif
+
+ // 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");
}
-#else
- print_verbose("Mono: Glue disabled, ignoring script assemblies.");
-#endif // MONO_GLUE_ENABLED
+}
- print_verbose("Mono: INITIALIZED");
+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
uint64_t get_editor_api_hash();
#endif
uint32_t get_bindings_version();
+uint32_t get_cs_glue_version();
void register_generated_icalls();
-} // namespace GodotSharpBindings
+
+#else
+
+uint64_t get_core_api_hash() {
+ GD_UNREACHABLE();
+}
+#ifdef TOOLS_ENABLED
+uint64_t get_editor_api_hash() {
+ GD_UNREACHABLE();
+}
#endif
+uint32_t get_bindings_version() {
+ GD_UNREACHABLE();
+}
+uint32_t get_cs_glue_version() {
+ GD_UNREACHABLE();
+}
+
+void register_generated_icalls() {
+ /* Fine, just do nothing */
+}
+
+#endif // MONO_GLUE_ENABLED
+} // namespace GodotSharpBindings
void GDMono::_register_internal_calls() {
-#ifdef MONO_GLUE_ENABLED
GodotSharpBindings::register_generated_icalls();
-#endif
}
void GDMono::_initialize_and_check_api_hashes() {
#ifdef MONO_GLUE_ENABLED
if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) {
- ERR_PRINT("Mono: Core API hash mismatch!");
+ ERR_PRINT("Mono: Core API hash mismatch.");
}
#ifdef TOOLS_ENABLED
if (get_api_editor_hash() != GodotSharpBindings::get_editor_api_hash()) {
- ERR_PRINT("Mono: Editor API hash mismatch!");
+ ERR_PRINT("Mono: Editor API hash mismatch.");
}
#endif // TOOLS_ENABLED
#endif // MONO_GLUE_ENABLED
@@ -565,49 +563,103 @@ bool GDMono::_load_corlib_assembly() {
}
#ifdef TOOLS_ENABLED
-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) {
+bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config) {
+
+ 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;
+
+ String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ String dst_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
+
+ 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(p_dst_dir)) {
- DirAccess *da = DirAccess::create_for_path(p_dst_dir);
- Error err = da->make_dir_recursive(p_dst_dir);
+ 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));
+ ERR_PRINTS("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);
+ 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) ||
- FileAccess::get_modified_time(assembly_src) > FileAccess::get_modified_time(assembly_dst) ||
- GDMono::get_singleton()->metadata_is_api_assembly_invalidated(p_api_type)) {
+ if (!FileAccess::exists(assembly_dst) || api_assembly_out_of_sync) {
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 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 = 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);
+ 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);
+ ERR_PRINTS("Failed to copy '" + assembly_file + "'.");
return false;
}
- GDMono::get_singleton()->metadata_set_api_assembly_invalidated(p_api_type, 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_exists) \
+ ( \
+ (m_out_of_sync ? \
+ String("The assembly is invalidated ") : \
+ String("The assembly was not found ")) + \
+ (m_prebuilt_exists ? \
+ String("and the prebuilt assemblies are missing.") : \
+ String("and we failed to copy the prebuilt assemblies.")))
+
+ 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
+
+ const int CONFIGS_LEN = 2;
+ String configs[CONFIGS_LEN] = { String("Debug"), String("Release") };
+
+ for (int i = 0; i < CONFIGS_LEN; i++) {
+ String config = configs[i];
+
+ print_verbose("Updating '" + config + "' API assemblies");
+
+ String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(config);
+ 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_exists: */ false);
+ }
+
+ // Copy the prebuilt Api
+ if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE, config) ||
+ !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR, config)) {
+ return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ true);
+ }
+ }
+
+ return String(); // Updated successfully
+
+#undef FAIL_REASON
+}
#endif
bool GDMono::_load_core_api_assembly() {
@@ -616,47 +668,33 @@ bool GDMono::_load_core_api_assembly() {
return true;
#ifdef TOOLS_ENABLED
- if (metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) {
- String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String prebuilt_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String invalidated_dll_path = get_invalidated_api_assembly_path(APIAssembly::API_CORE);
-
- if (!FileAccess::exists(prebuilt_dll_path) ||
- FileAccess::get_modified_time(invalidated_dll_path) == FileAccess::get_modified_time(prebuilt_dll_path)) {
- print_verbose("Mono: Skipping loading of Core API assembly because it was invalidated");
- return false;
- } else {
- // Copy the prebuilt Api
- String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();
- if (!copy_api_assembly(prebuilt_api_dir, res_assemblies_dir, CORE_API_ASSEMBLY_NAME, APIAssembly::API_CORE) ||
- !copy_api_assembly(prebuilt_api_dir, res_assemblies_dir, EDITOR_API_ASSEMBLY_NAME, APIAssembly::API_EDITOR)) {
- print_verbose("Mono: Failed to copy prebuilt API. Skipping loading of Core API assembly because it was invalidated");
- return false;
- }
- }
- }
-#endif
+ // 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
+
+ // If running the project manager, load it from the prebuilt API directory
+ String assembly_dir = !Main::is_project_manager() ?
+ GodotSharpDirs::get_res_assemblies_dir() :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll");
+ String assembly_path = assembly_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)) ||
- load_assembly(CORE_API_ASSEMBLY_NAME, &core_api_assembly);
+ 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 ||
- CS_GLUE_VERSION != api_assembly_ver.cs_glue_version;
+ GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version;
if (!core_api_assembly_out_of_sync) {
GDMonoUtils::update_godot_api_cache();
_install_trace_listener();
}
-#else
- GDMonoUtils::update_godot_api_cache();
-#endif
+ } else {
+ core_api_assembly_out_of_sync = false;
}
return success;
@@ -668,52 +706,115 @@ bool GDMono::_load_editor_api_assembly() {
if (editor_api_assembly)
return true;
- if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) {
- String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String prebuilt_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
- String invalidated_dll_path = get_invalidated_api_assembly_path(APIAssembly::API_EDITOR);
+ // 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
- if (!FileAccess::exists(prebuilt_dll_path) ||
- FileAccess::get_modified_time(invalidated_dll_path) == FileAccess::get_modified_time(prebuilt_dll_path)) {
- print_verbose("Mono: Skipping loading of Editor API assembly because it was invalidated");
- return false;
- } else {
- // Copy the prebuilt editor Api (no need to copy the core api if we got to this point)
- String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();
- if (!copy_api_assembly(prebuilt_api_dir, res_assemblies_dir, EDITOR_API_ASSEMBLY_NAME, APIAssembly::API_EDITOR)) {
- print_verbose("Mono: Failed to copy prebuilt API. Skipping loading of Editor API assembly because it was invalidated");
- return false;
- }
- }
- }
+ // If running the project manager, load it from the prebuilt API directory
+ String assembly_dir = !Main::is_project_manager() ?
+ GodotSharpDirs::get_res_assemblies_dir() :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
- String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
+ String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
- bool success = (FileAccess::exists(assembly_path) &&
- load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &editor_api_assembly)) ||
- load_assembly(EDITOR_API_ASSEMBLY_NAME, &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
+ GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version;
+ } else {
+ editor_api_assembly_out_of_sync = false;
}
return success;
}
#endif
+bool GDMono::_try_load_api_assemblies() {
+
+ if (!_load_core_api_assembly()) {
+ if (OS::get_singleton()->is_stdout_verbose())
+ print_error("Mono: Failed to load Core API assembly");
+ return false;
+ }
+
+#ifdef TOOLS_ENABLED
+ if (!_load_editor_api_assembly()) {
+ if (OS::get_singleton()->is_stdout_verbose())
+ print_error("Mono: Failed to load Editor API assembly");
+ return false;
+ }
+
+ if (editor_api_assembly_out_of_sync)
+ return false;
+#endif
+
+ // Check if the core API assembly is out of sync only after trying to load the
+ // editor API assembly. Otherwise, if both assemblies are out of sync, we would
+ // only update the former as we won't know the latter also needs to be updated.
+ if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)
+ return false;
+
+ return true;
+}
+
+void GDMono::_load_api_assemblies() {
+
+ if (!_try_load_api_assemblies()) {
+#ifdef TOOLS_ENABLED
+ // 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.
+
+ // Shouldn't happen. The project manager loads the prebuilt API assemblies
+ CRASH_COND_MSG(Main::is_project_manager(), "Failed to load one of the prebuilt API assemblies.");
+
+ // 1. Unload the scripts domain
+ Error domain_unload_err = _unload_scripts_domain();
+ CRASH_COND_MSG(domain_unload_err != OK, "Mono: Failed to unload scripts domain.");
+
+ // 2. Update the API assemblies
+ String update_error = update_api_assemblies_from_prebuilt();
+ CRASH_COND_MSG(!update_error.empty(), update_error);
+
+ // 3. Load the scripts domain again
+ Error domain_load_err = _load_scripts_domain();
+ CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
+
+ // 4. Try loading the updated assemblies
+ if (!_try_load_api_assemblies()) {
+ // welp... too bad
+
+ 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.");
+ }
+
+ if (editor_api_assembly_out_of_sync) {
+ ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync.");
+ }
+
+ CRASH_NOW();
+ } else {
+ CRASH_NOW_MSG("Failed to load one of the API assemblies.");
+ }
+ }
+#else
+ CRASH_NOW_MSG("Failed to load one of the API assemblies.");
+#endif
+ }
+}
+
#ifdef TOOLS_ENABLED
bool GDMono::_load_tools_assemblies() {
if (tools_assembly && tools_project_editor_assembly)
return true;
- bool success = load_assembly(TOOLS_ASSEMBLY_NAME, &tools_assembly) &&
- load_assembly(TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME, &tools_project_editor_assembly);
+ bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
+ load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
return success;
}
@@ -734,39 +835,11 @@ bool GDMono::_load_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");
}
return success;
}
-bool GDMono::_load_api_assemblies() {
-
- if (!_load_core_api_assembly()) {
- if (OS::get_singleton()->is_stdout_verbose())
- print_error("Mono: Failed to load Core API assembly");
- return false;
- }
-
- if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)
- return false;
-
-#ifdef TOOLS_ENABLED
- if (!_load_editor_api_assembly()) {
- if (OS::get_singleton()->is_stdout_verbose())
- print_error("Mono: Failed to load Editor API assembly");
- return false;
- }
-
- if (editor_api_assembly_out_of_sync)
- return false;
-#endif
-
- return true;
-}
-
void GDMono::_install_trace_listener() {
#ifdef DEBUG_ENABLED
@@ -778,84 +851,12 @@ void GDMono::_install_trace_listener() {
(DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener");
install_func((MonoObject **)&exc);
if (exc) {
- ERR_PRINT("Failed to install System.Diagnostics.Trace listener");
+ ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener.");
GDMonoUtils::debug_print_unhandled_exception(exc);
}
#endif
}
-#ifdef TOOLS_ENABLED
-String GDMono::_get_api_assembly_metadata_path() {
-
- return GodotSharpDirs::get_res_metadata_dir().plus_file("api_assemblies.cfg");
-}
-
-void GDMono::metadata_set_api_assembly_invalidated(APIAssembly::Type p_api_type, bool p_invalidated) {
-
- String section = APIAssembly::to_string(p_api_type);
- String path = _get_api_assembly_metadata_path();
-
- Ref<ConfigFile> metadata;
- metadata.instance();
- metadata->load(path);
-
- metadata->set_value(section, "invalidated", p_invalidated);
-
- 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");
-
- ERR_FAIL_COND(!FileAccess::exists(assembly_path));
-
- uint64_t modified_time = FileAccess::get_modified_time(assembly_path);
-
- metadata->set_value(section, "invalidated_asm_modified_time", String::num_uint64(modified_time));
-
- 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);
- }
-
- Error save_err = metadata->save(path);
- ERR_FAIL_COND(save_err != OK);
-}
-
-bool GDMono::metadata_is_api_assembly_invalidated(APIAssembly::Type p_api_type) {
-
- String section = APIAssembly::to_string(p_api_type);
-
- Ref<ConfigFile> metadata;
- metadata.instance();
- metadata->load(_get_api_assembly_metadata_path());
-
- 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");
-
- if (!FileAccess::exists(assembly_path))
- return false;
-
- uint64_t modified_time = FileAccess::get_modified_time(assembly_path);
-
- uint64_t stored_modified_time = metadata->get_value(section, "invalidated_asm_modified_time", 0);
-
- return metadata->get_value(section, "invalidated", false) && modified_time <= stored_modified_time;
-}
-
-String GDMono::get_invalidated_api_assembly_path(APIAssembly::Type p_api_type) {
-
- return GodotSharpDirs::get_res_assemblies_dir()
- .plus_file(p_api_type == APIAssembly::API_CORE ?
- CORE_API_ASSEMBLY_NAME ".dll" :
- EDITOR_API_ASSEMBLY_NAME ".dll");
-}
-#endif
-
Error GDMono::_load_scripts_domain() {
ERR_FAIL_COND_V(scripts_domain != NULL, ERR_BUG);
@@ -864,8 +865,7 @@ Error GDMono::_load_scripts_domain() {
scripts_domain = GDMonoUtils::create_domain("GodotEngine.ScriptsDomain");
- ERR_EXPLAIN("Mono: Could not create scripts app domain");
- ERR_FAIL_NULL_V(scripts_domain, ERR_CANT_CREATE);
+ ERR_FAIL_NULL_V_MSG(scripts_domain, ERR_CANT_CREATE, "Mono: Could not create scripts app domain.");
mono_domain_set(scripts_domain, true);
@@ -884,7 +884,7 @@ Error GDMono::_unload_scripts_domain() {
finalizing_scripts_domain = true;
if (!mono_domain_finalize(scripts_domain, 2000)) {
- ERR_PRINT("Mono: Domain finalization timeout");
+ ERR_PRINT("Mono: Domain finalization timeout.");
}
finalizing_scripts_domain = false;
@@ -903,11 +903,6 @@ Error GDMono::_unload_scripts_domain() {
tools_project_editor_assembly = NULL;
#endif
- core_api_assembly_out_of_sync = false;
-#ifdef TOOLS_ENABLED
- editor_api_assembly_out_of_sync = false;
-#endif
-
MonoDomain *domain = scripts_domain;
scripts_domain = NULL;
@@ -915,7 +910,7 @@ Error GDMono::_unload_scripts_domain() {
mono_domain_try_unload(domain, (MonoObject **)&exc);
if (exc) {
- ERR_PRINT("Exception thrown when unloading scripts domain");
+ ERR_PRINT("Exception thrown when unloading scripts domain.");
GDMonoUtils::debug_unhandled_exception(exc);
return FAILED;
}
@@ -929,72 +924,32 @@ Error GDMono::reload_scripts_domain() {
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
if (scripts_domain) {
- Error err = _unload_scripts_domain();
- if (err != OK) {
- ERR_PRINT("Mono: Failed to unload scripts domain");
- return err;
- }
+ Error domain_unload_err = _unload_scripts_domain();
+ ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain.");
}
CSharpLanguage::get_singleton()->_on_scripts_domain_unloaded();
- Error err = _load_scripts_domain();
- if (err != OK) {
- ERR_PRINT("Mono: Failed to load 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);
- }
-
- 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);
- }
+ Error domain_load_err = _load_scripts_domain();
+ ERR_FAIL_COND_V_MSG(domain_load_err != OK, domain_load_err, "Mono: Failed to load scripts domain.");
- err = _unload_scripts_domain();
- if (err != OK) {
- WARN_PRINT("Mono: Failed to unload scripts domain");
- }
+ // Load assemblies. The API and tools assemblies are required,
+ // the application is aborted if these assemblies cannot be loaded.
- return ERR_CANT_RESOLVE;
-#else
- ERR_PRINT("The loaded API assembly is invalid");
- CRASH_NOW();
-#endif
- } else {
- return ERR_CANT_OPEN;
- }
- }
+ _load_api_assemblies();
-#ifdef TOOLS_ENABLED
- ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies");
- ERR_FAIL_COND_V(!_load_tools_assemblies(), ERR_CANT_OPEN);
+#if defined(TOOLS_ENABLED)
+ bool tools_assemblies_loaded = _load_tools_assemblies();
+ CRASH_COND_MSG(!tools_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
#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;
}
@@ -1007,13 +962,13 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
String domain_name = mono_domain_get_friendly_name(p_domain);
- print_verbose("Mono: Unloading domain `" + domain_name + "`...");
+ print_verbose("Mono: Unloading domain '" + domain_name + "'...");
if (mono_domain_get() == p_domain)
mono_domain_set(root_domain, true);
if (!mono_domain_finalize(p_domain, 2000)) {
- ERR_PRINT("Mono: Domain finalization timeout");
+ ERR_PRINT("Mono: Domain finalization timeout.");
}
mono_gc_collect(mono_gc_max_generation());
@@ -1024,7 +979,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
mono_domain_try_unload(p_domain, (MonoObject **)&exc);
if (exc) {
- ERR_PRINTS("Exception thrown when unloading domain `" + domain_name + "`");
+ ERR_PRINTS("Exception thrown when unloading domain '" + domain_name + "'.");
GDMonoUtils::debug_print_unhandled_exception(exc);
return FAILED;
}
@@ -1131,6 +1086,8 @@ GDMono::GDMono() {
#ifdef TOOLS_ENABLED
api_editor_hash = 0;
#endif
+
+ unhandled_exception_policy = POLICY_TERMINATE_APP;
}
GDMono::~GDMono() {
@@ -1139,7 +1096,7 @@ GDMono::~GDMono() {
if (scripts_domain) {
Error err = _unload_scripts_domain();
if (err != OK) {
- ERR_PRINT("Mono: Failed to unload scripts domain");
+ ERR_PRINT("Mono: Failed to unload scripts domain.");
}
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index a926bf4126..4f7d3791f7 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -80,6 +80,13 @@ String to_string(Type p_type);
class GDMono {
+public:
+ enum UnhandledExceptionPolicy {
+ POLICY_TERMINATE_APP,
+ POLICY_LOG_ERROR
+ };
+
+private:
bool runtime_initialized;
bool finalizing_scripts_domain;
@@ -102,8 +109,12 @@ class GDMono {
HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies;
+ UnhandledExceptionPolicy unhandled_exception_policy;
+
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
@@ -112,11 +123,8 @@ class GDMono {
#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();
@@ -157,14 +165,15 @@ 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);
- String get_invalidated_api_assembly_path(APIAssembly::Type p_api_type);
+ bool copy_prebuilt_api_assembly(APIAssembly::Type p_api_type, const String &p_config);
+ String update_api_assemblies_from_prebuilt();
#endif
static GDMono *get_singleton() { return singleton; }
- static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
+ GD_NORETURN static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
+
+ UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; }
// Do not use these, unless you know what you're doing
void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly);
@@ -203,6 +212,7 @@ public:
Error finalize_and_unload_domain(MonoDomain *p_domain);
void initialize();
+ void initialize_load_assemblies();
GDMono();
~GDMono();
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 761c7f6fcb..a82bb42731 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -151,14 +151,14 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, vo
}
{
- // If we find the assembly here, we load it with `mono_assembly_load_from_full`,
+ // If we find the assembly here, we load it with 'mono_assembly_load_from_full',
// which in turn invokes load hooks before returning the MonoAssembly to us.
- // One of the load hooks is `load_aot_module`. This hook can end up calling preload hooks
- // again for the same assembly in certain in certain circumstances (the `do_load_image` part).
+ // One of the load hooks is 'load_aot_module'. This hook can end up calling preload hooks
+ // again for the same assembly in certain in certain circumstances (the 'do_load_image' part).
// If this is the case and we return NULL due to the no_search condition below,
// it will result in an internal crash later on. Therefore we need to return the assembly we didn't
- // get yet from `mono_assembly_load_from_full`. Luckily we have the image, which already got it.
- // This must be done here. If done in search hooks, it would cause `mono_assembly_load_from_full`
+ // get yet from 'mono_assembly_load_from_full'. Luckily we have the image, which already got it.
+ // This must be done here. If done in search hooks, it would cause 'mono_assembly_load_from_full'
// to think another MonoAssembly for this assembly was already loaded, making it delete its own,
// when in fact both pointers were the same... This hooks thing is confusing.
if (image_corlib_loading) {
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 1c10d3c8eb..89a88fcfb2 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -165,8 +165,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
#ifdef DEBUG_ENABLED
String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")";
- WARN_PRINTS("Method `" + fullname + "` is hidden by Godot API method. Should be `" +
- method->get_full_name_no_class() + "`. In class `" + namespace_name + "." + class_name + "`.");
+ WARN_PRINTS("Method '" + fullname + "' is hidden by Godot API method. Should be '" +
+ method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'.");
#endif
continue;
}
@@ -184,8 +184,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
if (m && m->get_name() != name) {
// found
String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")";
- WARN_PRINTS("Method `" + fullname + "` should be `" + m->get_full_name_no_class() +
- "`. In class `" + namespace_name + "." + class_name + "`.");
+ WARN_PRINTS("Method '" + fullname + "' should be '" + m->get_full_name_no_class() +
+ "'. In class '" + namespace_name + "." + class_name + "'.");
break;
}
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 3999658f93..7b8e6f89e9 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -219,16 +219,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
default: {
- ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Attempted to convert Variant to a managed enum value of unmarshallable base type.");
}
}
break;
}
- ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());
- ERR_FAIL();
+ ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + tclass->get_name() + "'.");
} break;
case MONO_TYPE_ARRAY:
@@ -275,8 +273,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
- ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
- ERR_FAIL();
+ ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
case MONO_TYPE_CLASS: {
@@ -351,8 +348,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
}
}
- ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name());
- ERR_FAIL();
+ ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
} break;
case MONO_TYPE_OBJECT: {
@@ -508,7 +504,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
} break;
default: {
- ERR_PRINTS(String() + "Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding));
+ ERR_PRINTS("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + ".");
} break;
}
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index a84332d4cd..3324ecb3a8 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -48,7 +48,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
CRASH_COND(!unmanaged);
- // All mono objects created from the managed world (e.g.: `new Player()`)
+ // All mono objects created from the managed world (e.g.: 'new Player()')
// need to have a CSharpScript in order for their methods to be callable from the unmanaged side
Reference *ref = Object::cast_to<Reference>(unmanaged);
@@ -108,9 +108,18 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
void unhandled_exception(MonoException *p_exc) {
mono_unhandled_exception((MonoObject *)p_exc); // prints the exception as well
- // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
- GDMono::unhandled_exception_hook((MonoObject *)p_exc, NULL);
- GD_UNREACHABLE();
+
+ if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
+ // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
+ GDMono::unhandled_exception_hook((MonoObject *)p_exc, NULL);
+ GD_UNREACHABLE();
+ } else {
+#ifdef DEBUG_ENABLED
+ GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
+ if (ScriptDebugger::get_singleton())
+ ScriptDebugger::get_singleton()->idle_poll();
+#endif
+ }
}
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h
index 2d77bde27c..0d82723913 100644
--- a/modules/mono/mono_gd/gd_mono_internals.h
+++ b/modules/mono/mono_gd/gd_mono_internals.h
@@ -45,7 +45,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
* Do not call this function directly.
* Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead.
*/
-GD_NORETURN void unhandled_exception(MonoException *p_exc);
+void unhandled_exception(MonoException *p_exc);
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index a6e04e561d..6d91075ce3 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -72,7 +72,7 @@ static void mono_log_callback(const char *log_domain, const char *log_level, con
}
if (fatal) {
- ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: " + GDMonoLog::get_singleton()->get_log_file_path() + "\n");
+ ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->get_log_file_path() + "'.");
// Make sure to flush before aborting
f->flush();
f->close();
@@ -90,8 +90,7 @@ bool GDMonoLog::_try_create_logs_dir(const String &p_logs_dir) {
DirAccessRef diraccess = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
ERR_FAIL_COND_V(!diraccess, false);
Error logs_mkdir_err = diraccess->make_dir_recursive(p_logs_dir);
- ERR_EXPLAIN("Failed to create mono logs directory");
- ERR_FAIL_COND_V(logs_mkdir_err != OK, false);
+ ERR_FAIL_COND_V_MSG(logs_mkdir_err != OK, false, "Failed to create mono logs directory.");
}
return true;
@@ -131,7 +130,7 @@ void GDMonoLog::initialize() {
CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8();
if (log_level.length() != 0 && log_level_get_id(log_level.get_data()) == -1) {
- ERR_PRINTS(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): " + log_level.get_data());
+ ERR_PRINTS(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): '" + log_level.get_data() + "'.");
log_level = CharString();
}
@@ -160,7 +159,7 @@ void GDMonoLog::initialize() {
log_file = FileAccess::open(log_file_path, FileAccess::WRITE);
if (!log_file) {
- ERR_PRINT("Mono: Cannot create log file");
+ ERR_PRINTS("Mono: Cannot create log file at: " + log_file_path);
}
}
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 42102ed835..7aac691102 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -276,7 +276,7 @@ String mono_to_utf8_string(MonoString *p_mono_string) {
char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
if (!mono_error_ok(&error)) {
- ERR_PRINTS(String("Failed to convert MonoString* to UTF-8: ") + mono_error_get_message(&error));
+ ERR_PRINTS(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'.");
mono_error_cleanup(&error);
return String();
}
@@ -474,8 +474,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return BOX_ENUM(enum_baseclass, val);
}
default: {
- ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
}
}
}
@@ -509,8 +508,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
- ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
case MONO_TYPE_CLASS: {
@@ -695,9 +693,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
} break;
}
- ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" +
- p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to an unmarshallable managed type. Name: '" +
+ p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + ".");
}
Variant mono_object_to_variant(MonoObject *p_obj) {
@@ -809,8 +806,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return mono_array_to_PoolColorArray((MonoArray *)p_obj);
- ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant.");
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
} break;
case MONO_TYPE_CLASS: {
@@ -908,9 +904,8 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
} break;
}
- ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
- type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding));
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" +
+ type.type_class->get_name() + "' Encoding: " + itos(type.type_encoding) + ".");
}
MonoArray *Array_to_mono_array(const Array &p_array) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 5987fa8ebb..e385f4c601 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -37,6 +37,10 @@
#include "core/project_settings.h"
#include "core/reference.h"
+#ifdef TOOLS_ENABLED
+#include "editor/script_editor_debugger.h"
+#endif
+
#include "../csharp_script.h"
#include "../utils/macros.h"
#include "../utils/mutex_utils.h"
@@ -48,14 +52,11 @@ namespace GDMonoUtils {
MonoCache mono_cache;
-#define CACHE_AND_CHECK(m_var, m_val) \
- { \
- CRASH_COND(m_var != NULL); \
- m_var = m_val; \
- if (!m_var) { \
- ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
- ERR_FAIL(); \
- } \
+#define CACHE_AND_CHECK(m_var, m_val) \
+ { \
+ CRASH_COND(m_var != NULL); \
+ m_var = m_val; \
+ ERR_FAIL_COND_MSG(!m_var, "Mono Cache: Member " #m_var " is null."); \
}
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val)
@@ -449,10 +450,9 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) {
}
MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) {
- 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);
- }
+ bool parent_is_object_class = ClassDB::is_parent_class(p_object->get_class_name(), p_native);
+ ERR_FAIL_COND_V_MSG(!parent_is_object_class, NULL,
+ "Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'.");
MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
ERR_FAIL_NULL_V(mono_object, NULL);
@@ -596,8 +596,14 @@ void debug_print_unhandled_exception(MonoException *p_exc) {
void debug_send_unhandled_exception_error(MonoException *p_exc) {
#ifdef DEBUG_ENABLED
- if (!ScriptDebugger::get_singleton())
+ if (!ScriptDebugger::get_singleton()) {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ ERR_PRINTS(GDMonoUtils::get_exception_name_and_message(p_exc));
+ }
+#endif
return;
+ }
_TLS_RECURSION_GUARD_;
@@ -621,7 +627,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
if (unexpected_exc) {
GDMonoInternals::unhandled_exception(unexpected_exc);
- GD_UNREACHABLE();
+ return;
}
Vector<ScriptLanguage::StackInfo> _si;
@@ -655,7 +661,6 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
void debug_unhandled_exception(MonoException *p_exc) {
GDMonoInternals::unhandled_exception(p_exc); // prints the exception as well
- GD_UNREACHABLE();
}
void print_unhandled_exception(MonoException *p_exc) {
@@ -665,11 +670,9 @@ void print_unhandled_exception(MonoException *p_exc) {
void set_pending_exception(MonoException *p_exc) {
#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();
}
if (!mono_runtime_set_pending_exception(p_exc, false)) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index f535fbb6d0..d73743bf0b 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -289,7 +289,7 @@ void set_exception_message(MonoException *p_exc, String message);
void debug_print_unhandled_exception(MonoException *p_exc);
void debug_send_unhandled_exception_error(MonoException *p_exc);
-GD_NORETURN void debug_unhandled_exception(MonoException *p_exc);
+void debug_unhandled_exception(MonoException *p_exc);
void print_unhandled_exception(MonoException *p_exc);
/**
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index 54d73c971f..189ceaab1b 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -67,10 +67,8 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
#ifdef DEBUG_ENABLED
- if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) {
- ERR_EXPLAIN("Resumed after await, but class instance is gone");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(),
+ "Resumed after await, but class instance is gone.");
#endif
if (p_argcount < 1) {
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index 2b014c2a45..716c712ccc 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -55,10 +55,7 @@ int sfind(const String &p_text, int p_from) {
for (int j = 0; j < src_len; j++) {
int read_pos = i + j;
- if (read_pos >= len) {
- ERR_PRINT("read_pos >= len");
- return -1;
- };
+ ERR_FAIL_COND_V(read_pos >= len, -1);
switch (j) {
case 0:
@@ -211,14 +208,18 @@ String str_format(const char *p_format, ...) {
#endif
#if defined(MINGW_ENABLED) || defined(_MSC_VER) && _MSC_VER < 1900
-#define vsnprintf(m_buffer, m_count, m_format, m_argptr) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_argptr)
+#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_args_copy)
+#define gd_vscprintf(m_format, m_args_copy) _vscprintf(m_format, m_args_copy)
+#else
+#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf(m_buffer, m_count, m_format, m_args_copy)
+#define gd_vscprintf(m_format, m_args_copy) vsnprintf(NULL, 0, p_format, m_args_copy)
#endif
String str_format(const char *p_format, va_list p_list) {
va_list list;
va_copy(list, p_list);
- int len = vsnprintf(NULL, 0, p_format, list);
+ int len = gd_vscprintf(p_format, list);
va_end(list);
len += 1; // for the trailing '/0'
@@ -226,7 +227,7 @@ String str_format(const char *p_format, va_list p_list) {
char *buffer(memnew_arr(char, len));
va_copy(list, p_list);
- vsnprintf(buffer, len, p_format, list);
+ gd_vsnprintf(buffer, len, p_format, list);
va_end(list);
String res(buffer);
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/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
index 615081d818..d3e8d3c9bb 100644
--- a/modules/opus/audio_stream_opus.cpp
+++ b/modules/opus/audio_stream_opus.cpp
@@ -287,8 +287,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) {
int ret = op_read(opus_file, (opus_int16 *)p_buffer, todo * stream_channels, &current_section);
if (ret < 0) {
playing = false;
- ERR_EXPLAIN("Error reading Opus File: " + file);
- ERR_BREAK(ret < 0);
+ ERR_BREAK_MSG(ret < 0, "Error reading Opus file: " + file + ".");
} else if (ret == 0) { // end of song, reload?
op_free(opus_file);
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 8b1f21d95d..cf6b396180 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -149,8 +149,7 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
format = Image::FORMAT_ETC;
break;
default:
- ERR_EXPLAIN("Unsupported format in PVR texture: " + itos(flags & 0xFF));
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unsupported format in PVR texture: " + itos(flags & 0xFF) + ".");
}
w.release();
diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/recast/navigation_mesh_generator.cpp
index 14467dc5c7..c5b60f2dca 100644
--- a/modules/recast/navigation_mesh_generator.cpp
+++ b/modules/recast/navigation_mesh_generator.cpp
@@ -49,6 +49,10 @@
#include "modules/csg/csg_shape.h"
#endif
+#ifdef MODULE_GRIDMAP_ENABLED
+#include "modules/gridmap/grid_map.h"
+#endif
+
EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::singleton = NULL;
void EditorNavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
@@ -240,8 +244,21 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
}
}
- if (Object::cast_to<Spatial>(p_node)) {
+#ifdef MODULE_GRIDMAP_ENABLED
+ if (Object::cast_to<GridMap>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ GridMap *gridmap_instance = Object::cast_to<GridMap>(p_node);
+ Array meshes = gridmap_instance->get_meshes();
+ Transform xform = gridmap_instance->get_transform();
+ for (int i = 0; i < meshes.size(); i += 2) {
+ Ref<Mesh> mesh = meshes[i + 1];
+ if (mesh.is_valid()) {
+ _add_mesh(mesh, p_accumulated_transform * xform * meshes[i], p_verticies, p_indices);
+ }
+ }
+ }
+#endif
+ if (Object::cast_to<Spatial>(p_node)) {
Spatial *spatial = Object::cast_to<Spatial>(p_node);
p_accumulated_transform = p_accumulated_transform * spatial->get_transform();
}
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index acbe4a5a01..1be5af02a5 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -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",
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 64f4c169cb..9b0a55eae3 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -57,8 +57,7 @@ void image_decompress_squish(Image *p_image) {
} else if (p_image->get_format() == Image::FORMAT_RGTC_RG) {
squish_flags = squish::kBc5;
} else {
- ERR_EXPLAIN("Squish: Can't decompress unknown format: " + itos(p_image->get_format()));
- ERR_FAIL_COND(true);
+ ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + ".");
return;
}
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index b0cd648734..a2ef88d130 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -109,12 +109,10 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
float upscale = upsample ? 2.0 : 1.0;
int w = (int)(svg_image->width * p_scale * upscale);
- ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
- ERR_FAIL_COND_V(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR);
+ ERR_FAIL_COND_V_MSG(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale)));
int h = (int)(svg_image->height * p_scale * upscale);
- ERR_EXPLAIN(vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
- ERR_FAIL_COND_V(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR);
+ ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
PoolVector<uint8_t> dst_image;
dst_image.resize(w * h * 4);
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index ae542713ea..6a1b463305 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -499,7 +499,6 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
/*If we are too slow, reduce the pp level.*/
pp_inc = pp_level > 0 ? -1 : 0;
}
- } else {
}
} else {
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index 4003fdc802..ee8479b1b4 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderTinyEXR : public ImageFormatLoader {
public:
diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp
new file mode 100644
index 0000000000..e1d42d3217
--- /dev/null
+++ b/modules/tinyexr/image_saver_tinyexr.cpp
@@ -0,0 +1,279 @@
+/*************************************************************************/
+/* image_saver_tinyexr.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 "image_saver_tinyexr.h"
+#include "core/math/math_funcs.h"
+
+#include "thirdparty/tinyexr/tinyexr.h"
+
+static bool is_supported_format(Image::Format p_format) {
+ // This is checked before anything else.
+ // Mostly uncompressed formats are considered.
+ switch (p_format) {
+ case Image::FORMAT_RF:
+ case Image::FORMAT_RGF:
+ case Image::FORMAT_RGBF:
+ case Image::FORMAT_RGBAF:
+ case Image::FORMAT_RH:
+ case Image::FORMAT_RGH:
+ case Image::FORMAT_RGBH:
+ case Image::FORMAT_RGBAH:
+ case Image::FORMAT_R8:
+ case Image::FORMAT_RG8:
+ case Image::FORMAT_RGB8:
+ case Image::FORMAT_RGBA8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+enum SrcPixelType {
+ SRC_FLOAT,
+ SRC_HALF,
+ SRC_BYTE
+};
+
+static SrcPixelType get_source_pixel_type(Image::Format p_format) {
+ switch (p_format) {
+ case Image::FORMAT_RF:
+ case Image::FORMAT_RGF:
+ case Image::FORMAT_RGBF:
+ case Image::FORMAT_RGBAF:
+ return SRC_FLOAT;
+ case Image::FORMAT_RH:
+ case Image::FORMAT_RGH:
+ case Image::FORMAT_RGBH:
+ case Image::FORMAT_RGBAH:
+ return SRC_HALF;
+ case Image::FORMAT_R8:
+ case Image::FORMAT_RG8:
+ case Image::FORMAT_RGB8:
+ case Image::FORMAT_RGBA8:
+ return SRC_BYTE;
+ default:
+ CRASH_NOW();
+ }
+}
+
+static int get_target_pixel_type(Image::Format p_format) {
+ switch (p_format) {
+ case Image::FORMAT_RF:
+ case Image::FORMAT_RGF:
+ case Image::FORMAT_RGBF:
+ case Image::FORMAT_RGBAF:
+ return TINYEXR_PIXELTYPE_FLOAT;
+ case Image::FORMAT_RH:
+ case Image::FORMAT_RGH:
+ case Image::FORMAT_RGBH:
+ case Image::FORMAT_RGBAH:
+ // EXR doesn't support 8-bit channels so in that case we'll convert
+ case Image::FORMAT_R8:
+ case Image::FORMAT_RG8:
+ case Image::FORMAT_RGB8:
+ case Image::FORMAT_RGBA8:
+ return TINYEXR_PIXELTYPE_HALF;
+ default:
+ CRASH_NOW();
+ }
+}
+
+static int get_pixel_type_size(int p_pixel_type) {
+ switch (p_pixel_type) {
+ case TINYEXR_PIXELTYPE_HALF:
+ return 2;
+ case TINYEXR_PIXELTYPE_FLOAT:
+ return 4;
+ }
+ CRASH_NOW();
+}
+
+static int get_channel_count(Image::Format p_format) {
+ switch (p_format) {
+ case Image::FORMAT_RF:
+ case Image::FORMAT_RH:
+ case Image::FORMAT_R8:
+ return 1;
+ case Image::FORMAT_RGF:
+ case Image::FORMAT_RGH:
+ case Image::FORMAT_RG8:
+ return 2;
+ case Image::FORMAT_RGBF:
+ case Image::FORMAT_RGBH:
+ case Image::FORMAT_RGB8:
+ return 3;
+ case Image::FORMAT_RGBAF:
+ case Image::FORMAT_RGBAH:
+ case Image::FORMAT_RGBA8:
+ return 4;
+ default:
+ CRASH_NOW();
+ }
+}
+
+Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale) {
+
+ Image::Format format = p_img->get_format();
+
+ if (!is_supported_format(format)) {
+ // Format not supported
+ print_error("Image format not supported for saving as EXR. Consider saving as PNG.");
+ return ERR_UNAVAILABLE;
+ }
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ const int max_channels = 4;
+
+ // Godot does not support more than 4 channels,
+ // so we can preallocate header infos on the stack and use only the subset we need
+ PoolByteArray channels[max_channels];
+ unsigned char *channels_ptrs[max_channels];
+ EXRChannelInfo channel_infos[max_channels];
+ int pixel_types[max_channels];
+ int requested_pixel_types[max_channels] = { -1 };
+
+ // Gimp and Blender are a bit annoying so order of channels isn't straightforward.
+ const int channel_mappings[4][4] = {
+ { 0 }, // R
+ { 1, 0 }, // GR
+ { 2, 1, 0 }, // BGR
+ { 2, 1, 0, 3 } // BGRA
+ };
+
+ int channel_count = get_channel_count(format);
+ ERR_FAIL_COND_V(p_grayscale && channel_count != 1, ERR_INVALID_PARAMETER);
+
+ int target_pixel_type = get_target_pixel_type(format);
+ int target_pixel_type_size = get_pixel_type_size(target_pixel_type);
+ SrcPixelType src_pixel_type = get_source_pixel_type(format);
+ const int pixel_count = p_img->get_width() * p_img->get_height();
+
+ const int *channel_mapping = channel_mappings[channel_count - 1];
+
+ {
+ PoolByteArray src_data = p_img->get_data();
+ PoolByteArray::Read src_r = src_data.read();
+
+ for (int channel_index = 0; channel_index < channel_count; ++channel_index) {
+
+ // De-interleave channels
+
+ PoolByteArray &dst = channels[channel_index];
+ dst.resize(pixel_count * target_pixel_type_size);
+
+ PoolByteArray::Write dst_w = dst.write();
+
+ if (src_pixel_type == SRC_FLOAT && target_pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+
+ // Note: we don't save mipmaps
+ CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
+
+ const float *src_rp = (float *)src_r.ptr();
+ float *dst_wp = (float *)dst_w.ptr();
+
+ for (int i = 0; i < pixel_count; ++i) {
+ dst_wp[i] = src_rp[channel_index + i * channel_count];
+ }
+
+ } else if (src_pixel_type == SRC_HALF && target_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+
+ CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
+
+ const uint16_t *src_rp = (uint16_t *)src_r.ptr();
+ uint16_t *dst_wp = (uint16_t *)dst_w.ptr();
+
+ for (int i = 0; i < pixel_count; ++i) {
+ dst_wp[i] = src_rp[channel_index + i * channel_count];
+ }
+
+ } else if (src_pixel_type == SRC_BYTE && target_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+
+ CRASH_COND(src_data.size() < pixel_count * channel_count);
+
+ const uint8_t *src_rp = (uint8_t *)src_r.ptr();
+ uint16_t *dst_wp = (uint16_t *)dst_w.ptr();
+
+ for (int i = 0; i < pixel_count; ++i) {
+ dst_wp[i] = Math::make_half_float(src_rp[channel_index + i * channel_count] / 255.f);
+ }
+
+ } else {
+ CRASH_NOW();
+ }
+
+ int remapped_index = channel_mapping[channel_index];
+
+ channels_ptrs[remapped_index] = dst_w.ptr();
+
+ // No conversion
+ pixel_types[remapped_index] = target_pixel_type;
+ requested_pixel_types[remapped_index] = target_pixel_type;
+
+ // Write channel name
+ if (p_grayscale) {
+ channel_infos[remapped_index].name[0] = 'Y';
+ channel_infos[remapped_index].name[1] = '\0';
+ } else {
+ const char *rgba = "RGBA";
+ channel_infos[remapped_index].name[0] = rgba[channel_index];
+ channel_infos[remapped_index].name[1] = '\0';
+ }
+ }
+ }
+
+ image.images = channels_ptrs;
+ image.num_channels = channel_count;
+ image.width = p_img->get_width();
+ image.height = p_img->get_height();
+
+ header.num_channels = image.num_channels;
+ header.channels = channel_infos;
+ header.pixel_types = pixel_types;
+ header.requested_pixel_types = requested_pixel_types;
+ // TODO DEBUG REMOVE
+ for (int i = 0; i < 4; ++i) {
+ print_line(String("requested_pixel_types{0}: {1}").format(varray(i, requested_pixel_types[i])));
+ }
+
+ CharString utf8_filename = p_path.utf8();
+ const char *err;
+ int ret = SaveEXRImageToFile(&image, &header, utf8_filename.ptr(), &err);
+ if (ret != TINYEXR_SUCCESS) {
+ print_error(String("Saving EXR failed. Error: {0}").format(varray(err)));
+ return ERR_FILE_CANT_WRITE;
+ }
+
+ return OK;
+}
diff --git a/modules/tinyexr/image_saver_tinyexr.h b/modules/tinyexr/image_saver_tinyexr.h
new file mode 100644
index 0000000000..298bd1d21c
--- /dev/null
+++ b/modules/tinyexr/image_saver_tinyexr.h
@@ -0,0 +1,38 @@
+/*************************************************************************/
+/* image_saver_tinyexr.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 IMAGE_SAVER_TINYEXR_H
+#define IMAGE_SAVER_TINYEXR_H
+
+#include "core/os/os.h"
+
+Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
+
+#endif // IMAGE_SAVER_TINYEXR_H
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index 5473a55687..233b3afa08 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -31,6 +31,7 @@
#include "register_types.h"
#include "image_loader_tinyexr.h"
+#include "image_saver_tinyexr.h"
static ImageLoaderTinyEXR *image_loader_tinyexr = NULL;
@@ -38,9 +39,13 @@ void register_tinyexr_types() {
image_loader_tinyexr = memnew(ImageLoaderTinyEXR);
ImageLoader::add_image_format_loader(image_loader_tinyexr);
+
+ Image::save_exr_func = save_exr;
}
void unregister_tinyexr_types() {
memdelete(image_loader_tinyexr);
+
+ Image::save_exr_func = NULL;
}
diff --git a/modules/vhacd/SCsub b/modules/vhacd/SCsub
index e581fb7bb2..685976dc33 100644
--- a/modules/vhacd/SCsub
+++ b/modules/vhacd/SCsub
@@ -26,10 +26,6 @@ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_vhacd.Prepend(CPPPATH=[thirdparty_dir + "/inc"])
-# upstream uses c++11
-if not env.msvc:
- env_vhacd.Append(CXXFLAGS="-std=c++11")
-
env_thirdparty = env_vhacd.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 470a3a5e35..9e3670ec35 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -213,7 +213,11 @@
return t * t * (3.0 - 2.0 * t)
[/codeblock]
</constant>
- <constant name="FUNC_MAX" value="65" enum="BuiltinFunc">
+ <constant name="MATH_POSMOD" value="65" enum="BuiltinFunc">
+ </constant>
+ <constant name="MATH_LERP_ANGLE" value="66" enum="BuiltinFunc">
+ </constant>
+ <constant name="FUNC_MAX" value="67" enum="BuiltinFunc">
Represents the size of the [enum BuiltinFunc] enum.
</constant>
</constants>
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 b816e37936..6bed1742eb 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -328,8 +328,7 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
if (Object::cast_to<VisualScriptFunction>(*p_node)) {
//the function indeed
- ERR_EXPLAIN("A function node already has been set here.");
- ERR_FAIL_COND(func.function_id >= 0);
+ ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here.");
func.function_id = p_id;
}
@@ -579,6 +578,10 @@ void VisualScript::get_data_connection_list(const StringName &p_func, List<DataC
}
}
+void VisualScript::set_tool_enabled(bool p_enabled) {
+ is_tool_script = p_enabled;
+}
+
void VisualScript::add_variable(const StringName &p_name, const Variant &p_default_value, bool p_export) {
ERR_FAIL_COND(instances.size());
@@ -895,7 +898,7 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
#ifdef TOOLS_ENABLED
- if (!ScriptServer::is_scripting_enabled()) {
+ if (!ScriptServer::is_scripting_enabled() && !is_tool_script) {
PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(VisualScriptLanguage::singleton, Ref<Script>((Script *)this), p_this));
placeholders.insert(sins);
@@ -959,7 +962,7 @@ Error VisualScript::reload(bool p_keep_state) {
bool VisualScript::is_tool() const {
- return false;
+ return is_tool_script;
}
bool VisualScript::is_valid() const {
@@ -1165,6 +1168,11 @@ void VisualScript::_set_data(const Dictionary &p_data) {
data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]);
}
}
+
+ if (d.has("is_tool_script"))
+ is_tool_script = d["is_tool_script"];
+ else
+ is_tool_script = false;
}
Dictionary VisualScript::_get_data() const {
@@ -1247,6 +1255,8 @@ Dictionary VisualScript::_get_data() const {
d["functions"] = funcs;
+ d["is_tool_script"] = is_tool_script;
+
return d;
}
@@ -1917,8 +1927,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
if (!E) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- ERR_EXPLAIN("No VisualScriptFunction node in function!");
- ERR_FAIL_V(Variant());
+ ERR_FAIL_V_MSG(Variant(), "No VisualScriptFunction node in function.");
}
VisualScriptNodeInstance *node = E->get();
@@ -1974,8 +1983,7 @@ String VisualScriptInstance::to_string(bool *r_valid) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
- ERR_EXPLAIN("Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
- ERR_FAIL_V(String());
+ ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
if (r_valid)
*r_valid = true;
@@ -2262,15 +2270,10 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- if (instance_id && !ObjectDB::get_instance(instance_id)) {
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
- ERR_FAIL_V(Variant());
- }
- if (script_id && !ObjectDB::get_instance(script_id)) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+
#endif
r_error.error = Variant::CallError::CALL_OK;
@@ -2329,15 +2332,10 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- if (instance_id && !ObjectDB::get_instance(instance_id)) {
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
- ERR_FAIL_V(Variant());
- }
- if (script_id && !ObjectDB::get_instance(script_id)) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
+ ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+
#endif
Variant::CallError r_error;
@@ -2463,7 +2461,7 @@ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, c
_debug_parse_err_node = p_node;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false);
+ ScriptDebugger::get_singleton()->debug(this, false, true);
return true;
} else {
return false;
@@ -2477,7 +2475,7 @@ bool VisualScriptLanguage::debug_break(const String &p_error, bool p_allow_conti
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, p_allow_continue);
+ ScriptDebugger::get_singleton()->debug(this, p_allow_continue, true);
return true;
} else {
return false;
@@ -2629,8 +2627,6 @@ void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Varian
}
String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_node >= 0)
- return "";
return "";
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 098c28370d..14927c4363 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -247,6 +247,8 @@ private:
Map<Object *, VisualScriptInstance *> instances;
+ bool is_tool_script;
+
#ifdef TOOLS_ENABLED
Set<PlaceHolderScriptInstance *> placeholders;
//void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
@@ -273,6 +275,7 @@ public:
Vector2 get_function_scroll(const StringName &p_name) const;
void get_function_list(List<StringName> *r_functions) const;
int get_function_node_id(const StringName &p_name) const;
+ void set_tool_enabled(bool p_enabled);
void add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2());
void remove_node(const StringName &p_func, int p_id);
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 75b79f8929..3fdceacebb 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -104,6 +104,9 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"bytes2var",
"color_named",
"smoothstep",
+ "posmod",
+ "lerp_angle",
+ "ord",
};
VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::find_function(const String &p_string) {
@@ -179,6 +182,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case OBJ_WEAKREF:
case TYPE_OF:
case TEXT_CHAR:
+ case TEXT_ORD:
case TEXT_STR:
case TEXT_PRINT:
case TEXT_PRINTERR:
@@ -192,6 +196,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case MATH_ATAN2:
case MATH_FMOD:
case MATH_FPOSMOD:
+ case MATH_POSMOD:
case MATH_POW:
case MATH_EASE:
case MATH_STEPIFY:
@@ -205,6 +210,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case COLORN:
return 2;
case MATH_LERP:
+ case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
case MATH_SMOOTHSTEP:
case MATH_MOVE_TOWARD:
@@ -261,7 +267,16 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_ASIN:
case MATH_ACOS:
case MATH_ATAN:
- case MATH_SQRT: {
+ case MATH_SQRT:
+ case MATH_FLOOR:
+ case MATH_CEIL:
+ case MATH_ROUND:
+ case MATH_ABS:
+ case MATH_SIGN:
+ case MATH_LOG:
+ case MATH_EXP:
+ case MATH_ISNAN:
+ case MATH_ISINF: {
return PropertyInfo(Variant::REAL, "s");
} break;
case MATH_ATAN2: {
@@ -271,32 +286,25 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::REAL, "x");
} break;
case MATH_FMOD:
- case MATH_FPOSMOD: {
+ case MATH_FPOSMOD:
+ case LOGIC_MAX:
+ case LOGIC_MIN: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "x");
+ return PropertyInfo(Variant::REAL, "a");
else
- return PropertyInfo(Variant::REAL, "y");
+ return PropertyInfo(Variant::REAL, "b");
} break;
- case MATH_FLOOR:
- case MATH_CEIL:
- case MATH_ROUND:
- case MATH_ABS:
- case MATH_SIGN: {
- return PropertyInfo(Variant::REAL, "s");
-
+ case MATH_POSMOD: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::INT, "a");
+ else
+ return PropertyInfo(Variant::INT, "b");
} break;
-
case MATH_POW: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "x");
+ return PropertyInfo(Variant::REAL, "base");
else
- return PropertyInfo(Variant::REAL, "y");
- } break;
- case MATH_LOG:
- case MATH_EXP:
- case MATH_ISNAN:
- case MATH_ISINF: {
- return PropertyInfo(Variant::REAL, "s");
+ return PropertyInfo(Variant::REAL, "exp");
} break;
case MATH_EASE: {
if (p_idx == 0)
@@ -313,15 +321,10 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::REAL, "steps");
} break;
- case MATH_LERP: {
- if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "from");
- else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "to");
- else
- return PropertyInfo(Variant::REAL, "weight");
- } break;
- case MATH_INVERSE_LERP: {
+ case MATH_LERP:
+ case MATH_LERP_ANGLE:
+ case MATH_INVERSE_LERP:
+ case MATH_SMOOTHSTEP: {
if (p_idx == 0)
return PropertyInfo(Variant::REAL, "from");
else if (p_idx == 1)
@@ -341,14 +344,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::REAL, "ostop");
} break;
- case MATH_SMOOTHSTEP: {
- if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "from");
- else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "to");
- else
- return PropertyInfo(Variant::REAL, "weight");
- } break;
case MATH_MOVE_TOWARD: {
if (p_idx == 0)
return PropertyInfo(Variant::REAL, "from");
@@ -365,12 +360,8 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::REAL, "step");
} break;
- case MATH_RANDOMIZE: {
-
- } break;
- case MATH_RAND: {
-
- } break;
+ case MATH_RANDOMIZE:
+ case MATH_RAND:
case MATH_RANDF: {
} break;
@@ -380,9 +371,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::REAL, "to");
} break;
- case MATH_SEED: {
- return PropertyInfo(Variant::INT, "seed");
- } break;
+ case MATH_SEED:
case MATH_RANDSEED: {
return PropertyInfo(Variant::INT, "seed");
} break;
@@ -418,26 +407,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
else
return PropertyInfo(Variant::INT, "max");
} break;
- case MATH_WRAPF: {
- if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "value");
- else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "min");
- else
- return PropertyInfo(Variant::REAL, "max");
- } break;
- case LOGIC_MAX: {
- if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "a");
- else
- return PropertyInfo(Variant::REAL, "b");
- } break;
- case LOGIC_MIN: {
- if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "a");
- else
- return PropertyInfo(Variant::REAL, "b");
- } break;
+ case MATH_WRAPF:
case LOGIC_CLAMP: {
if (p_idx == 0)
return PropertyInfo(Variant::REAL, "value");
@@ -450,20 +420,15 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::INT, "value");
} break;
case OBJ_WEAKREF: {
-
return PropertyInfo(Variant::OBJECT, "source");
-
} break;
case FUNC_FUNCREF: {
-
if (p_idx == 0)
return PropertyInfo(Variant::OBJECT, "instance");
else
return PropertyInfo(Variant::STRING, "funcname");
-
} break;
case TYPE_CONVERT: {
-
if (p_idx == 0)
return PropertyInfo(Variant::NIL, "what");
else
@@ -471,45 +436,27 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
} break;
case TYPE_OF: {
return PropertyInfo(Variant::NIL, "what");
-
} break;
case TYPE_EXISTS: {
-
return PropertyInfo(Variant::STRING, "type");
-
+ } break;
+ case TEXT_ORD: {
+ return PropertyInfo(Variant::STRING, "character");
} break;
case TEXT_CHAR: {
-
return PropertyInfo(Variant::INT, "ascii");
-
- } break;
- case TEXT_STR: {
-
- return PropertyInfo(Variant::NIL, "value");
-
- } break;
- case TEXT_PRINT: {
-
- return PropertyInfo(Variant::NIL, "value");
-
- } break;
- case TEXT_PRINTERR: {
- return PropertyInfo(Variant::NIL, "value");
-
} break;
+ case TEXT_STR:
+ case TEXT_PRINT:
+ case TEXT_PRINTERR:
case TEXT_PRINTRAW: {
-
return PropertyInfo(Variant::NIL, "value");
-
- } break;
- case VAR_TO_STR: {
- return PropertyInfo(Variant::NIL, "var");
-
} break;
case STR_TO_VAR: {
return PropertyInfo(Variant::STRING, "string");
} break;
+ case VAR_TO_STR:
case VAR_TO_BYTES: {
if (p_idx == 0)
return PropertyInfo(Variant::NIL, "var");
@@ -525,12 +472,10 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::BOOL, "allow_objects");
} break;
case COLORN: {
-
if (p_idx == 0)
return PropertyInfo(Variant::STRING, "name");
else
return PropertyInfo(Variant::REAL, "alpha");
-
} break;
case FUNC_MAX: {
}
@@ -561,6 +506,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_CEIL: {
t = Variant::REAL;
} break;
+ case MATH_POSMOD:
case MATH_ROUND: {
t = Variant::INT;
} break;
@@ -587,6 +533,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case MATH_STEPIFY:
case MATH_LERP:
+ case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
case MATH_RANGE_LERP:
case MATH_SMOOTHSTEP:
@@ -652,6 +599,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case TYPE_CONVERT: {
} break;
+ case TEXT_ORD:
case TYPE_OF: {
t = Variant::INT;
@@ -806,6 +754,12 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(1);
*r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
+ case VisualScriptBuiltinFunc::MATH_POSMOD: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]);
+ } break;
case VisualScriptBuiltinFunc::MATH_FLOOR: {
VALIDATE_ARG_NUM(0);
@@ -905,6 +859,13 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
+ case VisualScriptBuiltinFunc::MATH_LERP_ANGLE: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
case VisualScriptBuiltinFunc::MATH_INVERSE_LERP: {
VALIDATE_ARG_NUM(0);
@@ -1177,6 +1138,30 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = String(result);
} break;
+ case VisualScriptBuiltinFunc::TEXT_ORD: {
+
+ if (p_inputs[0]->get_type() != Variant::STRING) {
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::STRING;
+
+ return;
+ }
+
+ String str = p_inputs[0]->operator String();
+
+ if (str.length() != 1) {
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::STRING;
+ *r_return = "Expected a string of length 1 (a character).";
+
+ return;
+ }
+
+ *r_return = str.get(0);
+
+ } break;
case VisualScriptBuiltinFunc::TEXT_STR: {
String str = *p_inputs[0];
@@ -1417,6 +1402,9 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(BYTES_TO_VAR);
BIND_ENUM_CONSTANT(COLORN);
BIND_ENUM_CONSTANT(MATH_SMOOTHSTEP);
+ BIND_ENUM_CONSTANT(MATH_POSMOD);
+ BIND_ENUM_CONSTANT(MATH_LERP_ANGLE);
+ BIND_ENUM_CONSTANT(TEXT_ORD);
BIND_ENUM_CONSTANT(FUNC_MAX);
}
@@ -1454,6 +1442,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/sqrt", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SQRT>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/fmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FMOD>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/fposmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FPOSMOD>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/posmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_POSMOD>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/floor", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FLOOR>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/ceil", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_CEIL>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/round", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ROUND>);
@@ -1469,6 +1458,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECIMALS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp_angle", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP_ANGLE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/range_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANGE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/smoothstep", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SMOOTHSTEP>);
@@ -1501,6 +1491,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/typeof", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_OF>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/type_exists", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_EXISTS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/char", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_CHAR>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/ord", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_ORD>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/str", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_STR>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/print", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINT>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/printerr", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINTERR>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index f009f49b5b..998a6cbc6a 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -104,6 +104,9 @@ public:
BYTES_TO_VAR,
COLORN,
MATH_SMOOTHSTEP,
+ MATH_POSMOD,
+ MATH_LERP_ANGLE,
+ TEXT_ORD,
FUNC_MAX
};
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 31d5e4665a..7262dde359 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -591,6 +591,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->add_color_override("title_color", c);
c.a = 0.7;
gnode->add_color_override("close_color", c);
+ gnode->add_color_override("resizer_color", c);
gnode->add_style_override("frame", sbf);
}
@@ -776,8 +777,8 @@ void VisualScriptEditor::_update_members() {
TreeItem *functions = members->create_item(root);
functions->set_selectable(0, false);
functions->set_text(0, TTR("Functions:"));
- functions->add_button(0, Control::get_icon("Override", "EditorIcons"), 1);
- functions->add_button(0, Control::get_icon("Add", "EditorIcons"), 0);
+ functions->add_button(0, Control::get_icon("Override", "EditorIcons"), 1, false, TTR("Override an existing built-in function."));
+ functions->add_button(0, Control::get_icon("Add", "EditorIcons"), 0, false, TTR("Create a new function."));
functions->set_custom_color(0, Control::get_color("mono_color", "Editor"));
List<StringName> func_names;
@@ -795,7 +796,7 @@ void VisualScriptEditor::_update_members() {
TreeItem *variables = members->create_item(root);
variables->set_selectable(0, false);
variables->set_text(0, TTR("Variables:"));
- variables->add_button(0, Control::get_icon("Add", "EditorIcons"));
+ variables->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new variable."));
variables->set_custom_color(0, Control::get_color("mono_color", "Editor"));
Ref<Texture> type_icons[Variant::VARIANT_MAX] = {
@@ -848,7 +849,7 @@ void VisualScriptEditor::_update_members() {
TreeItem *_signals = members->create_item(root);
_signals->set_selectable(0, false);
_signals->set_text(0, TTR("Signals:"));
- _signals->add_button(0, Control::get_icon("Add", "EditorIcons"));
+ _signals->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new signal."));
_signals->set_custom_color(0, Control::get_color("mono_color", "Editor"));
List<StringName> signal_names;
@@ -2226,6 +2227,10 @@ void VisualScriptEditor::_change_base_type() {
select_base_type->popup_create(true, true);
}
+void VisualScriptEditor::_toggle_tool_script() {
+ script->set_tool_enabled(!script->is_tool());
+}
+
void VisualScriptEditor::clear_edit_menu() {
memdelete(edit_menu);
memdelete(left_vsplit);
@@ -3447,6 +3452,7 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
ClassDB::bind_method("_change_base_type", &VisualScriptEditor::_change_base_type);
ClassDB::bind_method("_change_base_type_callback", &VisualScriptEditor::_change_base_type_callback);
+ ClassDB::bind_method("_toggle_tool_script", &VisualScriptEditor::_toggle_tool_script);
ClassDB::bind_method("_node_selected", &VisualScriptEditor::_node_selected);
ClassDB::bind_method("_node_moved", &VisualScriptEditor::_node_moved);
ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node);
@@ -3532,6 +3538,11 @@ VisualScriptEditor::VisualScriptEditor() {
left_vb->set_v_size_flags(SIZE_EXPAND_FILL);
//left_vb->set_custom_minimum_size(Size2(230, 1) * EDSCALE);
+ CheckButton *tool_script_check = memnew(CheckButton);
+ tool_script_check->set_text(TTR("Make Tool:"));
+ left_vb->add_child(tool_script_check);
+ tool_script_check->connect("pressed", this, "_toggle_tool_script");
+
base_type_select = memnew(Button);
left_vb->add_margin_child(TTR("Base Type:"), base_type_select);
base_type_select->connect("pressed", this, "_change_base_type");
@@ -3670,7 +3681,6 @@ VisualScriptEditor::VisualScriptEditor() {
new_virtual_method_select = memnew(VisualScriptPropertySelector);
add_child(new_virtual_method_select);
new_virtual_method_select->connect("selected", this, "_selected_new_virtual_method");
- new_virtual_method_select->get_cancel();
member_popup = memnew(PopupMenu);
add_child(member_popup);
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 4f302d1d72..5df9b1a004 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -186,6 +186,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _node_filter_changed(const String &p_text);
void _change_base_type_callback();
void _change_base_type();
+ void _toggle_tool_script();
void _member_selected();
void _member_edited();
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 0413bbf303..c330fa1bc0 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -1026,7 +1026,6 @@ void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const {
}
PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const {
-
if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
if (p_idx == 0) {
PropertyInfo pi;
@@ -1037,6 +1036,16 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const
}
}
+ List<PropertyInfo> props;
+ ClassDB::get_property_list(_get_base_type(), &props, true);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (E->get().name == property) {
+ PropertyInfo pinfo = PropertyInfo(E->get().type, "value", PROPERTY_HINT_TYPE_STRING, E->get().hint_string);
+ _adjust_input_index(pinfo);
+ return pinfo;
+ }
+ }
+
PropertyInfo pinfo = type_cache;
pinfo.name = "value";
_adjust_input_index(pinfo);
@@ -1047,6 +1056,13 @@ PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) cons
if (call_mode == CALL_MODE_BASIC_TYPE) {
return PropertyInfo(basic_type, "out");
} else if (call_mode == CALL_MODE_INSTANCE) {
+ List<PropertyInfo> props;
+ ClassDB::get_property_list(_get_base_type(), &props, true);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (E->get().name == property) {
+ return PropertyInfo(E->get().type, "pass", PROPERTY_HINT_TYPE_STRING, E->get().hint_string);
+ }
+ }
return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type());
} else {
return PropertyInfo();
@@ -1796,14 +1812,12 @@ PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) const {
-
- if (index != StringName()) {
-
- Variant v;
- Variant::CallError ce;
- v = Variant::construct(type_cache, NULL, 0, ce);
- Variant i = v.get(index);
- return PropertyInfo(i.get_type(), "value." + String(index));
+ List<PropertyInfo> props;
+ ClassDB::get_property_list(_get_base_type(), &props, true);
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (E->get().name == property) {
+ return PropertyInfo(E->get().type, "value." + String(index));
+ }
}
return PropertyInfo(type_cache, "value");
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 1b0e41b2de..65820b4c15 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -197,7 +197,6 @@ String VisualScriptFunction::get_output_sequence_port_text(int p_port) const {
PropertyInfo VisualScriptFunction::get_input_value_port_info(int p_idx) const {
ERR_FAIL_V(PropertyInfo());
- return PropertyInfo();
}
PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
@@ -418,7 +417,7 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const {
{ Variant::NIL, Variant::NIL } //OP_IN,
};
- ERR_FAIL_INDEX_V(p_idx, Variant::OP_MAX, PropertyInfo());
+ ERR_FAIL_INDEX_V(p_idx, 2, PropertyInfo());
PropertyInfo pinfo;
pinfo.name = p_idx == 0 ? "A" : "B";
@@ -2531,7 +2530,7 @@ String VisualScriptCustomNode::get_category() const {
if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
return get_script_instance()->call("_get_category");
}
- return "custom";
+ return "Custom";
}
class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance {
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index 1e7ed3019c..764807cffd 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -130,12 +130,14 @@ void VisualScriptPropertySelector::_update_search() {
{
String b = String(E->get());
category = search_options->create_item(root);
- category->set_text(0, b.replace_first("*", ""));
- category->set_selectable(0, false);
- Ref<Texture> icon;
- String rep = b.replace("*", "");
- icon = EditorNode::get_singleton()->get_class_icon(rep);
- category->set_icon(0, icon);
+ if (category) {
+ category->set_text(0, b.replace_first("*", ""));
+ category->set_selectable(0, false);
+ Ref<Texture> icon;
+ String rep = b.replace("*", "");
+ icon = EditorNode::get_singleton()->get_class_icon(rep);
+ category->set_icon(0, icon);
+ }
}
if (properties || seq_connect) {
if (instance) {
@@ -405,7 +407,7 @@ void VisualScriptPropertySelector::_item_selected() {
String name = item->get_metadata(0);
String class_type;
- if (type) {
+ if (type != Variant::NIL) {
class_type = Variant::get_type_name(type);
} else {
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 2f4a45f108..2f56e778b9 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -116,8 +116,7 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
if (ret < 0) {
playing = false;
- ERR_EXPLAIN("Error reading OGG Vorbis File: " + file);
- ERR_BREAK(ret < 0);
+ ERR_BREAK_MSG(ret < 0, "Error reading OGG Vorbis file: " + file + ".");
} else if (ret == 0) { // end of song, reload?
ov_clear(&vf);
diff --git a/modules/webm/SCsub b/modules/webm/SCsub
index e57437229f..32e6727656 100644
--- a/modules/webm/SCsub
+++ b/modules/webm/SCsub
@@ -17,10 +17,6 @@ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_webm.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "libwebm/"])
-# upstream uses c++11
-if (not env_webm.msvc):
- env_webm.Append(CXXFLAGS="-std=c++11")
-
# also requires libogg, libvorbis and libopus
if env['builtin_libogg']:
env_webm.Prepend(CPPPATH=["#thirdparty/libogg"])
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 3670edc9ea..fa3602ad27 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -53,8 +53,7 @@ public:
file = FileAccess::open(p_file, FileAccess::READ);
- ERR_EXPLAIN("Failed loading resource: '" + p_file + "';");
- ERR_FAIL_COND(!file);
+ ERR_FAIL_COND_MSG(!file, "Failed loading resource: '" + p_file + "'.");
}
~MkvReader() {
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 630c15f140..d1bfa20842 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -84,8 +84,7 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Ref<Image>());
WebPBitstreamFeatures features;
if (WebPGetFeatures(&r[4], size, &features) != VP8_STATUS_OK) {
- ERR_EXPLAIN("Error unpacking WEBP image:");
- ERR_FAIL_V(Ref<Image>());
+ ERR_FAIL_V_MSG(Ref<Image>(), "Error unpacking WEBP image.");
}
/*
@@ -107,8 +106,7 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
errdec = WebPDecodeRGBInto(&r[4], size, dst_w.ptr(), datasize, 3 * features.width) == NULL;
}
- //ERR_EXPLAIN("Error decoding webp! - "+p_file);
- ERR_FAIL_COND_V(errdec, Ref<Image>());
+ ERR_FAIL_COND_V_MSG(errdec, Ref<Image>(), "Failed decoding WebP image.");
dst_w.release();
@@ -122,7 +120,6 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
WebPBitstreamFeatures features;
if (WebPGetFeatures(p_buffer, p_buffer_len, &features) != VP8_STATUS_OK) {
- // ERR_EXPLAIN("Error decoding WEBP image");
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
@@ -139,8 +136,7 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
}
dst_w.release();
- //ERR_EXPLAIN("Error decoding webp!");
- ERR_FAIL_COND_V(errdec, ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V_MSG(errdec, ERR_FILE_CORRUPT, "Failed decoding WebP image.");
p_image->create(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index 0c4e54df09..5a5c038017 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ImageLoaderWEBP : public ImageFormatLoader {
public:
diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp
index 58b68d926b..6f97842064 100644
--- a/modules/webrtc/register_types.cpp
+++ b/modules/webrtc/register_types.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "register_types.h"
+#include "core/project_settings.h"
#include "webrtc_data_channel.h"
#include "webrtc_peer_connection.h"
@@ -43,6 +44,12 @@
#include "webrtc_multiplayer.h"
void register_webrtc_types() {
+#define _SET_HINT(NAME, _VAL_, _MAX_) \
+ GLOBAL_DEF(NAME, _VAL_); \
+ ProjectSettings::get_singleton()->set_custom_property_info(NAME, PropertyInfo(Variant::INT, NAME, PROPERTY_HINT_RANGE, "2," #_MAX_ ",1,or_greater"));
+
+ _SET_HINT(WRTC_IN_BUF, 64, 4096);
+
#ifdef JAVASCRIPT_ENABLED
WebRTCPeerConnectionJS::make_default();
#elif defined(WEBRTC_GDNATIVE_ENABLED)
diff --git a/modules/webrtc/webrtc_data_channel.cpp b/modules/webrtc/webrtc_data_channel.cpp
index 2bd30e68f5..7b3843410a 100644
--- a/modules/webrtc/webrtc_data_channel.cpp
+++ b/modules/webrtc/webrtc_data_channel.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "webrtc_data_channel.h"
+#include "core/project_settings.h"
void WebRTCDataChannel::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &WebRTCDataChannel::poll);
@@ -58,6 +59,7 @@ void WebRTCDataChannel::_bind_methods() {
}
WebRTCDataChannel::WebRTCDataChannel() {
+ _in_buffer_shift = nearest_shift((int)GLOBAL_GET(WRTC_IN_BUF) - 1) + 10;
}
WebRTCDataChannel::~WebRTCDataChannel() {
diff --git a/modules/webrtc/webrtc_data_channel.h b/modules/webrtc/webrtc_data_channel.h
index 0b161da784..7e2c08d9d7 100644
--- a/modules/webrtc/webrtc_data_channel.h
+++ b/modules/webrtc/webrtc_data_channel.h
@@ -33,6 +33,8 @@
#include "core/io/packet_peer.h"
+#define WRTC_IN_BUF "network/limits/webrtc/max_channel_in_buffer_kb"
+
class WebRTCDataChannel : public PacketPeer {
GDCLASS(WebRTCDataChannel, PacketPeer);
@@ -50,6 +52,8 @@ public:
};
protected:
+ unsigned int _in_buffer_shift;
+
static void _bind_methods();
public:
diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp
index 069918cc9c..2edd212a50 100644
--- a/modules/webrtc/webrtc_data_channel_js.cpp
+++ b/modules/webrtc/webrtc_data_channel_js.cpp
@@ -56,7 +56,7 @@ EMSCRIPTEN_KEEPALIVE void _emrtc_on_ch_message(void *obj, uint8_t *p_data, uint3
}
void WebRTCDataChannelJS::_on_open() {
- in_buffer.resize(16);
+ in_buffer.resize(_in_buffer_shift);
}
void WebRTCDataChannelJS::_on_close() {
@@ -68,10 +68,8 @@ void WebRTCDataChannelJS::_on_error() {
}
void WebRTCDataChannelJS::_on_message(uint8_t *p_data, uint32_t p_size, bool p_is_string) {
- if (in_buffer.space_left() < (int)(p_size + 5)) {
- ERR_EXPLAIN("Buffer full! Dropping data");
- ERR_FAIL();
- }
+
+ ERR_FAIL_COND_MSG(in_buffer.space_left() < (int)(p_size + 5), "Buffer full! Dropping data.");
uint8_t is_string = p_is_string ? 1 : 0;
in_buffer.write((uint8_t *)&p_size, 4);
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp
index 17dafff93a..a759b17b83 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer.cpp
@@ -321,10 +321,8 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
if (target_peer > 0) {
E = peer_map.find(target_peer);
- if (!E) {
- ERR_EXPLAIN("Invalid Target Peer: " + itos(target_peer));
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer: " + itos(target_peer) + ".");
+
ERR_FAIL_COND_V(E->value()->channels.size() <= ch, ERR_BUG);
ERR_FAIL_COND_V(!E->value()->channels[ch].is_valid(), ERR_BUG);
return E->value()->channels[ch]->put_packet(p_buffer, p_buffer_size);
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.cpp b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
index af98aa750a..5e9dcb5366 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.cpp
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
@@ -51,13 +51,11 @@ Error WebRTCPeerConnectionGDNative::set_default_library(const godot_net_webrtc_l
WebRTCPeerConnection *WebRTCPeerConnectionGDNative::_create() {
WebRTCPeerConnectionGDNative *obj = memnew(WebRTCPeerConnectionGDNative);
- ERR_EXPLAIN("Default GDNative WebRTC implementation not defined.");
- ERR_FAIL_COND_V(!default_library, obj);
+ ERR_FAIL_COND_V_MSG(!default_library, obj, "Default GDNative WebRTC implementation not defined.");
// Call GDNative constructor
Error err = (Error)default_library->create_peer_connection(obj);
- ERR_EXPLAIN("GDNative default library constructor returned an error");
- ERR_FAIL_COND_V(err != OK, obj);
+ ERR_FAIL_COND_V_MSG(err != OK, obj, "GDNative default library constructor returned an error.");
return obj;
}
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index a9f38f1a82..58d4c52688 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -131,14 +131,12 @@ void EMWSPeer::close(int p_code, String p_reason) {
IP_Address EMWSPeer::get_connected_host() const {
- ERR_EXPLAIN("Not supported in HTML5 export");
- ERR_FAIL_V(IP_Address());
+ ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
};
uint16_t EMWSPeer::get_connected_port() const {
- ERR_EXPLAIN("Not supported in HTML5 export");
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
};
EMWSPeer::EMWSPeer() {
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index e24cb850ec..dd86c758bf 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -98,16 +98,14 @@ void WebSocketMultiplayerPeer::_bind_methods() {
//
int WebSocketMultiplayerPeer::get_available_packet_count() const {
- ERR_EXPLAIN("Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
return _incoming_packets.size();
}
Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_EXPLAIN("Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
r_buffer_size = 0;
@@ -127,8 +125,7 @@ Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buff
Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_EXPLAIN("Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
PoolVector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
@@ -160,8 +157,7 @@ void WebSocketMultiplayerPeer::set_target_peer(int p_target_peer) {
int WebSocketMultiplayerPeer::get_packet_peer() const {
- ERR_EXPLAIN("This function is not available when not using the MultiplayerAPI.");
- ERR_FAIL_COND_V(!_is_multiplayer, 1);
+ ERR_FAIL_COND_V_MSG(!_is_multiplayer, 1, "This function is not available when not using the MultiplayerAPI.");
ERR_FAIL_COND_V(_incoming_packets.size() == 0, 1);
return _incoming_packets.front()->get().source;
@@ -269,7 +265,10 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons
ERR_FAIL_COND_V(p_to == p_from, FAILED);
- return get_peer(p_to)->put_packet(p_buffer, p_buffer_size); // Sending to specific peer
+ Ref<WebSocketPeer> peer_to = get_peer(p_to);
+ ERR_FAIL_COND_V(peer_to.is_null(), FAILED);
+
+ return peer_to->put_packet(p_buffer, p_buffer_size); // Sending to specific peer
}
}
@@ -300,8 +299,6 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
ERR_FAIL_COND(type != SYS_NONE); // Only server sends sys messages
ERR_FAIL_COND(from != p_peer_id); // Someone is cheating
- _server_relay(from, to, in_buffer, size); // Relay if needed
-
if (to == 1) { // This is for the server
_store_pkt(from, to, in_buffer, data_size);
@@ -316,13 +313,9 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
// All but one, for us if not excluded
if (_peer_id != -(int32_t)p_peer_id)
_store_pkt(from, to, in_buffer, data_size);
-
- } else {
-
- // Send to specific peer
- ERR_FAIL_COND(!_peer_map.has(to));
- get_peer(to)->put_packet(in_buffer, size);
}
+ // Relay if needed (i.e. "to" includes a peer that is not the server)
+ _server_relay(from, to, in_buffer, size);
} else {
@@ -354,8 +347,7 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
_peer_id = id;
break;
default:
- ERR_EXPLAIN("Invalid multiplayer message");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid multiplayer message.");
break;
}
}
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index 86374e8f80..0006a057e0 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -53,8 +53,7 @@ void WSLClient::_do_handshake() {
// Header is too big
disconnect_from_host();
_on_error();
- ERR_EXPLAIN("Response headers too big");
- ERR_FAIL();
+ ERR_FAIL_MSG("Response headers too big.");
}
Error err = _connection->get_partial_data(&_resp_buf[_resp_pos], 1, read);
if (err == ERR_FILE_EOF) {
@@ -81,8 +80,7 @@ void WSLClient::_do_handshake() {
if (!_verify_headers(protocol)) {
disconnect_from_host();
_on_error();
- ERR_EXPLAIN("Invalid response headers");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid response headers.");
}
// Create peer.
WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData);
@@ -103,29 +101,18 @@ 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);
- }
+ ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
Vector<String> req = psa[0].split(" ", false);
- if (req.size() < 2) {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
+
// Wrong protocol
- if (req[0] != "HTTP/1.1" || req[1] != "101") {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req[0] != "HTTP/1.1" || req[1] != "101", false, "Invalid protocol or status code.");
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);
- }
+ ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i] + ".");
String name = header[0].to_lower();
String value = header[1].strip_edges();
if (headers.has(name))
@@ -134,17 +121,17 @@ bool WSLClient::_verify_headers(String &r_protocol) {
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));
+#define _WSL_CHECK(NAME, VALUE) \
+ ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \
+ "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
+#define _WSL_CHECK_NC(NAME, VALUE) \
+ ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME] != VALUE, false, \
+ "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
+ _WSL_CHECK("connection", "upgrade");
+ _WSL_CHECK("upgrade", "websocket");
+ _WSL_CHECK_NC("sec-websocket-accept", WSLPeer::compute_key_response(_key));
+#undef _WSL_CHECK_NC
+#undef _WSL_CHECK
if (_protocols.size() == 0) {
// We didn't request a custom protocol
ERR_FAIL_COND_V(headers.has("sec-websocket-protocol"), false);
@@ -161,10 +148,6 @@ bool WSLClient::_verify_headers(String &r_protocol) {
if (!valid)
return false;
}
-#undef _WLS_CHECK_NC
-#undef _WLS_CHECK
-#undef _WLS_EXPLAIN
-
return true;
}
@@ -190,8 +173,8 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
Error err = _tcp->connect_to_host(addr, p_port);
if (err != OK) {
- _on_error();
_tcp->disconnect_from_host();
+ _on_error();
return err;
}
_connection = _tcp;
@@ -230,8 +213,8 @@ 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();
+ _on_disconnect(_peer->close_code != -1);
}
return;
}
@@ -242,8 +225,8 @@ void WSLClient::poll() {
switch (_tcp->get_status()) {
case StreamPeerTCP::STATUS_NONE:
// Clean close
- _on_error();
disconnect_from_host();
+ _on_error();
break;
case StreamPeerTCP::STATUS_CONNECTED: {
Ref<StreamPeerSSL> ssl;
@@ -251,12 +234,11 @@ void WSLClient::poll() {
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());
+ ERR_FAIL_COND_MSG(ssl.is_null(), "SSL is not available in this build.");
ssl->set_blocking_handshake_enabled(false);
if (ssl->connect_to_stream(_tcp, verify_ssl, _host) != OK) {
- _on_error();
disconnect_from_host();
+ _on_error();
return;
}
_connection = ssl;
@@ -268,8 +250,8 @@ void WSLClient::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();
+ _on_error();
return; // Error.
}
}
@@ -277,8 +259,8 @@ void WSLClient::poll() {
_do_handshake();
} break;
case StreamPeerTCP::STATUS_ERROR:
- _on_error();
disconnect_from_host();
+ _on_error();
break;
case StreamPeerTCP::STATUS_CONNECTING:
break; // Wait for connection
@@ -332,8 +314,7 @@ uint16_t WSLClient::get_connected_port() const {
}
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);
+ ERR_FAIL_COND_V_MSG(_connection.is_valid(), FAILED, "Buffers sizes can only be set before listening or connecting.");
_in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
_in_pkt_size = nearest_shift(p_in_packets - 1);
diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp
index b11bd2b70f..74fb901232 100644
--- a/modules/websocket/wsl_peer.cpp
+++ b/modules/websocket/wsl_peer.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* lws_peer.cpp */
+/* wsl_peer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -35,7 +35,7 @@
#include "wsl_client.h"
#include "wsl_server.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/math/random_number_generator.h"
#include "core/os/os.h"
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 0d09a4d74e..efb526eed1 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* lws_server.cpp */
+/* wsl_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -45,29 +45,18 @@ WSLServer::PendingPeer::PendingPeer() {
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);
- }
+ ERR_FAIL_COND_V_MSG(len < 4, false, "Not enough response headers, got: " + itos(len) + ", expected >= 4.");
Vector<String> req = psa[0].split(" ", false);
- if (req.size() < 2) {
- ERR_EXPLAIN("Invalid protocol or status code.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req.size() < 2, false, "Invalid protocol or status code.");
+
// Wrong protocol
- if (req[0] != "GET" || req[2] != "HTTP/1.1") {
- ERR_EXPLAIN("Invalid method or HTTP version.");
- ERR_FAIL_V(false);
- }
+ ERR_FAIL_COND_V_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", false, "Invalid method or HTTP version.");
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);
- }
+ ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i]);
String name = header[0].to_lower();
String value = header[1].strip_edges();
if (headers.has(name))
@@ -75,18 +64,17 @@ bool WSLServer::PendingPeer::_parse_request(const PoolStringArray p_protocols) {
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
+#define _WSL_CHECK(NAME, VALUE) \
+ ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \
+ "Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'.");
+#define _WSL_CHECK_EX(NAME) \
+ ERR_FAIL_COND_V_MSG(!headers.has(NAME), false, "Missing header '" + String(NAME) + "'.");
+ _WSL_CHECK("upgrade", "websocket");
+ _WSL_CHECK("sec-websocket-version", "13");
+ _WSL_CHECK_EX("sec-websocket-key");
+ _WSL_CHECK_EX("connection");
+#undef _WSL_CHECK_EX
+#undef _WSL_CHECK
key = headers["sec-websocket-key"];
if (headers.has("sec-websocket-protocol")) {
Vector<String> protos = headers["sec-websocket-protocol"].split(",");
@@ -115,11 +103,7 @@ Error WSLServer::PendingPeer::do_handshake(PoolStringArray p_protocols) {
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);
- }
+ ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "Response headers too big.");
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
if (err != OK) // Got an error
return FAILED;
@@ -277,8 +261,7 @@ void WSLServer::disconnect_peer(int p_peer_id, int p_code, String 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);
+ ERR_FAIL_COND_V_MSG(_server->is_listening(), FAILED, "Buffers sizes can only be set before listening or connecting.");
_in_buf_size = nearest_shift(p_in_buffer - 1) + 10;
_in_pkt_size = nearest_shift(p_in_packets - 1);
diff --git a/modules/xatlas_unwrap/SCsub b/modules/xatlas_unwrap/SCsub
index 50e3cb1551..b242fd4673 100644
--- a/modules/xatlas_unwrap/SCsub
+++ b/modules/xatlas_unwrap/SCsub
@@ -15,10 +15,6 @@ if env['builtin_xatlas']:
env_xatlas_unwrap.Prepend(CPPPATH=[thirdparty_dir])
- # upstream uses c++11
- if (not env.msvc):
- env_xatlas_unwrap.Append(CXXFLAGS="-std=c++11")
-
env_thirdparty = env_xatlas_unwrap.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index 903b57f017..65b3cf08f5 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -29,108 +29,85 @@
/*************************************************************************/
#include "register_types.h"
+
#include "core/error_macros.h"
+
#include "thirdparty/xatlas/xatlas.h"
#include <stdio.h>
#include <stdlib.h>
+
extern bool (*array_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);
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;
-
- vertex_ptr[i] = p_vertices[i];
- normal_ptr[i] = p_normals[i];
- }
+ xatlas::ChartOptions chart_options;
+ xatlas::PackOptions pack_options;
- 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.blockAlign = 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;
if (w == 0 || h == 0) {
- return false; //could not bake
+ return false; //could not bake because there is no area
}
- 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");
+ xatlas::Destroy(atlas);
+ printf("Done\n");
return true;
}
diff --git a/platform/SCsub b/platform/SCsub
index aa83154ee0..38bab59d74 100644
--- a/platform/SCsub
+++ b/platform/SCsub
@@ -3,7 +3,8 @@
from compat import open_utf8
Import('env')
-platform_sources = []
+
+env.platform_sources = []
# Register platform-exclusive APIs
reg_apis_inc = '#include "register_platform_apis.h"\n'
@@ -11,7 +12,7 @@ reg_apis = 'void register_platform_apis() {\n'
unreg_apis = 'void unregister_platform_apis() {\n'
for platform in env.platform_apis:
platform_dir = env.Dir(platform)
- platform_sources.append(platform_dir.File('api/api.cpp'))
+ env.add_source_files(env.platform_sources, platform + '/api/api.cpp')
reg_apis += '\tregister_' + platform + '_api();\n'
unreg_apis += '\tunregister_' + platform + '_api();\n'
reg_apis_inc += '#include "' + platform + '/api/api.h"\n'
@@ -25,7 +26,7 @@ with open_utf8('register_platform_apis.gen.cpp', 'w') as f:
f.write(reg_apis)
f.write(unreg_apis)
-platform_sources.append('register_platform_apis.gen.cpp')
+env.add_source_files(env.platform_sources, 'register_platform_apis.gen.cpp')
-lib = env.add_library('platform', platform_sources)
-env.Prepend(LIBS=lib)
+lib = env.add_library('platform', env.platform_sources)
+env.Prepend(LIBS=[lib])
diff --git a/platform/android/SCsub b/platform/android/SCsub
index cf6752fa54..65172a12c0 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -1,13 +1,11 @@
#!/usr/bin/env python
-Import('env')
-
-from compat import open_utf8
-from distutils.version import LooseVersion
from detect import get_ndk_version
+from distutils.version import LooseVersion
-android_files = [
+Import('env')
+android_files = [
'os_android.cpp',
'file_access_android.cpp',
'audio_driver_opensl.cpp',
@@ -19,7 +17,7 @@ android_files = [
'java_class_wrapper.cpp',
'java_godot_wrapper.cpp',
'java_godot_io_wrapper.cpp',
-# 'power_android.cpp'
+ #'power_android.cpp'
]
env_android = env.Clone()
@@ -52,9 +50,8 @@ if lib_arch_dir != '':
else: # release_debug, debug
lib_type_dir = 'debug'
- out_dir = '#platform/android/java/libs/' + lib_type_dir + '/' + lib_arch_dir
+ out_dir = '#platform/android/java/lib/libs/' + lib_type_dir + '/' + lib_arch_dir
env_android.Command(out_dir + '/libgodot_android.so', '#bin/libgodot' + env['SHLIBSUFFIX'], Move("$TARGET", "$SOURCE"))
- ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
- stl_lib_path = str(env['ANDROID_NDK_ROOT']) + '/sources/cxx-stl/llvm-libc++/libs/' + lib_arch_dir + '/libc++_shared.so'
- env_android.Command(out_dir + '/libc++_shared.so', stl_lib_path, Copy("$TARGET", "$SOURCE"))
+
+ stl_lib_path = str(env['ANDROID_NDK_ROOT']) + '/sources/cxx-stl/llvm-libc++/libs/' + lib_arch_dir + '/libc++_shared.so'
+ env_android.Command(out_dir + '/libc++_shared.so', stl_lib_path, Copy("$TARGET", "$SOURCE"))
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index 1232fc7453..711088c158 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -97,17 +97,10 @@ Error AudioDriverOpenSL::init() {
{ (SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE }
};
res = slCreateEngine(&sl, 1, EngineOption, 0, NULL, NULL);
- if (res != SL_RESULT_SUCCESS) {
+ ERR_FAIL_COND_V_MSG(res != SL_RESULT_SUCCESS, ERR_INVALID_PARAMETER, "Could not initialize OpenSL.");
- ERR_EXPLAIN("Could not Initialize OpenSL");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
- if (res != SL_RESULT_SUCCESS) {
-
- ERR_EXPLAIN("Could not Realize OpenSL");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(res != SL_RESULT_SUCCESS, ERR_INVALID_PARAMETER, "Could not realize OpenSL.");
return OK;
}
@@ -215,8 +208,8 @@ void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf qu
for (int i = 0; i < rec_buffer.size(); i++) {
int32_t sample = rec_buffer[i] << 16;
- input_buffer_write(sample);
- input_buffer_write(sample); // call twice to convert to Stereo
+ capture_buffer_write(sample);
+ capture_buffer_write(sample); // call twice to convert to Stereo
}
SLresult res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t));
@@ -287,7 +280,7 @@ Error AudioDriverOpenSL::capture_init_device() {
const int rec_buffer_frames = 2048;
rec_buffer.resize(rec_buffer_frames);
- input_buffer_init(rec_buffer_frames);
+ capture_buffer_init(rec_buffer_frames);
res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t));
ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN);
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 3f179e3a65..8b62360888 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -28,19 +28,16 @@ def get_opts():
('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
EnumVariable('android_arch', 'Target architecture', "armv7", ('armv7', 'arm64v8', 'x86', 'x86_64')),
BoolVariable('android_neon', 'Enable NEON support (armv7 only)', True),
- BoolVariable('android_stl', 'Enable Android STL support (for modules)', True)
]
def get_flags():
-
return [
('tools', False),
]
def create(env):
-
tools = env['TOOLS']
if "mingw" in tools:
tools.remove('mingw')
@@ -51,7 +48,6 @@ def create(env):
def configure(env):
-
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
if (os.name == "nt"):
@@ -91,7 +87,7 @@ def configure(env):
env['SPAWN'] = mySpawn
- ## Architecture
+ # Architecture
if env['android_arch'] not in ['armv7', 'arm64v8', 'x86', 'x86_64']:
env['android_arch'] = 'armv7'
@@ -138,14 +134,14 @@ def configure(env):
arch_subpath = "arm64-v8a"
env.extra_suffix = ".armv8" + env.extra_suffix
- ## Build type
+ # Build type
if (env["target"].startswith("release")):
- if (env["optimize"] == "speed"): #optimize for speed (default)
+ if (env["optimize"] == "speed"): # optimize for speed (default)
env.Append(LINKFLAGS=['-O2'])
env.Append(CCFLAGS=['-O2', '-fomit-frame-pointer'])
env.Append(CPPDEFINES=['NDEBUG'])
- else: #optimize for size
+ else: # optimize for size
env.Append(CCFLAGS=['-Os'])
env.Append(CPPDEFINES=['NDEBUG'])
env.Append(LINKFLAGS=['-Os'])
@@ -160,7 +156,7 @@ def configure(env):
env.Append(CPPDEFINES=['_DEBUG', 'DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED'])
env.Append(CPPFLAGS=['-UNDEBUG'])
- ## Compiler configuration
+ # Compiler configuration
env['SHLIBSUFFIX'] = '.so'
@@ -205,31 +201,29 @@ def configure(env):
common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path]
- lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
+ # Compile flags
+
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
+ env.Append(CXXFLAGS=["-std=gnu++14"])
- ## Compile flags
# Disable exceptions and rtti on non-tools (template) builds
- if env['tools'] or env['android_stl']:
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
- env.Append(CXXFLAGS=['-frtti', "-std=gnu++14"])
+ if env['tools']:
+ env.Append(CXXFLAGS=['-frtti'])
else:
env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions'])
# Don't use dynamic_cast, necessary with no-rtti.
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"):
- print("Using NDK unified headers")
- sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
- env.Append(CPPFLAGS=["--sysroot=" + sysroot])
- 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(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))])
- else:
- print("Using NDK deprecated headers")
- env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"])
+ lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
+
+ # Using NDK unified headers (NDK r15+)
+ sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
+ env.Append(CPPFLAGS=["--sysroot=" + sysroot])
+ 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(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))])
env.Append(CCFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split())
env.Append(CPPDEFINES=['NO_STATVFS', 'GLES_ENABLED'])
@@ -262,19 +256,16 @@ def configure(env):
env.Append(CCFLAGS=target_opts)
env.Append(CCFLAGS=common_opts)
- ## Link flags
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
- if LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
- env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a', '-Wl,--exclude-libs,libatomic.a', '-nostdlib++'])
- else:
- env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"])
- env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
- env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"])
+ # Link flags
+
+ ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
+ if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
+ env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a', '-Wl,--exclude-libs,libatomic.a', '-nostdlib++'])
else:
- env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
- if mt_link:
- env.Append(LINKFLAGS=['-Wl,--threads'])
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"])
+ env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"])
if env["android_arch"] == "armv7":
env.Append(LINKFLAGS='-Wl,--fix-cortex-a8'.split())
@@ -293,6 +284,7 @@ def configure(env):
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).
def get_ndk_version(path):
if path is None:
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 1b9d31d752..b37f04c4f8 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -32,6 +32,7 @@
#include "core/io/marshalls.h"
#include "core/io/zip_io.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@@ -725,8 +726,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
uint32_t string_at = decode_uint32(&p_manifest[st_offset + i * 4]);
string_at += st_offset + string_count * 4;
- ERR_EXPLAIN("Unimplemented, can't read utf8 string table.");
- ERR_FAIL_COND(string_flags & UTF8_FLAG);
+ ERR_FAIL_COND_MSG(string_flags & UTF8_FLAG, "Unimplemented, can't read UTF-8 string table.");
if (string_flags & UTF8_FLAG) {
@@ -794,6 +794,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
string_table.write[attr_value] = version_name;
}
+ if (tname == "instrumentation" && attrname == "targetPackage") {
+ string_table.write[attr_value] = get_package_name(package_name);
+ }
+
if (tname == "activity" && attrname == "screenOrientation") {
encode_uint32(orientation == 0 ? 0 : 1, &p_manifest.write[iofs + 16]);
@@ -847,6 +851,136 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
String tname = string_table[name];
+ int dof_index = p_preset->get("graphics/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof
+
+ if (tname == "uses-feature" && dof_index > 0) {
+ if (xr_mode_index == 0) {
+ WARN_PRINT("VR DOF feature setting is only valid for oculus HMDs with an XR mode set to VR");
+ }
+ ofs += 24; // skip over end tag
+
+ // save manifest ending so we can restore it
+ Vector<uint8_t> manifest_end;
+ uint32_t manifest_cur_size = p_manifest.size();
+
+ manifest_end.resize(p_manifest.size() - ofs);
+ memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
+
+ int32_t attr_name_string = string_table.find("name");
+ ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute.");
+
+ int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android");
+ if (ns_android_string == -1) {
+ string_table.push_back("http://schemas.android.com/apk/res/android");
+ ns_android_string = string_table.size() - 1;
+ }
+
+ int32_t attr_uses_permission_string = string_table.find("uses-feature");
+ if (attr_uses_permission_string == -1) {
+ string_table.push_back("uses-feature");
+ attr_uses_permission_string = string_table.size() - 1;
+ }
+
+ int32_t attr_required_string = string_table.find("required");
+ if (attr_required_string == -1) {
+ string_table.push_back("required");
+ attr_required_string = string_table.size() - 1;
+ }
+
+ int32_t attr_version_string = string_table.find("version");
+ if (attr_version_string == -1) {
+ string_table.push_back("version");
+ attr_version_string = string_table.size() - 1;
+ }
+
+ String required_value_string;
+ if (dof_index == 1) {
+ required_value_string = "false";
+ } else if (dof_index == 2) {
+ required_value_string = "true";
+ } else {
+ ERR_FAIL_MSG("Unknown DoF index: " + itos(dof_index) + ".");
+ }
+ int32_t required_value = string_table.find(required_value_string);
+ if (required_value == -1) {
+ string_table.push_back(required_value_string);
+ required_value = string_table.size() - 1;
+ }
+
+ int32_t version_value = string_table.find("1");
+ if (version_value == -1) {
+ string_table.push_back("1");
+ version_value = string_table.size() - 1;
+ }
+
+ int32_t feature_string = string_table.find("android.hardware.vr.headtracking");
+ if (feature_string == -1) {
+ string_table.push_back("android.hardware.vr.headtracking");
+ feature_string = string_table.size() - 1;
+ }
+
+ {
+ manifest_cur_size += 96 + 20; // node and three attrs + end node
+ p_manifest.resize(manifest_cur_size);
+
+ // start tag
+ encode_uint16(0x102, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(96, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
+ encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
+ encode_uint16(3, &p_manifest.write[ofs + 28]); // num_attrs
+ encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index
+ encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index
+ encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index
+
+ // android:name attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns
+ encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name'
+ encode_uint32(feature_string, &p_manifest.write[ofs + 44]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size
+ p_manifest.write[ofs + 50] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string)
+ encode_uint32(feature_string, &p_manifest.write[ofs + 52]); // typedvalue reference
+
+ // android:required attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns
+ encode_uint32(attr_required_string, &p_manifest.write[ofs + 60]); // 'name'
+ encode_uint32(required_value, &p_manifest.write[ofs + 64]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size
+ p_manifest.write[ofs + 70] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string)
+ encode_uint32(required_value, &p_manifest.write[ofs + 72]); // typedvalue reference
+
+ // android:version attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 76]); // ns
+ encode_uint32(attr_version_string, &p_manifest.write[ofs + 80]); // 'name'
+ encode_uint32(version_value, &p_manifest.write[ofs + 84]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 88]); // typedvalue_size
+ p_manifest.write[ofs + 90] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 91] = 0x03; // typedvalue_type (string)
+ encode_uint32(version_value, &p_manifest.write[ofs + 92]); // typedvalue reference
+
+ ofs += 96;
+
+ // end tag
+ encode_uint16(0x103, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(24, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+
+ ofs += 24;
+ }
+ memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size());
+ ofs -= 24; // go back over back end
+ }
if (tname == "manifest") {
// save manifest ending so we can restore it
@@ -857,12 +991,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
int32_t attr_name_string = string_table.find("name");
- ERR_EXPLAIN("Template does not have 'name' attribute");
- ERR_FAIL_COND(attr_name_string == -1);
+ ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute.");
int32_t ns_android_string = string_table.find("android");
- ERR_EXPLAIN("Template does not have 'android' namespace");
- ERR_FAIL_COND(ns_android_string == -1);
+ ERR_FAIL_COND_MSG(ns_android_string == -1, "Template does not have 'android' namespace.");
int32_t attr_uses_permission_string = string_table.find("uses-permission");
if (attr_uses_permission_string == -1) {
@@ -1156,6 +1288,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::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 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"), ""));
@@ -1175,7 +1308,7 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/opengl_debug"), false));
- for (unsigned int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
}
@@ -1270,8 +1403,9 @@ public:
return ERR_UNCONFIGURED;
}
- //export_temp
+ // Export_temp APK.
if (ep.step("Exporting APK", 0)) {
+ device_lock->unlock();
return ERR_SKIP;
}
@@ -1281,11 +1415,20 @@ public:
if (use_reverse)
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
- String export_to = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
- Error err = export_project(p_preset, true, export_to, p_debug_flags);
- if (err) {
- device_lock->unlock();
- return err;
+ String tmp_export_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
+
+#define CLEANUP_AND_RETURN(m_err) \
+ { \
+ DirAccess::remove_file_or_error(tmp_export_path); \
+ device_lock->unlock(); \
+ return m_err; \
+ }
+
+ // Export to temporary APK before sending to device.
+ Error err = export_project(p_preset, true, tmp_export_path, p_debug_flags);
+
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
}
List<String> args;
@@ -1297,7 +1440,7 @@ public:
if (remove_prev) {
if (ep.step("Uninstalling...", 1)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
print_line("Uninstalling previous version: " + devices[p_device].name);
@@ -1312,7 +1455,7 @@ public:
print_line("Installing to device (please wait...): " + devices[p_device].name);
if (ep.step("Installing to device (please wait...)", 2)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
@@ -1320,20 +1463,19 @@ public:
args.push_back(devices[p_device].id);
args.push_back("install");
args.push_back("-r");
- args.push_back(export_to);
+ args.push_back(tmp_export_path);
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
if (use_remote) {
if (use_reverse) {
- static const char *const msg = "** Device API >= 21; debugging over USB **";
- EditorNode::get_singleton()->get_log()->add_message(msg);
+ static const char *const msg = "--- Device API >= 21; debugging over USB ---";
+ EditorNode::get_singleton()->get_log()->add_message(msg, EditorLog::MSG_TYPE_EDITOR);
print_line(String(msg).to_upper());
args.clear();
@@ -1373,14 +1515,14 @@ public:
}
} else {
- static const char *const msg = "** Device API < 21; debugging over Wi-Fi **";
- EditorNode::get_singleton()->get_log()->add_message(msg);
+ static const char *const msg = "--- Device API < 21; debugging over Wi-Fi ---";
+ EditorNode::get_singleton()->get_log()->add_message(msg, EditorLog::MSG_TYPE_EDITOR);
print_line(String(msg).to_upper());
}
}
if (ep.step("Running on Device...", 3)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
args.push_back("-s");
@@ -1395,16 +1537,16 @@ public:
args.push_back("-a");
args.push_back("android.intent.action.MAIN");
args.push_back("-n");
- args.push_back(get_package_name(package_name) + "/org.godotengine.godot.Godot");
+ args.push_back(get_package_name(package_name) + "/com.godot.game.GodotApp");
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not execute on device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
- device_lock->unlock();
- return OK;
+
+ CLEANUP_AND_RETURN(OK);
+#undef CLEANUP_AND_RETURN
}
virtual Ref<Texture> get_run_icon() const {
@@ -1472,19 +1614,16 @@ public:
valid = false;
} else {
Error errn;
- DirAccess *da = DirAccess::open(sdk_path.plus_file("tools"), &errn);
+ DirAccessRef da = DirAccess::open(sdk_path.plus_file("tools"), &errn);
if (errn != OK) {
err += TTR("Invalid Android SDK path for custom build in Editor Settings.") + "\n";
valid = false;
}
- if (da) {
- memdelete(da);
- }
}
if (!FileAccess::exists("res://android/build/build.gradle")) {
- err += TTR("Android project is not installed for compiling. Install from Editor menu.") + "\n";
+ err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
valid = false;
}
}
@@ -1895,8 +2034,16 @@ public:
zlib_filefunc_def io2 = io;
FileAccess *dst_f = NULL;
io2.opaque = &dst_f;
- String unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk");
- zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
+
+ String tmp_unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk");
+
+#define CLEANUP_AND_RETURN(m_err) \
+ { \
+ DirAccess::remove_file_or_error(tmp_unaligned_path); \
+ return m_err; \
+ }
+
+ zipFile unaligned_apk = zipOpen2(tmp_unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
@@ -1953,7 +2100,7 @@ public:
if (file == "res/drawable-nodpi-v4/icon.png") {
bool found = false;
- for (unsigned int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges();
if (icon_path != "" && icon_path.ends_with(".png")) {
FileAccess *f = FileAccess::open(icon_path, FileAccess::READ);
@@ -2024,7 +2171,7 @@ public:
}
if (ep.step("Adding Files...", 1)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
Error err = OK;
Vector<String> cl = cmdline.strip_edges().split(" ");
@@ -2056,7 +2203,7 @@ public:
unzClose(pkg);
EditorNode::add_io_error("Could not write expansion package file: " + apkfname);
- return OK;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
cl.push_back("--use_apk_expansion");
@@ -2079,7 +2226,7 @@ public:
APKExportData ed;
ed.ep = &ep;
ed.apk = unaligned_apk;
- for (unsigned int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges();
if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) {
Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path);
@@ -2143,8 +2290,8 @@ public:
zipClose(unaligned_apk, NULL);
unzClose(pkg);
- if (err) {
- return err;
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
}
if (_signed) {
@@ -2152,7 +2299,7 @@ public:
String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner");
if (!FileAccess::exists(jarsigner)) {
EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting APK is unsigned.");
- return OK;
+ CLEANUP_AND_RETURN(OK);
}
String keystore;
@@ -2172,7 +2319,7 @@ public:
}
if (ep.step("Signing debug APK...", 103)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
} else {
@@ -2181,13 +2328,13 @@ public:
user = release_username;
if (ep.step("Signing release APK...", 103)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
}
if (!FileAccess::exists(keystore)) {
EditorNode::add_io_error("Could not find keystore, unable to export.");
- return ERR_FILE_CANT_OPEN;
+ CLEANUP_AND_RETURN(ERR_FILE_CANT_OPEN);
}
List<String> args;
@@ -2205,30 +2352,30 @@ public:
args.push_back(keystore);
args.push_back("-storepass");
args.push_back(password);
- args.push_back(unaligned_path);
+ args.push_back(tmp_unaligned_path);
args.push_back(user);
int retval;
OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
if (retval) {
EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval));
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
if (ep.step("Verifying APK...", 104)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
args.clear();
args.push_back("-verify");
args.push_back("-keystore");
args.push_back(keystore);
- args.push_back(unaligned_path);
+ args.push_back(tmp_unaligned_path);
args.push_back("-verbose");
OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
if (retval) {
EditorNode::add_io_error("'jarsigner' verification of APK failed. Make sure to use a jarsigner from OpenJDK 8.");
- return ERR_CANT_CREATE;
+ CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
}
@@ -2237,14 +2384,14 @@ public:
static const int ZIP_ALIGNMENT = 4;
if (ep.step("Aligning APK...", 105)) {
- return ERR_SKIP;
+ CLEANUP_AND_RETURN(ERR_SKIP);
}
- unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io);
+ unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
- EditorNode::add_io_error("Could not find temp unaligned APK.");
- return ERR_FILE_NOT_FOUND;
+ EditorNode::add_io_error("Could not unzip temporary unaligned APK.");
+ CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
ret = unzGoToFirstFile(tmp_unaligned);
@@ -2314,7 +2461,7 @@ public:
zipClose(final_apk, NULL);
unzClose(tmp_unaligned);
- return OK;
+ CLEANUP_AND_RETURN(OK);
}
virtual void get_platform_features(List<String> *r_features) {
@@ -2367,7 +2514,7 @@ void register_android_exporter() {
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);
EDITOR_DEF("export/android/custom_build_sdk_path", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/custom_build_sdk_path", PROPERTY_HINT_GLOBAL_DIR, "*.keystore"));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/custom_build_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
EDITOR_DEF("export/android/timestamping_authority_url", "");
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
diff --git a/platform/android/java/AndroidManifest.xml b/platform/android/java/AndroidManifest.xml
deleted file mode 100644
index 3152ef12cd..0000000000
--- a/platform/android/java/AndroidManifest.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.godot.game"
- android:versionCode="1"
- android:versionName="1.0"
- android:installLocation="auto"
- >
-<supports-screens android:smallScreens="true"
- android:normalScreens="true"
- android:largeScreens="true"
- android:xlargeScreens="true"/>
-
-<!--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/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-->
-<!--CHUNK_USER_PERMISSIONS_END-->
-
-<!--Anything in this line after the icon will be erased when doing custom build. If you want to add tags manually, do before it.-->
- <application android:label="@string/godot_project_name_string" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@drawable/icon">
-
-<!--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.Black.NoTitleBar.Fullscreen"
- android:launchMode="singleTask"
- android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
- android:resizeableActivity="false"
- tools:ignore="UnusedAttribute">
-
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service android:name="org.godotengine.godot.GodotDownloaderService" />
-
-<!--Custom application XML added by add-ons-->
-<!--CHUNK_APPLICATION_BEGIN-->
-<!--CHUNK_APPLICATION_END-->
-
- </application>
-
- <instrumentation android:icon="@drawable/icon"
- android:label="@string/godot_project_name_string"
- android:name="org.godotengine.godot.GodotInstrumentation"
- android:targetPackage="org.godotengine.game" />
-
-</manifest>
diff --git a/platform/android/java/README.md b/platform/android/java/README.md
deleted file mode 100644
index 58d2b10706..0000000000
--- a/platform/android/java/README.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Third party libraries
-
-
-## Google's vending library
-
-- Upstream: https://github.com/google/play-licensing/tree/master/lvl_library/src/main/java/com/google/android/vending
-- Version: git (eb57657, 2018) with modifications
-- License: Apache 2.0
-
-Overwrite all files under `com/google/android/vending`
-
-### Modify some files to avoid compile error and lint warning
-
-#### com/google/android/vending/licensing/util/Base64.java
-```
-@@ -338,7 +338,8 @@ public class Base64 {
- e += 4;
- }
-
-- assert (e == outBuff.length);
-+ if (BuildConfig.DEBUG && e != outBuff.length)
-+ throw new RuntimeException();
- return outBuff;
- }
-```
-
-#### com/google/android/vending/licensing/LicenseChecker.java
-```
-@@ -29,8 +29,8 @@ import android.os.RemoteException;
- import android.provider.Settings.Secure;
- import android.util.Log;
-
--import com.android.vending.licensing.ILicenseResultListener;
--import com.android.vending.licensing.ILicensingService;
-+import com.google.android.vending.licensing.ILicenseResultListener;
-+import com.google.android.vending.licensing.ILicensingService;
- import com.google.android.vending.licensing.util.Base64;
- import com.google.android.vending.licensing.util.Base64DecoderException;
-```
-```
-@@ -287,13 +287,15 @@ public class LicenseChecker implements ServiceConnection {
- if (logResponse) {
-- String android_id = Secure.getString(mContext.getContentResolver(),
-- Secure.ANDROID_ID);
-+ String android_id = Secure.ANDROID_ID;
- Date date = new Date();
-```
diff --git a/platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl b/platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
deleted file mode 100644
index 2a492f7845..0000000000
--- a/platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.vending.billing;
-
-import android.os.Bundle;
-
-/**
- * InAppBillingService is the service that provides in-app billing version 3 and beyond.
- * This service provides the following features:
- * 1. Provides a new API to get details of in-app items published for the app including
- * price, type, title and description.
- * 2. The purchase flow is synchronous and purchase information is available immediately
- * after it completes.
- * 3. Purchase information of in-app purchases is maintained within the Google Play system
- * till the purchase is consumed.
- * 4. An API to consume a purchase of an inapp item. All purchases of one-time
- * in-app items are consumable and thereafter can be purchased again.
- * 5. An API to get current purchases of the user immediately. This will not contain any
- * consumed purchases.
- *
- * All calls will give a response code with the following possible values
- * RESULT_OK = 0 - success
- * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog
- * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested
- * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase
- * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API
- * RESULT_ERROR = 6 - Fatal error during the API action
- * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
- * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
- */
-interface IInAppBillingService {
- /**
- * Checks support for the requested billing API version, package and in-app type.
- * Minimum API version supported by this interface is 3.
- * @param apiVersion the billing version which the app is using
- * @param packageName the package name of the calling app
- * @param type type of the in-app item being purchased "inapp" for one-time purchases
- * and "subs" for subscription.
- * @return RESULT_OK(0) on success, corresponding result code on failures
- */
- int isBillingSupported(int apiVersion, String packageName, String type);
-
- /**
- * Provides details of a list of SKUs
- * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
- * with a list JSON strings containing the productId, price, title and description.
- * This API can be called with a maximum of 20 SKUs.
- * @param apiVersion billing API version that the Third-party is using
- * @param packageName the package name of the calling app
- * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "DETAILS_LIST" with a StringArrayList containing purchase information
- * in JSON format similar to:
- * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00",
- * "title : "Example Title", "description" : "This is an example description" }'
- */
- Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
-
- /**
- * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
- * the type, a unique purchase token and an optional developer payload.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param sku the SKU of the in-app item as published in the developer console
- * @param type the type of the in-app item ("inapp" for one-time purchases
- * and "subs" for subscription).
- * @param developerPayload optional argument to be sent back with the purchase information
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "BUY_INTENT" - PendingIntent to start the purchase flow
- *
- * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
- * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
- * If the purchase is successful, the result data will contain the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "INAPP_PURCHASE_DATA" - String in JSON format similar to
- * '{"orderId":"12999763169054705758.1371079406387615",
- * "packageName":"com.example.app",
- * "productId":"exampleSku",
- * "purchaseTime":1345678900000,
- * "purchaseToken" : "122333444455555",
- * "developerPayload":"example developer payload" }'
- * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
- * was signed with the private key of the developer
- * TODO: change this to app-specific keys.
- */
- Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
- String developerPayload);
-
- /**
- * Returns the current SKUs owned by the user of the type and package name specified along with
- * purchase information and a signature of the data to be validated.
- * This will return all SKUs that have been purchased in V3 and managed items purchased using
- * V1 and V2 that have not been consumed.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param type the type of the in-app items being requested
- * ("inapp" for one-time purchases and "subs" for subscription).
- * @param continuationToken to be set as null for the first call, if the number of owned
- * skus are too many, a continuationToken is returned in the response bundle.
- * This method can be called again with the continuation token to get the next set of
- * owned skus.
- * @return Bundle containing the following key-value pairs
- * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
- * failure as listed above.
- * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
- * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
- * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
- * of the purchase information
- * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
- * next set of in-app purchases. Only set if the
- * user has more owned skus than the current list.
- */
- Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
-
- /**
- * Consume the last purchase of the given SKU. This will result in this item being removed
- * from all subsequent responses to getPurchases() and allow re-purchase of this item.
- * @param apiVersion billing API version that the app is using
- * @param packageName package name of the calling app
- * @param purchaseToken token in the purchase information JSON that identifies the purchase
- * to be consumed
- * @return 0 if consumption succeeded. Appropriate error values for failures.
- */
- int consumePurchase(int apiVersion, String packageName, String purchaseToken);
-}
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
new file mode 100644
index 0000000000..d5f4ba18d6
--- /dev/null
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.godot.game"
+ android:versionCode="1"
+ android:versionName="1.0"
+ android:installLocation="auto" >
+
+ <!-- Adding custom text to the manifest is fine, but do it outside the custom USER and APPLICATION BEGIN/END comments, -->
+ <!-- as that gets rewritten. -->
+
+ <supports-screens
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:largeScreens="true"
+ android:xlargeScreens="true" />
+
+ <!-- glEsVersion is modified by the exporter, changing this value here has no effect. -->
+ <uses-feature
+ android:glEsVersion="0x00020000"
+ android:required="true" />
+
+<!-- Custom user permissions XML added by add-ons. It's recommended to add them from the export preset, though. -->
+<!--CHUNK_USER_PERMISSIONS_BEGIN-->
+<!--CHUNK_USER_PERMISSIONS_END-->
+
+ <!-- Any tag in this line after android:icon will be erased when doing custom builds. -->
+ <!-- If you want to add tags manually, do before it. -->
+ <application
+ android:label="@string/godot_project_name_string"
+ android:allowBackup="false"
+ tools:ignore="GoogleAppIndexingWarning"
+ android:icon="@drawable/icon" >
+
+ <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. -->
+ <!-- Do these changes in the export preset. Adding new ones is fine. -->
+
+ <!-- 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=".GodotApp"
+ android:label="@string/godot_project_name_string"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:screenOrientation="landscape"
+ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
+ android:resizeableActivity="false"
+ tools:ignore="UnusedAttribute" >
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+<!-- Custom application XML added by add-ons. -->
+<!--CHUNK_APPLICATION_BEGIN-->
+<!--CHUNK_APPLICATION_END-->
+
+ </application>
+
+</manifest>
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
new file mode 100644
index 0000000000..9f64c3dc8a
--- /dev/null
+++ b/platform/android/java/app/build.gradle
@@ -0,0 +1,121 @@
+// Gradle build config for Godot Engine's Android port.
+//
+// Do not remove/modify comments ending with BEGIN/END, they are used to inject
+// addon-specific configuration.
+apply from: 'config.gradle'
+
+buildscript {
+ apply from: 'config.gradle'
+
+ repositories {
+ google()
+ jcenter()
+//CHUNK_BUILDSCRIPT_REPOSITORIES_BEGIN
+//CHUNK_BUILDSCRIPT_REPOSITORIES_END
+ }
+ dependencies {
+ classpath libraries.androidGradlePlugin
+//CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN
+//CHUNK_BUILDSCRIPT_DEPENDENCIES_END
+ }
+}
+
+apply plugin: 'com.android.application'
+
+allprojects {
+ repositories {
+ mavenCentral()
+ google()
+ jcenter()
+//CHUNK_ALLPROJECTS_REPOSITORIES_BEGIN
+//CHUNK_ALLPROJECTS_REPOSITORIES_END
+ }
+}
+
+dependencies {
+ if (rootProject.findProject(":lib")) {
+ implementation project(":lib")
+ } else {
+ // Custom build mode. In this scenario this project is the only one around and the Godot
+ // library is available through the pre-generated godot-lib.*.aar android archive files.
+ debugImplementation fileTree(dir: 'libs/debug', include: ['*.jar', '*.aar'])
+ releaseImplementation fileTree(dir: 'libs/release', include: ['*.jar', '*.aar'])
+ }
+//CHUNK_DEPENDENCIES_BEGIN
+//CHUNK_DEPENDENCIES_END
+}
+
+android {
+ compileSdkVersion versions.compileSdk
+ buildToolsVersion versions.buildTools
+
+ defaultConfig {
+ // Feel free to modify the application id to your own.
+ applicationId "com.godot.game"
+ minSdkVersion versions.minSdk
+ targetSdkVersion versions.targetSdk
+//CHUNK_ANDROID_DEFAULTCONFIG_BEGIN
+//CHUNK_ANDROID_DEFAULTCONFIG_END
+ }
+
+ lintOptions {
+ abortOnError false
+ disable 'MissingTranslation', 'UnusedResources'
+ }
+
+ packagingOptions {
+ exclude 'META-INF/LICENSE'
+ exclude 'META-INF/NOTICE'
+ }
+
+ // Both signing and zip-aligning will be done at export time
+ buildTypes.all { buildType ->
+ buildType.zipAlignEnabled false
+ buildType.signingConfig null
+ }
+
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = [
+ 'src'
+//DIR_SRC_BEGIN
+//DIR_SRC_END
+ ]
+ res.srcDirs = [
+ 'res'
+//DIR_RES_BEGIN
+//DIR_RES_END
+ ]
+ aidl.srcDirs = [
+ 'aidl'
+//DIR_AIDL_BEGIN
+//DIR_AIDL_END
+ ]
+ assets.srcDirs = [
+ 'assets'
+//DIR_ASSETS_BEGIN
+//DIR_ASSETS_END
+ ]
+ }
+ debug.jniLibs.srcDirs = [
+ 'libs/debug'
+//DIR_JNI_DEBUG_BEGIN
+//DIR_JNI_DEBUG_END
+ ]
+ release.jniLibs.srcDirs = [
+ 'libs/release'
+//DIR_JNI_RELEASE_BEGIN
+//DIR_JNI_RELEASE_END
+ ]
+ }
+
+ applicationVariants.all { variant ->
+ variant.outputs.all { output ->
+ output.outputFileName = "android_${variant.name}.apk"
+ }
+ }
+}
+
+//CHUNK_GLOBAL_BEGIN
+//CHUNK_GLOBAL_END
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
new file mode 100644
index 0000000000..20c3123221
--- /dev/null
+++ b/platform/android/java/app/config.gradle
@@ -0,0 +1,12 @@
+ext.versions = [
+ androidGradlePlugin : '3.4.2',
+ compileSdk : 28,
+ minSdk : 18,
+ targetSdk : 28,
+ buildTools : '28.0.3',
+
+]
+
+ext.libraries = [
+ androidGradlePlugin : "com.android.tools.build:gradle:$versions.androidGradlePlugin"
+]
diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java
new file mode 100644
index 0000000000..fabd7b1dbb
--- /dev/null
+++ b/platform/android/java/app/src/com/godot/game/GodotApp.java
@@ -0,0 +1,10 @@
+package com.godot.game;
+
+import org.godotengine.godot.Godot;
+
+/**
+ * Template activity for Godot Android custom builds.
+ * Feel free to extend and modify this class for your custom logic.
+ */
+public class GodotApp extends Godot {
+}
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index c468277daa..99ffa937b0 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -1,113 +1,95 @@
-//Gradle project for Godot Engine Android port.
-//Do not modify code between the BEGIN/END sections, as it's autogenerated by add-ons
+apply from: 'app/config.gradle'
buildscript {
- repositories {
- google()
- jcenter()
-//CHUNK_BUILDSCRIPT_REPOSITORIES_BEGIN
-//CHUNK_BUILDSCRIPT_REPOSITORIES_END
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
-//CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN
-//CHUNK_BUILDSCRIPT_DEPENDENCIES_END
- }
-}
+ apply from: 'app/config.gradle'
-apply plugin: 'com.android.application'
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath libraries.androidGradlePlugin
+ }
+}
allprojects {
repositories {
- mavenCentral()
- google()
- jcenter()
-//CHUNK_ALLPROJECTS_REPOSITORIES_BEGIN
-//CHUNK_ALLPROJECTS_REPOSITORIES_END
-
+ google()
+ jcenter()
+ mavenCentral()
}
}
-dependencies {
- implementation "com.android.support:support-core-utils:28.0.0"
-//CHUNK_DEPENDENCIES_BEGIN
-//CHUNK_DEPENDENCIES_END
+def binDir = "../../../bin/"
+
+/**
+ * Copy the generated 'android_debug.apk' binary template into the Godot bin directory.
+ * Depends on the app build task to ensure the binary is generated prior to copying.
+ */
+task copyDebugBinaryToBin(type: Copy) {
+ dependsOn ':app:build'
+ from('app/build/outputs/apk/debug')
+ into(binDir)
+ include('android_debug.apk')
}
-android {
-
- lintOptions {
- abortOnError false
- disable 'MissingTranslation','UnusedResources'
- }
-
- compileSdkVersion 28
- buildToolsVersion "28.0.3"
- useLibrary 'org.apache.http.legacy'
-
- packagingOptions {
- exclude 'META-INF/LICENSE'
- exclude 'META-INF/NOTICE'
- }
- defaultConfig {
- minSdkVersion 18
- targetSdkVersion 28
-//CHUNK_ANDROID_DEFAULTCONFIG_BEGIN
-//CHUNK_ANDROID_DEFAULTCONFIG_END
- }
- // Both signing and zip-aligning will be done at export time
- buildTypes.all { buildType ->
- buildType.zipAlignEnabled false
- buildType.signingConfig null
- }
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src'
-//DIR_SRC_BEGIN
-//DIR_SRC_END
- ]
- res.srcDirs = [
- 'res'
-//DIR_RES_BEGIN
-//DIR_RES_END
- ]
- aidl.srcDirs = [
- 'aidl'
-//DIR_AIDL_BEGIN
-//DIR_AIDL_END
- ]
- assets.srcDirs = [
- 'assets'
-//DIR_ASSETS_BEGIN
-//DIR_ASSETS_END
-
- ]
- }
- debug.jniLibs.srcDirs = [
- 'libs/debug'
-//DIR_JNI_DEBUG_BEGIN
-//DIR_JNI_DEBUG_END
- ]
- release.jniLibs.srcDirs = [
- 'libs/release'
-//DIR_JNI_RELEASE_BEGIN
-//DIR_JNI_RELEASE_END
- ]
- }
-// No longer used, as it's not useful for build source template
-// applicationVariants.all { variant ->
-// variant.outputs.all { output ->
-// output.outputFileName = "../../../../../../../bin/android_${variant.name}.apk"
-// }
-// }
-
+/**
+ * Copy the generated 'android_release.apk' binary template into the Godot bin directory.
+ * Depends on the app build task to ensure the binary is generated prior to copying.
+ */
+task copyReleaseBinaryToBin(type: Copy) {
+ dependsOn ':app:build'
+ from('app/build/outputs/apk/release')
+ into(binDir)
+ include('android_release.apk')
}
-//CHUNK_GLOBAL_BEGIN
-//CHUNK_GLOBAL_END
-
-
+/**
+ * Copy the Godot android library archive debug file into the app debug libs directory.
+ * Depends on the library build task to ensure the AAR file is generated prior to copying.
+ */
+task copyDebugAAR(type: Copy) {
+ dependsOn ':lib:build'
+ from('lib/build/outputs/aar')
+ into('app/libs/debug')
+ include('godot-lib.debug.aar')
+}
+/**
+ * Copy the Godot android library archive release file into the app release libs directory.
+ * Depends on the library build task to ensure the AAR file is generated prior to copying.
+ */
+task copyReleaseAAR(type: Copy) {
+ dependsOn ':lib:build'
+ from('lib/build/outputs/aar')
+ into('app/libs/release')
+ include('godot-lib.release.aar')
+}
+/**
+ * Generate Godot custom build template by zipping the source files from the app directory, as well
+ * as the AAR files generated by 'copyDebugAAR' and 'copyReleaseAAR'.
+ * The zip file also includes some gradle tools to allow building of the custom build.
+ */
+task zipCustomBuild(type: Zip) {
+ dependsOn 'copyDebugAAR'
+ dependsOn 'copyReleaseAAR'
+ from(fileTree(dir: 'app', excludes: ['**/build/**', '**/.gradle/**', '**/*.iml']), fileTree(dir: '.', includes: ['gradle.properties','gradlew', 'gradlew.bat', 'gradle/**']))
+ include '**/*'
+ archiveName 'android_source.zip'
+ destinationDir(file(binDir))
+}
+/**
+ * Master task used to coordinate the tasks defined above to generate the set of Godot templates.
+ */
+task generateGodotTemplates(type: GradleBuild) {
+ tasks = [
+ // Copy the generated aar library files to the custom build directory.
+ 'copyDebugAAR', 'copyReleaseAAR',
+ // Zip the custom build directory.
+ 'zipCustomBuild',
+ // Copy the prebuilt binary templates to the bin directory.
+ 'copyDebugBinaryToBin', 'copyReleaseBinaryToBin',
+ ]
+}
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index bf3de21830..bf50265715 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+#Mon Sep 02 02:44:30 PDT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
new file mode 100644
index 0000000000..517fc403b2
--- /dev/null
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.godotengine.godot"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <application>
+
+ <service android:name=".GodotDownloaderService" />
+
+ </application>
+
+ <instrumentation
+ android:icon="@drawable/icon"
+ android:label="@string/godot_project_name_string"
+ android:name=".GodotInstrumentation"
+ android:targetPackage="org.godotengine.godot" />
+
+</manifest>
diff --git a/misc/ide/jetbrains/CMakeLists.txt b/platform/android/java/lib/CMakeLists.txt
index b6e56e0778..d3bdf6a5f2 100644
--- a/misc/ide/jetbrains/CMakeLists.txt
+++ b/platform/android/java/lib/CMakeLists.txt
@@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-set(GODOT_ROOT_DIR ../../..)
+set(GODOT_ROOT_DIR ../../../..)
# Get sources
file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**)
diff --git a/platform/android/java/lib/THIRDPARTY.md b/platform/android/java/lib/THIRDPARTY.md
new file mode 100644
index 0000000000..2496b59263
--- /dev/null
+++ b/platform/android/java/lib/THIRDPARTY.md
@@ -0,0 +1,39 @@
+# Third-party libraries
+
+This file list third-party libraries used in the Android source folder,
+with their provenance and, when relevant, modifications made to those files.
+
+## com.android.vending.billing
+
+- Upstream: https://github.com/googlesamples/android-play-billing/tree/master/TrivialDrive/app/src/main
+- Version: git (7a94c69, 2019)
+- License: Apache 2.0
+
+Overwrite the file `aidl/com/android/vending/billing/IInAppBillingService.aidl`.
+
+## com.google.android.vending.expansion.downloader
+
+- Upstream: https://github.com/google/play-apk-expansion/tree/master/apkx_library
+- Version: git (9ecf54e, 2017)
+- License: Apache 2.0
+
+Overwrite all files under:
+
+- `src/com/google/android/vending/expansion/downloader`
+
+Some files have been modified for yet unclear reasons.
+See the `patches/com.google.android.vending.expansion.downloader.patch` file.
+
+## com.google.android.vending.licensing
+
+- Upstream: https://github.com/google/play-licensing/tree/master/lvl_library/
+- Version: git (eb57657, 2018) with modifications
+- License: Apache 2.0
+
+Overwrite all files under:
+
+- `aidl/com/android/vending/licensing`
+- `src/com/google/android/vending/licensing`
+
+Some files have been modified to silence linter errors or fix downstream issues.
+See the `patches/com.google.android.vending.licensing.patch` file.
diff --git a/platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl b/platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl
new file mode 100644
index 0000000000..0f2bcae338
--- /dev/null
+++ b/platform/android/java/lib/aidl/com/android/vending/billing/IInAppBillingService.aidl
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.vending.billing;
+
+import android.os.Bundle;
+
+/**
+ * InAppBillingService is the service that provides in-app billing version 3 and beyond.
+ * This service provides the following features:
+ * 1. Provides a new API to get details of in-app items published for the app including
+ * price, type, title and description.
+ * 2. The purchase flow is synchronous and purchase information is available immediately
+ * after it completes.
+ * 3. Purchase information of in-app purchases is maintained within the Google Play system
+ * till the purchase is consumed.
+ * 4. An API to consume a purchase of an inapp item. All purchases of one-time
+ * in-app items are consumable and thereafter can be purchased again.
+ * 5. An API to get current purchases of the user immediately. This will not contain any
+ * consumed purchases.
+ *
+ * All calls will give a response code with the following possible values
+ * RESULT_OK = 0 - success
+ * RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog
+ * RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down
+ * RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested
+ * RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase
+ * RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API
+ * RESULT_ERROR = 6 - Fatal error during the API action
+ * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
+ * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
+ */
+interface IInAppBillingService {
+ /**
+ * Checks support for the requested billing API version, package and in-app type.
+ * Minimum API version supported by this interface is 3.
+ * @param apiVersion billing API version that the app is using
+ * @param packageName the package name of the calling app
+ * @param type type of the in-app item being purchased ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @return RESULT_OK(0) on success and appropriate response code on failures.
+ */
+ int isBillingSupported(int apiVersion, String packageName, String type);
+
+ /**
+ * Provides details of a list of SKUs
+ * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
+ * with a list JSON strings containing the productId, price, title and description.
+ * This API can be called with a maximum of 20 SKUs.
+ * @param apiVersion billing API version that the app is using
+ * @param packageName the package name of the calling app
+ * @param type of the in-app items ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
+ * @return Bundle containing the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
+ * on failures.
+ * "DETAILS_LIST" with a StringArrayList containing purchase information
+ * in JSON format similar to:
+ * '{ "productId" : "exampleSku",
+ * "type" : "inapp",
+ * "price" : "$5.00",
+ * "price_currency": "USD",
+ * "price_amount_micros": 5000000,
+ * "title : "Example Title",
+ * "description" : "This is an example description" }'
+ */
+ Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
+
+ /**
+ * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
+ * the type, a unique purchase token and an optional developer payload.
+ * @param apiVersion billing API version that the app is using
+ * @param packageName package name of the calling app
+ * @param sku the SKU of the in-app item as published in the developer console
+ * @param type of the in-app item being purchased ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @param developerPayload optional argument to be sent back with the purchase information
+ * @return Bundle containing the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
+ * on failures.
+ * "BUY_INTENT" - PendingIntent to start the purchase flow
+ *
+ * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
+ * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
+ * If the purchase is successful, the result data will contain the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
+ * codes on failures.
+ * "INAPP_PURCHASE_DATA" - String in JSON format similar to
+ * '{"orderId":"12999763169054705758.1371079406387615",
+ * "packageName":"com.example.app",
+ * "productId":"exampleSku",
+ * "purchaseTime":1345678900000,
+ * "purchaseToken" : "122333444455555",
+ * "developerPayload":"example developer payload" }'
+ * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
+ * was signed with the private key of the developer
+ */
+ Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
+ String developerPayload);
+
+ /**
+ * Returns the current SKUs owned by the user of the type and package name specified along with
+ * purchase information and a signature of the data to be validated.
+ * This will return all SKUs that have been purchased in V3 and managed items purchased using
+ * V1 and V2 that have not been consumed.
+ * @param apiVersion billing API version that the app is using
+ * @param packageName package name of the calling app
+ * @param type of the in-app items being requested ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @param continuationToken to be set as null for the first call, if the number of owned
+ * skus are too many, a continuationToken is returned in the response bundle.
+ * This method can be called again with the continuation token to get the next set of
+ * owned skus.
+ * @return Bundle containing the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
+ on failures.
+ * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
+ * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
+ * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
+ * of the purchase information
+ * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
+ * next set of in-app purchases. Only set if the
+ * user has more owned skus than the current list.
+ */
+ Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
+
+ /**
+ * Consume the last purchase of the given SKU. This will result in this item being removed
+ * from all subsequent responses to getPurchases() and allow re-purchase of this item.
+ * @param apiVersion billing API version that the app is using
+ * @param packageName package name of the calling app
+ * @param purchaseToken token in the purchase information JSON that identifies the purchase
+ * to be consumed
+ * @return RESULT_OK(0) if consumption succeeded, appropriate response codes on failures.
+ */
+ int consumePurchase(int apiVersion, String packageName, String purchaseToken);
+
+ /**
+ * This API is currently under development.
+ */
+ int stub(int apiVersion, String packageName, String type);
+
+ /**
+ * Returns a pending intent to launch the purchase flow for upgrading or downgrading a
+ * subscription. The existing owned SKU(s) should be provided along with the new SKU that
+ * the user is upgrading or downgrading to.
+ * @param apiVersion billing API version that the app is using, must be 5 or later
+ * @param packageName package name of the calling app
+ * @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
+ * if null or empty this method will behave like {@link #getBuyIntent}
+ * @param newSku the SKU that the user is upgrading or downgrading to
+ * @param type of the item being purchased, currently must be "subs"
+ * @param developerPayload optional argument to be sent back with the purchase information
+ * @return Bundle containing the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
+ * on failures.
+ * "BUY_INTENT" - PendingIntent to start the purchase flow
+ *
+ * The Pending intent should be launched with startIntentSenderForResult. When purchase flow
+ * has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
+ * If the purchase is successful, the result data will contain the following key-value pairs
+ * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
+ * codes on failures.
+ * "INAPP_PURCHASE_DATA" - String in JSON format similar to
+ * '{"orderId":"12999763169054705758.1371079406387615",
+ * "packageName":"com.example.app",
+ * "productId":"exampleSku",
+ * "purchaseTime":1345678900000,
+ * "purchaseToken" : "122333444455555",
+ * "developerPayload":"example developer payload" }'
+ * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
+ * was signed with the private key of the developer
+ */
+ Bundle getBuyIntentToReplaceSkus(int apiVersion, String packageName,
+ in List<String> oldSkus, String newSku, String type, String developerPayload);
+
+ /**
+ * Returns a pending intent to launch the purchase flow for an in-app item. This method is
+ * a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
+ * parameter. This parameter is a Bundle of optional keys and values that affect the
+ * operation of the method.
+ * @param apiVersion billing API version that the app is using, must be 6 or later
+ * @param packageName package name of the calling app
+ * @param sku the SKU of the in-app item as published in the developer console
+ * @param type of the in-app item being purchased ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @param developerPayload optional argument to be sent back with the purchase information
+ * @extraParams a Bundle with the following optional keys:
+ * "skusToReplace" - List<String> - an optional list of SKUs that the user is
+ * upgrading or downgrading from.
+ * Pass this field if the purchase is upgrading or downgrading
+ * existing subscriptions.
+ * The specified SKUs are replaced with the SKUs that the user is
+ * purchasing. Google Play replaces the specified SKUs at the start of
+ * the next billing cycle.
+ * "replaceSkusProration" - Boolean - whether the user should be credited for any unused
+ * subscription time on the SKUs they are upgrading or downgrading.
+ * If you set this field to true, Google Play swaps out the old SKUs
+ * and credits the user with the unused value of their subscription
+ * time on a pro-rated basis.
+ * Google Play applies this credit to the new subscription, and does
+ * not begin billing the user for the new subscription until after
+ * the credit is used up.
+ * If you set this field to false, the user does not receive credit for
+ * any unused subscription time and the recurrence date does not
+ * change.
+ * Default value is true. Ignored if you do not pass skusToReplace.
+ * "accountId" - String - an optional obfuscated string that is uniquely
+ * associated with the user's account in your app.
+ * If you pass this value, Google Play can use it to detect irregular
+ * activity, such as many devices making purchases on the same
+ * account in a short period of time.
+ * Do not use the developer ID or the user's Google ID for this field.
+ * In addition, this field should not contain the user's ID in
+ * cleartext.
+ * We recommend that you use a one-way hash to generate a string from
+ * the user's ID, and store the hashed string in this field.
+ * "vr" - Boolean - an optional flag indicating whether the returned intent
+ * should start a VR purchase flow. The apiVersion must also be 7 or
+ * later to use this flag.
+ */
+ Bundle getBuyIntentExtraParams(int apiVersion, String packageName, String sku,
+ String type, String developerPayload, in Bundle extraParams);
+
+ /**
+ * Returns the most recent purchase made by the user for each SKU, even if that purchase is
+ * expired, canceled, or consumed.
+ * @param apiVersion billing API version that the app is using, must be 6 or later
+ * @param packageName package name of the calling app
+ * @param type of the in-app items being requested ("inapp" for one-time purchases
+ * and "subs" for subscriptions)
+ * @param continuationToken to be set as null for the first call, if the number of owned
+ * skus is too large, a continuationToken is returned in the response bundle.
+ * This method can be called again with the continuation token to get the next set of
+ * owned skus.
+ * @param extraParams a Bundle with extra params that would be appended into http request
+ * query string. Not used at this moment. Reserved for future functionality.
+ * @return Bundle containing the following key-value pairs
+ * "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
+ * {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
+ *
+ * "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
+ * "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
+ * "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
+ * of the purchase information
+ * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
+ * next set of in-app purchases. Only set if the
+ * user has more owned skus than the current list.
+ */
+ Bundle getPurchaseHistory(int apiVersion, String packageName, String type,
+ String continuationToken, in Bundle extraParams);
+
+ /**
+ * This method is a variant of {@link #isBillingSupported}} that takes an additional
+ * {@code extraParams} parameter.
+ * @param apiVersion billing API version that the app is using, must be 7 or later
+ * @param packageName package name of the calling app
+ * @param type of the in-app item being purchased ("inapp" for one-time purchases and "subs"
+ * for subscriptions)
+ * @param extraParams a Bundle with the following optional keys:
+ * "vr" - Boolean - an optional flag to indicate whether {link #getBuyIntentExtraParams}
+ * supports returning a VR purchase flow.
+ * @return RESULT_OK(0) on success and appropriate response code on failures.
+ */
+ int isBillingSupportedExtraParams(int apiVersion, String packageName, String type,
+ in Bundle extraParams);
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.aidl b/platform/android/java/lib/aidl/com/android/vending/licensing/ILicenseResultListener.aidl
index c816558afc..869cb16f68 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.aidl
+++ b/platform/android/java/lib/aidl/com/android/vending/licensing/ILicenseResultListener.aidl
@@ -16,8 +16,6 @@
package com.android.vending.licensing;
-// Android library projects do not yet support AIDL, so this has been
-// precompiled into the src directory.
oneway interface ILicenseResultListener {
void verifyLicense(int responseCode, String signedData, String signature);
}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ILicensingService.aidl b/platform/android/java/lib/aidl/com/android/vending/licensing/ILicensingService.aidl
index 664510ce0c..9541a2090c 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/ILicensingService.aidl
+++ b/platform/android/java/lib/aidl/com/android/vending/licensing/ILicensingService.aidl
@@ -18,8 +18,6 @@ package com.android.vending.licensing;
import com.android.vending.licensing.ILicenseResultListener;
-// Android library projects do not yet support AIDL, so this has been
-// precompiled into the src directory.
oneway interface ILicensingService {
void checkLicense(long nonce, String packageName, in ILicenseResultListener listener);
}
diff --git a/misc/ide/jetbrains/build.gradle b/platform/android/java/lib/build.gradle
index eb2fbc0e69..6d07504e45 100644
--- a/misc/ide/jetbrains/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -1,60 +1,43 @@
-buildscript {
- repositories {
- google()
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.3.2'
- }
-}
-
-allprojects {
- repositories {
- google()
- jcenter()
- }
-}
-
apply plugin: 'com.android.library'
dependencies {
implementation "com.android.support:support-core-utils:28.0.0"
}
-def pathToRootDir = "../../../"
+def pathToRootDir = "../../../../"
// Note: Only keep the abis you support to speed up the gradle 'assemble' task.
def supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"]
android {
+ compileSdkVersion versions.compileSdk
+ buildToolsVersion versions.buildTools
+ useLibrary 'org.apache.http.legacy'
+
+ defaultConfig {
+ minSdkVersion versions.minSdk
+ targetSdkVersion versions.targetSdk
+ }
lintOptions {
abortOnError false
- disable "MissingTranslation", 'UnusedResources'
+ disable 'MissingTranslation', 'UnusedResources'
}
- compileSdkVersion 28
- buildToolsVersion "28.0.3"
- useLibrary 'org.apache.http.legacy'
-
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
- defaultConfig {
- minSdkVersion 18
- targetSdkVersion 28
- }
sourceSets {
main {
- manifest.srcFile "AndroidManifest.xml"
- java.srcDirs = ["${pathToRootDir}platform/android/java/src"]
- res.srcDirs = ["${pathToRootDir}platform/android/java/res"]
- aidl.srcDirs = ["${pathToRootDir}platform/android/java/aidl"]
- assets.srcDirs = ["${pathToRootDir}platform/android/java/assets"]
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['src']
+ res.srcDirs = ['res']
+ aidl.srcDirs = ['aidl']
+ assets.srcDirs = ['assets']
}
- debug.jniLibs.srcDirs = ["${pathToRootDir}platform/android/java/libs/debug"]
- release.jniLibs.srcDirs = ["${pathToRootDir}platform/android/java/libs/release"]
+ debug.jniLibs.srcDirs = ['libs/debug']
+ release.jniLibs.srcDirs = ['libs/release']
}
libraryVariants.all { variant ->
diff --git a/platform/android/java/lib/patches/com.google.android.vending.expansion.downloader.patch b/platform/android/java/lib/patches/com.google.android.vending.expansion.downloader.patch
new file mode 100644
index 0000000000..49cc41e817
--- /dev/null
+++ b/platform/android/java/lib/patches/com.google.android.vending.expansion.downloader.patch
@@ -0,0 +1,300 @@
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
+index ad6ea0de6..452c7d148 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
+@@ -32,6 +32,9 @@ import android.os.Messenger;
+ import android.os.RemoteException;
+ import android.util.Log;
+
++// -- GODOT start --
++import java.lang.ref.WeakReference;
++// -- GODOT end --
+
+
+ /**
+@@ -118,29 +121,46 @@ public class DownloaderClientMarshaller {
+ /**
+ * Target we publish for clients to send messages to IncomingHandler.
+ */
+- final Messenger mMessenger = new Messenger(new Handler() {
++ // -- GODOT start --
++ private final MessengerHandlerClient mMsgHandler = new MessengerHandlerClient(this);
++ final Messenger mMessenger = new Messenger(mMsgHandler);
++
++ private static class MessengerHandlerClient extends Handler {
++ private final WeakReference<Stub> mDownloader;
++ public MessengerHandlerClient(Stub downloader) {
++ mDownloader = new WeakReference<>(downloader);
++ }
++
+ @Override
+ public void handleMessage(Message msg) {
+- switch (msg.what) {
+- case MSG_ONDOWNLOADPROGRESS:
+- Bundle bun = msg.getData();
+- if ( null != mContext ) {
+- bun.setClassLoader(mContext.getClassLoader());
+- DownloadProgressInfo dpi = (DownloadProgressInfo) msg.getData()
+- .getParcelable(PARAM_PROGRESS);
+- mItf.onDownloadProgress(dpi);
+- }
+- break;
+- case MSG_ONDOWNLOADSTATE_CHANGED:
+- mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
+- break;
+- case MSG_ONSERVICECONNECTED:
+- mItf.onServiceConnected(
+- (Messenger) msg.getData().getParcelable(PARAM_MESSENGER));
+- break;
++ Stub downloader = mDownloader.get();
++ if (downloader != null) {
++ downloader.handleMessage(msg);
+ }
+ }
+- });
++ }
++
++ private void handleMessage(Message msg) {
++ switch (msg.what) {
++ case MSG_ONDOWNLOADPROGRESS:
++ Bundle bun = msg.getData();
++ if (null != mContext) {
++ bun.setClassLoader(mContext.getClassLoader());
++ DownloadProgressInfo dpi = (DownloadProgressInfo)msg.getData()
++ .getParcelable(PARAM_PROGRESS);
++ mItf.onDownloadProgress(dpi);
++ }
++ break;
++ case MSG_ONDOWNLOADSTATE_CHANGED:
++ mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
++ break;
++ case MSG_ONSERVICECONNECTED:
++ mItf.onServiceConnected(
++ (Messenger)msg.getData().getParcelable(PARAM_MESSENGER));
++ break;
++ }
++ }
++ // -- GODOT end --
+
+ public Stub(IDownloaderClient itf, Class<?> downloaderService) {
+ mItf = itf;
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
+index 979352299..3771d19c9 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
+@@ -25,6 +25,9 @@ import android.os.Message;
+ import android.os.Messenger;
+ import android.os.RemoteException;
+
++// -- GODOT start --
++import java.lang.ref.WeakReference;
++// -- GODOT end --
+
+
+ /**
+@@ -108,32 +111,49 @@ public class DownloaderServiceMarshaller {
+
+ private static class Stub implements IStub {
+ private IDownloaderService mItf = null;
+- final Messenger mMessenger = new Messenger(new Handler() {
++ // -- GODOT start --
++ private final MessengerHandlerServer mMsgHandler = new MessengerHandlerServer(this);
++ final Messenger mMessenger = new Messenger(mMsgHandler);
++
++ private static class MessengerHandlerServer extends Handler {
++ private final WeakReference<Stub> mDownloader;
++ public MessengerHandlerServer(Stub downloader) {
++ mDownloader = new WeakReference<>(downloader);
++ }
++
+ @Override
+ public void handleMessage(Message msg) {
+- switch (msg.what) {
+- case MSG_REQUEST_ABORT_DOWNLOAD:
+- mItf.requestAbortDownload();
+- break;
+- case MSG_REQUEST_CONTINUE_DOWNLOAD:
+- mItf.requestContinueDownload();
+- break;
+- case MSG_REQUEST_PAUSE_DOWNLOAD:
+- mItf.requestPauseDownload();
+- break;
+- case MSG_SET_DOWNLOAD_FLAGS:
+- mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
+- break;
+- case MSG_REQUEST_DOWNLOAD_STATE:
+- mItf.requestDownloadStatus();
+- break;
+- case MSG_REQUEST_CLIENT_UPDATE:
+- mItf.onClientUpdated((Messenger) msg.getData().getParcelable(
+- PARAM_MESSENGER));
+- break;
++ Stub downloader = mDownloader.get();
++ if (downloader != null) {
++ downloader.handleMessage(msg);
+ }
+ }
+- });
++ }
++
++ private void handleMessage(Message msg) {
++ switch (msg.what) {
++ case MSG_REQUEST_ABORT_DOWNLOAD:
++ mItf.requestAbortDownload();
++ break;
++ case MSG_REQUEST_CONTINUE_DOWNLOAD:
++ mItf.requestContinueDownload();
++ break;
++ case MSG_REQUEST_PAUSE_DOWNLOAD:
++ mItf.requestPauseDownload();
++ break;
++ case MSG_SET_DOWNLOAD_FLAGS:
++ mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
++ break;
++ case MSG_REQUEST_DOWNLOAD_STATE:
++ mItf.requestDownloadStatus();
++ break;
++ case MSG_REQUEST_CLIENT_UPDATE:
++ mItf.onClientUpdated((Messenger)msg.getData().getParcelable(
++ PARAM_MESSENGER));
++ break;
++ }
++ }
++ // -- GODOT end --
+
+ public Stub(IDownloaderService itf) {
+ mItf = itf;
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
+index e4b1b0f1c..36cd6aacf 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
+@@ -24,7 +24,10 @@ import android.os.StatFs;
+ import android.os.SystemClock;
+ import android.util.Log;
+
+-import com.android.vending.expansion.downloader.R;
++// -- GODOT start --
++//import com.android.vending.expansion.downloader.R;
++import org.godotengine.godot.R;
++// -- GODOT end --
+
+ import java.io.File;
+ import java.text.SimpleDateFormat;
+@@ -146,12 +149,14 @@ public class Helpers {
+ }
+ return "";
+ }
+- return String.format("%.2f",
++ // -- GODOT start --
++ return String.format(Locale.ENGLISH, "%.2f",
+ (float) overallProgress / (1024.0f * 1024.0f))
+ + "MB /" +
+- String.format("%.2f", (float) overallTotal /
++ String.format(Locale.ENGLISH, "%.2f", (float) overallTotal /
+ (1024.0f * 1024.0f))
+ + "MB";
++ // -- GODOT end --
+ }
+
+ /**
+@@ -184,7 +189,9 @@ public class Helpers {
+ }
+
+ public static String getSpeedString(float bytesPerMillisecond) {
+- return String.format("%.2f", bytesPerMillisecond * 1000 / 1024);
++ // -- GODOT start --
++ return String.format(Locale.ENGLISH, "%.2f", bytesPerMillisecond * 1000 / 1024);
++ // -- GODOT end --
+ }
+
+ public static String getTimeRemaining(long durationInMilliseconds) {
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
+index 12edd97ab..a0e1165cc 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
+@@ -26,6 +26,10 @@ import android.net.NetworkInfo;
+ import android.telephony.TelephonyManager;
+ import android.util.Log;
+
++// -- GODOT start --
++import android.annotation.SuppressLint;
++// -- GODOT end --
++
+ /**
+ * Contains useful helper functions, typically tied to the application context.
+ */
+@@ -51,6 +55,7 @@ class SystemFacade {
+ return null;
+ }
+
++ @SuppressLint("MissingPermission")
+ NetworkInfo activeInfo = connectivity.getActiveNetworkInfo();
+ if (activeInfo == null) {
+ if (Constants.LOGVV) {
+@@ -69,6 +74,7 @@ class SystemFacade {
+ return false;
+ }
+
++ @SuppressLint("MissingPermission")
+ NetworkInfo info = connectivity.getActiveNetworkInfo();
+ boolean isMobile = (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE);
+ TelephonyManager tm = (TelephonyManager) mContext
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
+index f1536e80e..4b214b22d 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
+@@ -16,7 +16,11 @@
+
+ package com.google.android.vending.expansion.downloader.impl;
+
+-import com.android.vending.expansion.downloader.R;
++// -- GODOT start --
++//import com.android.vending.expansion.downloader.R;
++import org.godotengine.godot.R;
++// -- GODOT end --
++
+ import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
+ import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
+ import com.google.android.vending.expansion.downloader.Helpers;
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
+index b2e0e7af0..c114b8a64 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
+@@ -146,8 +146,12 @@ public class DownloadThread {
+
+ try {
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+- wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
+- wakeLock.acquire();
++ // -- GODOT start --
++ //wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
++ //wakeLock.acquire();
++ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "org.godot.game:wakelock");
++ wakeLock.acquire(20 * 60 * 1000L /*20 minutes*/);
++ // -- GODOT end --
+
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
+diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+index 4babe476f..8d41a7690 100644
+--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
++++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+@@ -50,6 +50,10 @@ import android.provider.Settings.Secure;
+ import android.telephony.TelephonyManager;
+ import android.util.Log;
+
++// -- GODOT start --
++import android.annotation.SuppressLint;
++// -- GODOT end --
++
+ import java.io.File;
+
+ /**
+@@ -578,6 +582,7 @@ public abstract class DownloaderService extends CustomIntentService implements I
+ Log.w(Constants.TAG,
+ "couldn't get connectivity manager to poll network state");
+ } else {
++ @SuppressLint("MissingPermission")
+ NetworkInfo activeInfo = mConnectivityManager
+ .getActiveNetworkInfo();
+ updateNetworkState(activeInfo);
diff --git a/platform/android/java/lib/patches/com.google.android.vending.licensing.patch b/platform/android/java/lib/patches/com.google.android.vending.licensing.patch
new file mode 100644
index 0000000000..4adb81d951
--- /dev/null
+++ b/platform/android/java/lib/patches/com.google.android.vending.licensing.patch
@@ -0,0 +1,42 @@
+diff --git a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java b/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
+index 7c42bfc28..feb579af0 100644
+--- a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
++++ b/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
+@@ -45,6 +45,9 @@ public class PreferenceObfuscator {
+ public void putString(String key, String value) {
+ if (mEditor == null) {
+ mEditor = mPreferences.edit();
++ // -- GODOT start --
++ mEditor.apply();
++ // -- GODOT end --
+ }
+ String obfuscatedValue = mObfuscator.obfuscate(value, key);
+ mEditor.putString(key, obfuscatedValue);
+diff --git a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java b/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
+index a0d2779af..a8bf65f9c 100644
+--- a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
++++ b/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
+@@ -31,6 +31,10 @@ package com.google.android.vending.licensing.util;
+ * @version 1.3
+ */
+
++// -- GODOT start --
+import org.godotengine.godot.BuildConfig;
++// -- GODOT end --
++
+ /**
+ * Base64 converter class. This code is not a full-blown MIME encoder;
+ * it simply converts binary data to base64 data and back.
+@@ -341,7 +345,11 @@ public class Base64 {
+ e += 4;
+ }
+
+- assert (e == outBuff.length);
++ // -- GODOT start --
++ //assert (e == outBuff.length);
++ if (BuildConfig.DEBUG && e != outBuff.length)
++ throw new RuntimeException();
++ // -- GODOT end --
+ return outBuff;
+ }
+
diff --git a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png
index 2c246b04a4..2c246b04a4 100644
--- a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png
index 8bcd464bed..8bcd464bed 100644
--- a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable-nodpi/icon.png b/platform/android/java/lib/res/drawable-nodpi/icon.png
index 6ad9b43117..6ad9b43117 100644
--- a/platform/android/java/res/drawable-nodpi/icon.png
+++ b/platform/android/java/lib/res/drawable-nodpi/icon.png
Binary files differ
diff --git a/platform/android/java/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
index 372b763ec5..372b763ec5 100644
--- a/platform/android/java/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png
index b458ff3057..b458ff3057 100644
--- a/platform/android/java/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/layout/downloading_expansion.xml b/platform/android/java/lib/res/layout/downloading_expansion.xml
index 4a9700965f..4a9700965f 100644
--- a/platform/android/java/res/layout/downloading_expansion.xml
+++ b/platform/android/java/lib/res/layout/downloading_expansion.xml
diff --git a/platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml b/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml
index fae1faeb60..fae1faeb60 100644
--- a/platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml
+++ b/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml
diff --git a/platform/android/java/res/values-ar/strings.xml b/platform/android/java/lib/res/values-ar/strings.xml
index 9f3dc6d6ac..9f3dc6d6ac 100644
--- a/platform/android/java/res/values-ar/strings.xml
+++ b/platform/android/java/lib/res/values-ar/strings.xml
diff --git a/platform/android/java/res/values-bg/strings.xml b/platform/android/java/lib/res/values-bg/strings.xml
index bd8109277e..bd8109277e 100644
--- a/platform/android/java/res/values-bg/strings.xml
+++ b/platform/android/java/lib/res/values-bg/strings.xml
diff --git a/platform/android/java/res/values-ca/strings.xml b/platform/android/java/lib/res/values-ca/strings.xml
index 494cb88468..494cb88468 100644
--- a/platform/android/java/res/values-ca/strings.xml
+++ b/platform/android/java/lib/res/values-ca/strings.xml
diff --git a/platform/android/java/res/values-cs/strings.xml b/platform/android/java/lib/res/values-cs/strings.xml
index 30ce00f895..30ce00f895 100644
--- a/platform/android/java/res/values-cs/strings.xml
+++ b/platform/android/java/lib/res/values-cs/strings.xml
diff --git a/platform/android/java/res/values-da/strings.xml b/platform/android/java/lib/res/values-da/strings.xml
index 4c2a1cf0f4..4c2a1cf0f4 100644
--- a/platform/android/java/res/values-da/strings.xml
+++ b/platform/android/java/lib/res/values-da/strings.xml
diff --git a/platform/android/java/res/values-de/strings.xml b/platform/android/java/lib/res/values-de/strings.xml
index 52946d4cce..52946d4cce 100644
--- a/platform/android/java/res/values-de/strings.xml
+++ b/platform/android/java/lib/res/values-de/strings.xml
diff --git a/platform/android/java/res/values-el/strings.xml b/platform/android/java/lib/res/values-el/strings.xml
index 181dc51762..181dc51762 100644
--- a/platform/android/java/res/values-el/strings.xml
+++ b/platform/android/java/lib/res/values-el/strings.xml
diff --git a/platform/android/java/res/values-en/strings.xml b/platform/android/java/lib/res/values-en/strings.xml
index 976a565013..976a565013 100644
--- a/platform/android/java/res/values-en/strings.xml
+++ b/platform/android/java/lib/res/values-en/strings.xml
diff --git a/platform/android/java/res/values-es-rES/strings.xml b/platform/android/java/lib/res/values-es-rES/strings.xml
index 73f63a08f8..73f63a08f8 100644
--- a/platform/android/java/res/values-es-rES/strings.xml
+++ b/platform/android/java/lib/res/values-es-rES/strings.xml
diff --git a/platform/android/java/res/values-es/strings.xml b/platform/android/java/lib/res/values-es/strings.xml
index 07b718a641..07b718a641 100644
--- a/platform/android/java/res/values-es/strings.xml
+++ b/platform/android/java/lib/res/values-es/strings.xml
diff --git a/platform/android/java/res/values-fa/strings.xml b/platform/android/java/lib/res/values-fa/strings.xml
index f1e29013c4..f1e29013c4 100644
--- a/platform/android/java/res/values-fa/strings.xml
+++ b/platform/android/java/lib/res/values-fa/strings.xml
diff --git a/platform/android/java/res/values-fi/strings.xml b/platform/android/java/lib/res/values-fi/strings.xml
index 323d82aff1..323d82aff1 100644
--- a/platform/android/java/res/values-fi/strings.xml
+++ b/platform/android/java/lib/res/values-fi/strings.xml
diff --git a/platform/android/java/res/values-fr/strings.xml b/platform/android/java/lib/res/values-fr/strings.xml
index 32bead2661..32bead2661 100644
--- a/platform/android/java/res/values-fr/strings.xml
+++ b/platform/android/java/lib/res/values-fr/strings.xml
diff --git a/platform/android/java/res/values-hi/strings.xml b/platform/android/java/lib/res/values-hi/strings.xml
index 8aab2a8c63..8aab2a8c63 100644
--- a/platform/android/java/res/values-hi/strings.xml
+++ b/platform/android/java/lib/res/values-hi/strings.xml
diff --git a/platform/android/java/res/values-hr/strings.xml b/platform/android/java/lib/res/values-hr/strings.xml
index caf55e2241..caf55e2241 100644
--- a/platform/android/java/res/values-hr/strings.xml
+++ b/platform/android/java/lib/res/values-hr/strings.xml
diff --git a/platform/android/java/res/values-hu/strings.xml b/platform/android/java/lib/res/values-hu/strings.xml
index e7f9e51226..e7f9e51226 100644
--- a/platform/android/java/res/values-hu/strings.xml
+++ b/platform/android/java/lib/res/values-hu/strings.xml
diff --git a/platform/android/java/res/values-in/strings.xml b/platform/android/java/lib/res/values-in/strings.xml
index 9e9a8b0c03..9e9a8b0c03 100644
--- a/platform/android/java/res/values-in/strings.xml
+++ b/platform/android/java/lib/res/values-in/strings.xml
diff --git a/platform/android/java/res/values-it/strings.xml b/platform/android/java/lib/res/values-it/strings.xml
index 1f5e5a049e..1f5e5a049e 100644
--- a/platform/android/java/res/values-it/strings.xml
+++ b/platform/android/java/lib/res/values-it/strings.xml
diff --git a/platform/android/java/res/values-iw/strings.xml b/platform/android/java/lib/res/values-iw/strings.xml
index f52ede2085..f52ede2085 100644
--- a/platform/android/java/res/values-iw/strings.xml
+++ b/platform/android/java/lib/res/values-iw/strings.xml
diff --git a/platform/android/java/res/values-ja/strings.xml b/platform/android/java/lib/res/values-ja/strings.xml
index 7f85f57df7..7f85f57df7 100644
--- a/platform/android/java/res/values-ja/strings.xml
+++ b/platform/android/java/lib/res/values-ja/strings.xml
diff --git a/platform/android/java/res/values-ko/strings.xml b/platform/android/java/lib/res/values-ko/strings.xml
index fab0bdd753..fab0bdd753 100644
--- a/platform/android/java/res/values-ko/strings.xml
+++ b/platform/android/java/lib/res/values-ko/strings.xml
diff --git a/platform/android/java/res/values-lt/strings.xml b/platform/android/java/lib/res/values-lt/strings.xml
index 6e3677fde7..6e3677fde7 100644
--- a/platform/android/java/res/values-lt/strings.xml
+++ b/platform/android/java/lib/res/values-lt/strings.xml
diff --git a/platform/android/java/res/values-lv/strings.xml b/platform/android/java/lib/res/values-lv/strings.xml
index 701fc271ac..701fc271ac 100644
--- a/platform/android/java/res/values-lv/strings.xml
+++ b/platform/android/java/lib/res/values-lv/strings.xml
diff --git a/platform/android/java/res/values-nb/strings.xml b/platform/android/java/lib/res/values-nb/strings.xml
index 73147ca1af..73147ca1af 100644
--- a/platform/android/java/res/values-nb/strings.xml
+++ b/platform/android/java/lib/res/values-nb/strings.xml
diff --git a/platform/android/java/res/values-nl/strings.xml b/platform/android/java/lib/res/values-nl/strings.xml
index e501928a35..e501928a35 100644
--- a/platform/android/java/res/values-nl/strings.xml
+++ b/platform/android/java/lib/res/values-nl/strings.xml
diff --git a/platform/android/java/res/values-pl/strings.xml b/platform/android/java/lib/res/values-pl/strings.xml
index ea5da73b6f..ea5da73b6f 100644
--- a/platform/android/java/res/values-pl/strings.xml
+++ b/platform/android/java/lib/res/values-pl/strings.xml
diff --git a/platform/android/java/res/values-pt/strings.xml b/platform/android/java/lib/res/values-pt/strings.xml
index bdda7cd2c7..bdda7cd2c7 100644
--- a/platform/android/java/res/values-pt/strings.xml
+++ b/platform/android/java/lib/res/values-pt/strings.xml
diff --git a/platform/android/java/res/values-ro/strings.xml b/platform/android/java/lib/res/values-ro/strings.xml
index 3686da4c19..3686da4c19 100644
--- a/platform/android/java/res/values-ro/strings.xml
+++ b/platform/android/java/lib/res/values-ro/strings.xml
diff --git a/platform/android/java/res/values-ru/strings.xml b/platform/android/java/lib/res/values-ru/strings.xml
index 954067658b..954067658b 100644
--- a/platform/android/java/res/values-ru/strings.xml
+++ b/platform/android/java/lib/res/values-ru/strings.xml
diff --git a/platform/android/java/res/values-sk/strings.xml b/platform/android/java/lib/res/values-sk/strings.xml
index 37d1283124..37d1283124 100644
--- a/platform/android/java/res/values-sk/strings.xml
+++ b/platform/android/java/lib/res/values-sk/strings.xml
diff --git a/platform/android/java/res/values-sl/strings.xml b/platform/android/java/lib/res/values-sl/strings.xml
index 0bb249c375..0bb249c375 100644
--- a/platform/android/java/res/values-sl/strings.xml
+++ b/platform/android/java/lib/res/values-sl/strings.xml
diff --git a/platform/android/java/res/values-sr/strings.xml b/platform/android/java/lib/res/values-sr/strings.xml
index 0e83cab1a1..0e83cab1a1 100644
--- a/platform/android/java/res/values-sr/strings.xml
+++ b/platform/android/java/lib/res/values-sr/strings.xml
diff --git a/platform/android/java/res/values-sv/strings.xml b/platform/android/java/lib/res/values-sv/strings.xml
index e3a04ac2ec..e3a04ac2ec 100644
--- a/platform/android/java/res/values-sv/strings.xml
+++ b/platform/android/java/lib/res/values-sv/strings.xml
diff --git a/platform/android/java/res/values-th/strings.xml b/platform/android/java/lib/res/values-th/strings.xml
index 0aa893b8bf..0aa893b8bf 100644
--- a/platform/android/java/res/values-th/strings.xml
+++ b/platform/android/java/lib/res/values-th/strings.xml
diff --git a/platform/android/java/res/values-tl/strings.xml b/platform/android/java/lib/res/values-tl/strings.xml
index e7e2af4909..e7e2af4909 100644
--- a/platform/android/java/res/values-tl/strings.xml
+++ b/platform/android/java/lib/res/values-tl/strings.xml
diff --git a/platform/android/java/res/values-tr/strings.xml b/platform/android/java/lib/res/values-tr/strings.xml
index 97af1243a6..97af1243a6 100644
--- a/platform/android/java/res/values-tr/strings.xml
+++ b/platform/android/java/lib/res/values-tr/strings.xml
diff --git a/platform/android/java/res/values-uk/strings.xml b/platform/android/java/lib/res/values-uk/strings.xml
index 3dea6908a9..3dea6908a9 100644
--- a/platform/android/java/res/values-uk/strings.xml
+++ b/platform/android/java/lib/res/values-uk/strings.xml
diff --git a/platform/android/java/res/values-vi/strings.xml b/platform/android/java/lib/res/values-vi/strings.xml
index a6552130b0..a6552130b0 100644
--- a/platform/android/java/res/values-vi/strings.xml
+++ b/platform/android/java/lib/res/values-vi/strings.xml
diff --git a/platform/android/java/res/values-zh-rCN/strings.xml b/platform/android/java/lib/res/values-zh-rCN/strings.xml
index 6668c56bd9..6668c56bd9 100644
--- a/platform/android/java/res/values-zh-rCN/strings.xml
+++ b/platform/android/java/lib/res/values-zh-rCN/strings.xml
diff --git a/platform/android/java/res/values-zh-rHK/strings.xml b/platform/android/java/lib/res/values-zh-rHK/strings.xml
index 8a6269da0f..8a6269da0f 100644
--- a/platform/android/java/res/values-zh-rHK/strings.xml
+++ b/platform/android/java/lib/res/values-zh-rHK/strings.xml
diff --git a/platform/android/java/res/values-zh-rTW/strings.xml b/platform/android/java/lib/res/values-zh-rTW/strings.xml
index b1bb39d5d6..b1bb39d5d6 100644
--- a/platform/android/java/res/values-zh-rTW/strings.xml
+++ b/platform/android/java/lib/res/values-zh-rTW/strings.xml
diff --git a/platform/android/java/res/values/strings.xml b/platform/android/java/lib/res/values/strings.xml
index a1b81a6186..a1b81a6186 100644
--- a/platform/android/java/res/values/strings.xml
+++ b/platform/android/java/lib/res/values/strings.xml
diff --git a/platform/android/java/res/values/styles.xml b/platform/android/java/lib/res/values/styles.xml
index a442f61e7e..a442f61e7e 100644
--- a/platform/android/java/res/values/styles.xml
+++ b/platform/android/java/lib/res/values/styles.xml
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Constants.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Constants.java
index ff1eee528f..1dcc370d83 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Constants.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Constants.java
@@ -18,113 +18,115 @@ package com.google.android.vending.expansion.downloader;
import java.io.File;
+
/**
* Contains the internal constants that are used in the download manager.
* As a general rule, modifying these constants should be done with care.
*/
public class Constants {
- /** Tag used for debugging/logging */
- public static final String TAG = "LVLDL";
+ /** Tag used for debugging/logging */
+ public static final String TAG = "LVLDL";
- /**
+ /**
* Expansion path where we store obb files
*/
- public static final String EXP_PATH = File.separator + "Android" + File.separator + "obb" + File.separator;
+ public static final String EXP_PATH = File.separator + "Android"
+ + File.separator + "obb" + File.separator;
- /** The intent that gets sent when the service must wake up for a retry */
- public static final String ACTION_RETRY = "android.intent.action.DOWNLOAD_WAKEUP";
+ /** The intent that gets sent when the service must wake up for a retry */
+ public static final String ACTION_RETRY = "android.intent.action.DOWNLOAD_WAKEUP";
- /** the intent that gets sent when clicking a successful download */
- public static final String ACTION_OPEN = "android.intent.action.DOWNLOAD_OPEN";
+ /** the intent that gets sent when clicking a successful download */
+ public static final String ACTION_OPEN = "android.intent.action.DOWNLOAD_OPEN";
- /** the intent that gets sent when clicking an incomplete/failed download */
- public static final String ACTION_LIST = "android.intent.action.DOWNLOAD_LIST";
+ /** the intent that gets sent when clicking an incomplete/failed download */
+ public static final String ACTION_LIST = "android.intent.action.DOWNLOAD_LIST";
- /** the intent that gets sent when deleting the notification of a completed download */
- public static final String ACTION_HIDE = "android.intent.action.DOWNLOAD_HIDE";
+ /** the intent that gets sent when deleting the notification of a completed download */
+ public static final String ACTION_HIDE = "android.intent.action.DOWNLOAD_HIDE";
- /**
+ /**
* When a number has to be appended to the filename, this string is used to separate the
* base filename from the sequence number
*/
- public static final String FILENAME_SEQUENCE_SEPARATOR = "-";
+ public static final String FILENAME_SEQUENCE_SEPARATOR = "-";
- /** The default user agent used for downloads */
- public static final String DEFAULT_USER_AGENT = "Android.LVLDM";
+ /** The default user agent used for downloads */
+ public static final String DEFAULT_USER_AGENT = "Android.LVLDM";
- /** The buffer size used to stream the data */
- public static final int BUFFER_SIZE = 4096;
+ /** The buffer size used to stream the data */
+ public static final int BUFFER_SIZE = 4096;
- /** The minimum amount of progress that has to be done before the progress bar gets updated */
- public static final int MIN_PROGRESS_STEP = 4096;
+ /** The minimum amount of progress that has to be done before the progress bar gets updated */
+ public static final int MIN_PROGRESS_STEP = 4096;
- /** The minimum amount of time that has to elapse before the progress bar gets updated, in ms */
- public static final long MIN_PROGRESS_TIME = 1000;
+ /** The minimum amount of time that has to elapse before the progress bar gets updated, in ms */
+ public static final long MIN_PROGRESS_TIME = 1000;
- /** The maximum number of rows in the database (FIFO) */
- public static final int MAX_DOWNLOADS = 1000;
+ /** The maximum number of rows in the database (FIFO) */
+ public static final int MAX_DOWNLOADS = 1000;
- /**
+ /**
* The number of times that the download manager will retry its network
* operations when no progress is happening before it gives up.
*/
- public static final int MAX_RETRIES = 5;
+ public static final int MAX_RETRIES = 5;
- /**
+ /**
* The minimum amount of time that the download manager accepts for
* a Retry-After response header with a parameter in delta-seconds.
*/
- public static final int MIN_RETRY_AFTER = 30; // 30s
+ public static final int MIN_RETRY_AFTER = 30; // 30s
- /**
+ /**
* The maximum amount of time that the download manager accepts for
* a Retry-After response header with a parameter in delta-seconds.
*/
- public static final int MAX_RETRY_AFTER = 24 * 60 * 60; // 24h
+ public static final int MAX_RETRY_AFTER = 24 * 60 * 60; // 24h
- /**
+ /**
* The maximum number of redirects.
*/
- public static final int MAX_REDIRECTS = 5; // can't be more than 7.
+ public static final int MAX_REDIRECTS = 5; // can't be more than 7.
- /**
+ /**
* The time between a failure and the first retry after an IOException.
* Each subsequent retry grows exponentially, doubling each time.
* The time is in seconds.
*/
- public static final int RETRY_FIRST_DELAY = 30;
+ public static final int RETRY_FIRST_DELAY = 30;
- /** Enable separate connectivity logging */
- public static final boolean LOGX = true;
+ /** Enable separate connectivity logging */
+ public static final boolean LOGX = true;
- /** Enable verbose logging */
- public static final boolean LOGV = false;
+ /** Enable verbose logging */
+ public static final boolean LOGV = false;
- /** Enable super-verbose logging */
- private static final boolean LOCAL_LOGVV = false;
- public static final boolean LOGVV = LOCAL_LOGVV && LOGV;
+ /** Enable super-verbose logging */
+ private static final boolean LOCAL_LOGVV = false;
+ public static final boolean LOGVV = LOCAL_LOGVV && LOGV;
- /**
+ /**
* This download has successfully completed.
* Warning: there might be other status values that indicate success
* in the future.
* Use isSucccess() to capture the entire category.
*/
- public static final int STATUS_SUCCESS = 200;
+ public static final int STATUS_SUCCESS = 200;
- /**
+ /**
* This request couldn't be parsed. This is also used when processing
* requests with unknown/unsupported URI schemes.
*/
- public static final int STATUS_BAD_REQUEST = 400;
+ public static final int STATUS_BAD_REQUEST = 400;
- /**
+ /**
* This download can't be performed because the content type cannot be
* handled.
*/
- public static final int STATUS_NOT_ACCEPTABLE = 406;
+ public static final int STATUS_NOT_ACCEPTABLE = 406;
- /**
+ /**
* This download cannot be performed because the length cannot be
* determined accurately. This is the code for the HTTP error "Length
* Required", which is typically used when making requests that require
@@ -133,101 +135,102 @@ public class Constants {
* accurately (therefore making it impossible to know when a download
* completes).
*/
- public static final int STATUS_LENGTH_REQUIRED = 411;
+ public static final int STATUS_LENGTH_REQUIRED = 411;
- /**
+ /**
* This download was interrupted and cannot be resumed.
* This is the code for the HTTP error "Precondition Failed", and it is
* also used in situations where the client doesn't have an ETag at all.
*/
- public static final int STATUS_PRECONDITION_FAILED = 412;
+ public static final int STATUS_PRECONDITION_FAILED = 412;
- /**
+ /**
* The lowest-valued error status that is not an actual HTTP status code.
*/
- public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;
+ public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;
- /**
+ /**
* The requested destination file already exists.
*/
- public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
+ public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
- /**
+ /**
* Some possibly transient error occurred, but we can't resume the download.
*/
- public static final int STATUS_CANNOT_RESUME = 489;
+ public static final int STATUS_CANNOT_RESUME = 489;
- /**
+ /**
* This download was canceled
*/
- public static final int STATUS_CANCELED = 490;
+ public static final int STATUS_CANCELED = 490;
- /**
+ /**
* This download has completed with an error.
* Warning: there will be other status values that indicate errors in
* the future. Use isStatusError() to capture the entire category.
*/
- public static final int STATUS_UNKNOWN_ERROR = 491;
+ public static final int STATUS_UNKNOWN_ERROR = 491;
- /**
+ /**
* This download couldn't be completed because of a storage issue.
* Typically, that's because the filesystem is missing or full.
* Use the more specific {@link #STATUS_INSUFFICIENT_SPACE_ERROR}
* and {@link #STATUS_DEVICE_NOT_FOUND_ERROR} when appropriate.
*/
- public static final int STATUS_FILE_ERROR = 492;
+ public static final int STATUS_FILE_ERROR = 492;
- /**
+ /**
* This download couldn't be completed because of an HTTP
* redirect response that the download manager couldn't
* handle.
*/
- public static final int STATUS_UNHANDLED_REDIRECT = 493;
+ public static final int STATUS_UNHANDLED_REDIRECT = 493;
- /**
+ /**
* This download couldn't be completed because of an
* unspecified unhandled HTTP code.
*/
- public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
+ public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
- /**
+ /**
* This download couldn't be completed because of an
* error receiving or processing data at the HTTP level.
*/
- public static final int STATUS_HTTP_DATA_ERROR = 495;
+ public static final int STATUS_HTTP_DATA_ERROR = 495;
- /**
+ /**
* This download couldn't be completed because of an
* HttpException while setting up the request.
*/
- public static final int STATUS_HTTP_EXCEPTION = 496;
+ public static final int STATUS_HTTP_EXCEPTION = 496;
- /**
+ /**
* This download couldn't be completed because there were
* too many redirects.
*/
- public static final int STATUS_TOO_MANY_REDIRECTS = 497;
+ public static final int STATUS_TOO_MANY_REDIRECTS = 497;
- /**
+ /**
* This download couldn't be completed due to insufficient storage
* space. Typically, this is because the SD card is full.
*/
- public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
+ public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
- /**
+ /**
* This download couldn't be completed because no external storage
* device was found. Typically, this is because the SD card is not
* mounted.
*/
- public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
+ public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
- /**
+ /**
* The wake duration to check to see if a download is possible.
*/
- public static final long WATCHDOG_WAKE_TIMER = 60 * 1000;
+ public static final long WATCHDOG_WAKE_TIMER = 60*1000;
- /**
+ /**
* The wake duration to check to see if the process was killed.
*/
- public static final long ACTIVE_THREAD_WATCHDOG = 5 * 1000;
+ public static final long ACTIVE_THREAD_WATCHDOG = 5*1000;
+
} \ No newline at end of file
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java
new file mode 100644
index 0000000000..9cb294d721
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+
+/**
+ * This class contains progress information about the active download(s).
+ *
+ * When you build the Activity that initiates a download and tracks the
+ * progress by implementing the {@link IDownloaderClient} interface, you'll
+ * receive a DownloadProgressInfo object in each call to the {@link
+ * IDownloaderClient#onDownloadProgress} method. This allows you to update
+ * your activity's UI with information about the download progress, such
+ * as the progress so far, time remaining and current speed.
+ */
+public class DownloadProgressInfo implements Parcelable {
+ public long mOverallTotal;
+ public long mOverallProgress;
+ public long mTimeRemaining; // time remaining
+ public float mCurrentSpeed; // speed in KB/S
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel p, int i) {
+ p.writeLong(mOverallTotal);
+ p.writeLong(mOverallProgress);
+ p.writeLong(mTimeRemaining);
+ p.writeFloat(mCurrentSpeed);
+ }
+
+ public DownloadProgressInfo(Parcel p) {
+ mOverallTotal = p.readLong();
+ mOverallProgress = p.readLong();
+ mTimeRemaining = p.readLong();
+ mCurrentSpeed = p.readFloat();
+ }
+
+ public DownloadProgressInfo(long overallTotal, long overallProgress,
+ long timeRemaining,
+ float currentSpeed) {
+ this.mOverallTotal = overallTotal;
+ this.mOverallProgress = overallProgress;
+ this.mTimeRemaining = timeRemaining;
+ this.mCurrentSpeed = currentSpeed;
+ }
+
+ public static final Creator<DownloadProgressInfo> CREATOR = new Creator<DownloadProgressInfo>() {
+ @Override
+ public DownloadProgressInfo createFromParcel(Parcel parcel) {
+ return new DownloadProgressInfo(parcel);
+ }
+
+ @Override
+ public DownloadProgressInfo[] newArray(int i) {
+ return new DownloadProgressInfo[i];
+ }
+ };
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
new file mode 100644
index 0000000000..452c7d1483
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader;
+
+import com.google.android.vending.expansion.downloader.impl.DownloaderService;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+// -- GODOT start --
+import java.lang.ref.WeakReference;
+// -- GODOT end --
+
+
+/**
+ * This class binds the service API to your application client. It contains the IDownloaderClient proxy,
+ * which is used to call functions in your client as well as the Stub, which is used to call functions
+ * in the client implementation of IDownloaderClient.
+ *
+ * <p>The IPC is implemented using an Android Messenger and a service Binder. The connect method
+ * should be called whenever the client wants to bind to the service. It opens up a service connection
+ * that ends up calling the onServiceConnected client API that passes the service messenger
+ * in. If the client wants to be notified by the service, it is responsible for then passing its
+ * messenger to the service in a separate call.
+ *
+ * <p>Critical methods are {@link #startDownloadServiceIfRequired} and {@link #CreateStub}.
+ *
+ * <p>When your application first starts, you should first check whether your app's expansion files are
+ * already on the device. If not, you should then call {@link #startDownloadServiceIfRequired}, which
+ * starts your {@link impl.DownloaderService} to download the expansion files if necessary. The method
+ * returns a value indicating whether download is required or not.
+ *
+ * <p>If a download is required, {@link #startDownloadServiceIfRequired} begins the download through
+ * the specified service and you should then call {@link #CreateStub} to instantiate a member {@link
+ * IStub} object that you need in order to receive calls through your {@link IDownloaderClient}
+ * interface.
+ */
+public class DownloaderClientMarshaller {
+ public static final int MSG_ONDOWNLOADSTATE_CHANGED = 10;
+ public static final int MSG_ONDOWNLOADPROGRESS = 11;
+ public static final int MSG_ONSERVICECONNECTED = 12;
+
+ public static final String PARAM_NEW_STATE = "newState";
+ public static final String PARAM_PROGRESS = "progress";
+ public static final String PARAM_MESSENGER = DownloaderService.EXTRA_MESSAGE_HANDLER;
+
+ public static final int NO_DOWNLOAD_REQUIRED = DownloaderService.NO_DOWNLOAD_REQUIRED;
+ public static final int LVL_CHECK_REQUIRED = DownloaderService.LVL_CHECK_REQUIRED;
+ public static final int DOWNLOAD_REQUIRED = DownloaderService.DOWNLOAD_REQUIRED;
+
+ private static class Proxy implements IDownloaderClient {
+ private Messenger mServiceMessenger;
+
+ @Override
+ public void onDownloadStateChanged(int newState) {
+ Bundle params = new Bundle(1);
+ params.putInt(PARAM_NEW_STATE, newState);
+ send(MSG_ONDOWNLOADSTATE_CHANGED, params);
+ }
+
+ @Override
+ public void onDownloadProgress(DownloadProgressInfo progress) {
+ Bundle params = new Bundle(1);
+ params.putParcelable(PARAM_PROGRESS, progress);
+ send(MSG_ONDOWNLOADPROGRESS, params);
+ }
+
+ private void send(int method, Bundle params) {
+ Message m = Message.obtain(null, method);
+ m.setData(params);
+ try {
+ mServiceMessenger.send(m);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Proxy(Messenger msg) {
+ mServiceMessenger = msg;
+ }
+
+ @Override
+ public void onServiceConnected(Messenger m) {
+ /**
+ * This is never called through the proxy.
+ */
+ }
+ }
+
+ private static class Stub implements IStub {
+ private IDownloaderClient mItf = null;
+ private Class<?> mDownloaderServiceClass;
+ private boolean mBound;
+ private Messenger mServiceMessenger;
+ private Context mContext;
+ /**
+ * Target we publish for clients to send messages to IncomingHandler.
+ */
+ // -- GODOT start --
+ private final MessengerHandlerClient mMsgHandler = new MessengerHandlerClient(this);
+ final Messenger mMessenger = new Messenger(mMsgHandler);
+
+ private static class MessengerHandlerClient extends Handler {
+ private final WeakReference<Stub> mDownloader;
+ public MessengerHandlerClient(Stub downloader) {
+ mDownloader = new WeakReference<>(downloader);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Stub downloader = mDownloader.get();
+ if (downloader != null) {
+ downloader.handleMessage(msg);
+ }
+ }
+ }
+
+ private void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ONDOWNLOADPROGRESS:
+ Bundle bun = msg.getData();
+ if (null != mContext) {
+ bun.setClassLoader(mContext.getClassLoader());
+ DownloadProgressInfo dpi = (DownloadProgressInfo)msg.getData()
+ .getParcelable(PARAM_PROGRESS);
+ mItf.onDownloadProgress(dpi);
+ }
+ break;
+ case MSG_ONDOWNLOADSTATE_CHANGED:
+ mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
+ break;
+ case MSG_ONSERVICECONNECTED:
+ mItf.onServiceConnected(
+ (Messenger)msg.getData().getParcelable(PARAM_MESSENGER));
+ break;
+ }
+ }
+ // -- GODOT end --
+
+ public Stub(IDownloaderClient itf, Class<?> downloaderService) {
+ mItf = itf;
+ mDownloaderServiceClass = downloaderService;
+ }
+
+ /**
+ * Class for interacting with the main interface of the service.
+ */
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // This is called when the connection with the service has been
+ // established, giving us the object we can use to
+ // interact with the service. We are communicating with the
+ // service using a Messenger, so here we get a client-side
+ // representation of that from the raw IBinder object.
+ mServiceMessenger = new Messenger(service);
+ mItf.onServiceConnected(
+ mServiceMessenger);
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ mServiceMessenger = null;
+ }
+ };
+
+ @Override
+ public void connect(Context c) {
+ mContext = c;
+ Intent bindIntent = new Intent(c, mDownloaderServiceClass);
+ bindIntent.putExtra(PARAM_MESSENGER, mMessenger);
+ if ( !c.bindService(bindIntent, mConnection, Context.BIND_DEBUG_UNBIND) ) {
+ if ( Constants.LOGVV ) {
+ Log.d(Constants.TAG, "Service Unbound");
+ }
+ } else {
+ mBound = true;
+ }
+
+ }
+
+ @Override
+ public void disconnect(Context c) {
+ if (mBound) {
+ c.unbindService(mConnection);
+ mBound = false;
+ }
+ mContext = null;
+ }
+
+ @Override
+ public Messenger getMessenger() {
+ return mMessenger;
+ }
+ }
+
+ /**
+ * Returns a proxy that will marshal calls to IDownloaderClient methods
+ *
+ * @param msg
+ * @return
+ */
+ public static IDownloaderClient CreateProxy(Messenger msg) {
+ return new Proxy(msg);
+ }
+
+ /**
+ * Returns a stub object that, when connected, will listen for marshaled
+ * {@link IDownloaderClient} methods and translate them into calls to the supplied
+ * interface.
+ *
+ * @param itf An implementation of IDownloaderClient that will be called
+ * when remote method calls are unmarshaled.
+ * @param downloaderService The class for your implementation of {@link
+ * impl.DownloaderService}.
+ * @return The {@link IStub} that allows you to connect to the service such that
+ * your {@link IDownloaderClient} receives status updates.
+ */
+ public static IStub CreateStub(IDownloaderClient itf, Class<?> downloaderService) {
+ return new Stub(itf, downloaderService);
+ }
+
+ /**
+ * Starts the download if necessary. This function starts a flow that does `
+ * many things. 1) Checks to see if the APK version has been checked and
+ * the metadata database updated 2) If the APK version does not match,
+ * checks the new LVL status to see if a new download is required 3) If the
+ * APK version does match, then checks to see if the download(s) have been
+ * completed 4) If the downloads have been completed, returns
+ * NO_DOWNLOAD_REQUIRED The idea is that this can be called during the
+ * startup of an application to quickly ascertain if the application needs
+ * to wait to hear about any updated APK expansion files. Note that this does
+ * mean that the application MUST be run for the first time with a network
+ * connection, even if Market delivers all of the files.
+ *
+ * @param context Your application Context.
+ * @param notificationClient A PendingIntent to start the Activity in your application
+ * that shows the download progress and which will also start the application when download
+ * completes.
+ * @param serviceClass the class of your {@link imp.DownloaderService} implementation
+ * @return whether the service was started and the reason for starting the service.
+ * Either {@link #NO_DOWNLOAD_REQUIRED}, {@link #LVL_CHECK_REQUIRED}, or {@link
+ * #DOWNLOAD_REQUIRED}.
+ * @throws NameNotFoundException
+ */
+ public static int startDownloadServiceIfRequired(Context context, PendingIntent notificationClient,
+ Class<?> serviceClass)
+ throws NameNotFoundException {
+ return DownloaderService.startDownloadServiceIfRequired(context, notificationClient,
+ serviceClass);
+ }
+
+ /**
+ * This version assumes that the intent contains the pending intent as a parameter. This
+ * is used for responding to alarms.
+ * <p>The pending intent must be in an extra with the key {@link
+ * impl.DownloaderService#EXTRA_PENDING_INTENT}.
+ *
+ * @param context
+ * @param notificationClient
+ * @param serviceClass the class of the service to start
+ * @return
+ * @throws NameNotFoundException
+ */
+ public static int startDownloadServiceIfRequired(Context context, Intent notificationClient,
+ Class<?> serviceClass)
+ throws NameNotFoundException {
+ return DownloaderService.startDownloadServiceIfRequired(context, notificationClient,
+ serviceClass);
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
new file mode 100644
index 0000000000..3771d19c9b
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader;
+
+import com.google.android.vending.expansion.downloader.impl.DownloaderService;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+
+// -- GODOT start --
+import java.lang.ref.WeakReference;
+// -- GODOT end --
+
+
+/**
+ * This class is used by the client activity to proxy requests to the Downloader
+ * Service.
+ *
+ * Most importantly, you must call {@link #CreateProxy} during the {@link
+ * IDownloaderClient#onServiceConnected} callback in your activity in order to instantiate
+ * an {@link IDownloaderService} object that you can then use to issue commands to the {@link
+ * DownloaderService} (such as to pause and resume downloads).
+ */
+public class DownloaderServiceMarshaller {
+
+ public static final int MSG_REQUEST_ABORT_DOWNLOAD =
+ 1;
+ public static final int MSG_REQUEST_PAUSE_DOWNLOAD =
+ 2;
+ public static final int MSG_SET_DOWNLOAD_FLAGS =
+ 3;
+ public static final int MSG_REQUEST_CONTINUE_DOWNLOAD =
+ 4;
+ public static final int MSG_REQUEST_DOWNLOAD_STATE =
+ 5;
+ public static final int MSG_REQUEST_CLIENT_UPDATE =
+ 6;
+
+ public static final String PARAMS_FLAGS = "flags";
+ public static final String PARAM_MESSENGER = DownloaderService.EXTRA_MESSAGE_HANDLER;
+
+ private static class Proxy implements IDownloaderService {
+ private Messenger mMsg;
+
+ private void send(int method, Bundle params) {
+ Message m = Message.obtain(null, method);
+ m.setData(params);
+ try {
+ mMsg.send(m);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Proxy(Messenger msg) {
+ mMsg = msg;
+ }
+
+ @Override
+ public void requestAbortDownload() {
+ send(MSG_REQUEST_ABORT_DOWNLOAD, new Bundle());
+ }
+
+ @Override
+ public void requestPauseDownload() {
+ send(MSG_REQUEST_PAUSE_DOWNLOAD, new Bundle());
+ }
+
+ @Override
+ public void setDownloadFlags(int flags) {
+ Bundle params = new Bundle();
+ params.putInt(PARAMS_FLAGS, flags);
+ send(MSG_SET_DOWNLOAD_FLAGS, params);
+ }
+
+ @Override
+ public void requestContinueDownload() {
+ send(MSG_REQUEST_CONTINUE_DOWNLOAD, new Bundle());
+ }
+
+ @Override
+ public void requestDownloadStatus() {
+ send(MSG_REQUEST_DOWNLOAD_STATE, new Bundle());
+ }
+
+ @Override
+ public void onClientUpdated(Messenger clientMessenger) {
+ Bundle bundle = new Bundle(1);
+ bundle.putParcelable(PARAM_MESSENGER, clientMessenger);
+ send(MSG_REQUEST_CLIENT_UPDATE, bundle);
+ }
+ }
+
+ private static class Stub implements IStub {
+ private IDownloaderService mItf = null;
+ // -- GODOT start --
+ private final MessengerHandlerServer mMsgHandler = new MessengerHandlerServer(this);
+ final Messenger mMessenger = new Messenger(mMsgHandler);
+
+ private static class MessengerHandlerServer extends Handler {
+ private final WeakReference<Stub> mDownloader;
+ public MessengerHandlerServer(Stub downloader) {
+ mDownloader = new WeakReference<>(downloader);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Stub downloader = mDownloader.get();
+ if (downloader != null) {
+ downloader.handleMessage(msg);
+ }
+ }
+ }
+
+ private void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_REQUEST_ABORT_DOWNLOAD:
+ mItf.requestAbortDownload();
+ break;
+ case MSG_REQUEST_CONTINUE_DOWNLOAD:
+ mItf.requestContinueDownload();
+ break;
+ case MSG_REQUEST_PAUSE_DOWNLOAD:
+ mItf.requestPauseDownload();
+ break;
+ case MSG_SET_DOWNLOAD_FLAGS:
+ mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
+ break;
+ case MSG_REQUEST_DOWNLOAD_STATE:
+ mItf.requestDownloadStatus();
+ break;
+ case MSG_REQUEST_CLIENT_UPDATE:
+ mItf.onClientUpdated((Messenger)msg.getData().getParcelable(
+ PARAM_MESSENGER));
+ break;
+ }
+ }
+ // -- GODOT end --
+
+ public Stub(IDownloaderService itf) {
+ mItf = itf;
+ }
+
+ @Override
+ public Messenger getMessenger() {
+ return mMessenger;
+ }
+
+ @Override
+ public void connect(Context c) {
+
+ }
+
+ @Override
+ public void disconnect(Context c) {
+
+ }
+ }
+
+ /**
+ * Returns a proxy that will marshall calls to IDownloaderService methods
+ *
+ * @param ctx
+ * @return
+ */
+ public static IDownloaderService CreateProxy(Messenger msg) {
+ return new Proxy(msg);
+ }
+
+ /**
+ * Returns a stub object that, when connected, will listen for marshalled
+ * IDownloaderService methods and translate them into calls to the supplied
+ * interface.
+ *
+ * @param itf An implementation of IDownloaderService that will be called
+ * when remote method calls are unmarshalled.
+ * @return
+ */
+ public static IStub CreateStub(IDownloaderService itf) {
+ return new Stub(itf);
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
new file mode 100644
index 0000000000..2a72c9818d
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.os.Environment;
+import android.os.StatFs;
+import android.os.SystemClock;
+import android.util.Log;
+
+// -- GODOT start --
+//import com.android.vending.expansion.downloader.R;
+import org.godotengine.godot.R;
+// -- GODOT end --
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Random;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Some helper functions for the download manager
+ */
+public class Helpers {
+
+ public static Random sRandom = new Random(SystemClock.uptimeMillis());
+
+ /** Regex used to parse content-disposition headers */
+ private static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern
+ .compile("attachment;\\s*filename\\s*=\\s*\"([^\"]*)\"");
+
+ private Helpers() {
+ }
+
+ /*
+ * Parse the Content-Disposition HTTP Header. The format of the header is defined here:
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
+ * content that is going to be downloaded to the file system. We only support the attachment
+ * type.
+ */
+ static String parseContentDisposition(String contentDisposition) {
+ try {
+ Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);
+ if (m.find()) {
+ return m.group(1);
+ }
+ } catch (IllegalStateException ex) {
+ // This function is defined as returning null when it can't parse
+ // the header
+ }
+ return null;
+ }
+
+ /**
+ * @return the root of the filesystem containing the given path
+ */
+ public static File getFilesystemRoot(String path) {
+ File cache = Environment.getDownloadCacheDirectory();
+ if (path.startsWith(cache.getPath())) {
+ return cache;
+ }
+ File external = Environment.getExternalStorageDirectory();
+ if (path.startsWith(external.getPath())) {
+ return external;
+ }
+ throw new IllegalArgumentException(
+ "Cannot determine filesystem root for " + path);
+ }
+
+ public static boolean isExternalMediaMounted() {
+ if (!Environment.getExternalStorageState().equals(
+ Environment.MEDIA_MOUNTED)) {
+ // No SD card found.
+ if (Constants.LOGVV) {
+ Log.d(Constants.TAG, "no external storage");
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return the number of bytes available on the filesystem rooted at the given File
+ */
+ public static long getAvailableBytes(File root) {
+ StatFs stat = new StatFs(root.getPath());
+ // put a bit of margin (in case creating the file grows the system by a
+ // few blocks)
+ long availableBlocks = (long) stat.getAvailableBlocks() - 4;
+ return stat.getBlockSize() * availableBlocks;
+ }
+
+ /**
+ * Checks whether the filename looks legitimate
+ */
+ public static boolean isFilenameValid(String filename) {
+ filename = filename.replaceFirst("/+", "/"); // normalize leading
+ // slashes
+ return filename.startsWith(Environment.getDownloadCacheDirectory().toString())
+ || filename.startsWith(Environment.getExternalStorageDirectory().toString());
+ }
+
+ /*
+ * Delete the given file from device
+ */
+ /* package */static void deleteFile(String path) {
+ try {
+ File file = new File(path);
+ file.delete();
+ } catch (Exception e) {
+ Log.w(Constants.TAG, "file: '" + path + "' couldn't be deleted", e);
+ }
+ }
+
+ /**
+ * Showing progress in MB here. It would be nice to choose the unit (KB, MB, GB) based on total
+ * file size, but given what we know about the expected ranges of file sizes for APK expansion
+ * files, it's probably not necessary.
+ *
+ * @param overallProgress
+ * @param overallTotal
+ * @return
+ */
+
+ static public String getDownloadProgressString(long overallProgress, long overallTotal) {
+ if (overallTotal == 0) {
+ if (Constants.LOGVV) {
+ Log.e(Constants.TAG, "Notification called when total is zero");
+ }
+ return "";
+ }
+ // -- GODOT start --
+ return String.format(Locale.ENGLISH, "%.2f",
+ (float) overallProgress / (1024.0f * 1024.0f))
+ + "MB /" +
+ String.format(Locale.ENGLISH, "%.2f", (float) overallTotal /
+ (1024.0f * 1024.0f))
+ + "MB";
+ // -- GODOT end --
+ }
+
+ /**
+ * Adds a percentile to getDownloadProgressString.
+ *
+ * @param overallProgress
+ * @param overallTotal
+ * @return
+ */
+ static public String getDownloadProgressStringNotification(long overallProgress,
+ long overallTotal) {
+ if (overallTotal == 0) {
+ if (Constants.LOGVV) {
+ Log.e(Constants.TAG, "Notification called when total is zero");
+ }
+ return "";
+ }
+ return getDownloadProgressString(overallProgress, overallTotal) + " (" +
+ getDownloadProgressPercent(overallProgress, overallTotal) + ")";
+ }
+
+ public static String getDownloadProgressPercent(long overallProgress, long overallTotal) {
+ if (overallTotal == 0) {
+ if (Constants.LOGVV) {
+ Log.e(Constants.TAG, "Notification called when total is zero");
+ }
+ return "";
+ }
+ return Long.toString(overallProgress * 100 / overallTotal) + "%";
+ }
+
+ public static String getSpeedString(float bytesPerMillisecond) {
+ // -- GODOT start --
+ return String.format(Locale.ENGLISH, "%.2f", bytesPerMillisecond * 1000 / 1024);
+ // -- GODOT end --
+ }
+
+ public static String getTimeRemaining(long durationInMilliseconds) {
+ SimpleDateFormat sdf;
+ if (durationInMilliseconds > 1000 * 60 * 60) {
+ sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
+ } else {
+ sdf = new SimpleDateFormat("mm:ss", Locale.getDefault());
+ }
+ return sdf.format(new Date(durationInMilliseconds - TimeZone.getDefault().getRawOffset()));
+ }
+
+ /**
+ * Returns the file name (without full path) for an Expansion APK file from the given context.
+ *
+ * @param c the context
+ * @param mainFile true for main file, false for patch file
+ * @param versionCode the version of the file
+ * @return String the file name of the expansion file
+ */
+ public static String getExpansionAPKFileName(Context c, boolean mainFile, int versionCode) {
+ return (mainFile ? "main." : "patch.") + versionCode + "." + c.getPackageName() + ".obb";
+ }
+
+ /**
+ * Returns the filename (where the file should be saved) from info about a download
+ */
+ static public String generateSaveFileName(Context c, String fileName) {
+ String path = getSaveFilePath(c)
+ + File.separator + fileName;
+ return path;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ static public String getSaveFilePath(Context c) {
+ // This technically existed since Honeycomb, but it is critical
+ // on KitKat and greater versions since it will create the
+ // directory if needed
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ return c.getObbDir().toString();
+ } else {
+ File root = Environment.getExternalStorageDirectory();
+ String path = root.toString() + Constants.EXP_PATH + c.getPackageName();
+ return path;
+ }
+ }
+
+ /**
+ * Helper function to ascertain the existence of a file and return true/false appropriately
+ *
+ * @param c the app/activity/service context
+ * @param fileName the name (sans path) of the file to query
+ * @param fileSize the size that the file must match
+ * @param deleteFileOnMismatch if the file sizes do not match, delete the file
+ * @return true if it does exist, false otherwise
+ */
+ static public boolean doesFileExist(Context c, String fileName, long fileSize,
+ boolean deleteFileOnMismatch) {
+ // the file may have been delivered by Play --- let's make sure
+ // it's the size we expect
+ File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
+ if (fileForNewFile.exists()) {
+ if (fileForNewFile.length() == fileSize) {
+ return true;
+ }
+ if (deleteFileOnMismatch) {
+ // delete the file --- we won't be able to resume
+ // because we cannot confirm the integrity of the file
+ fileForNewFile.delete();
+ }
+ }
+ return false;
+ }
+
+ public static final int FS_READABLE = 0;
+ public static final int FS_DOES_NOT_EXIST = 1;
+ public static final int FS_CANNOT_READ = 2;
+
+ /**
+ * Helper function to ascertain whether a file can be read.
+ *
+ * @param c the app/activity/service context
+ * @param fileName the name (sans path) of the file to query
+ * @return true if it does exist, false otherwise
+ */
+ static public int getFileStatus(Context c, String fileName) {
+ // the file may have been delivered by Play --- let's make sure
+ // it's the size we expect
+ File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
+ int returnValue;
+ if (fileForNewFile.exists()) {
+ if (fileForNewFile.canRead()) {
+ returnValue = FS_READABLE;
+ } else {
+ returnValue = FS_CANNOT_READ;
+ }
+ } else {
+ returnValue = FS_DOES_NOT_EXIST;
+ }
+ return returnValue;
+ }
+
+ /**
+ * Helper function to ascertain whether the application has the correct access to the OBB
+ * directory to allow an OBB file to be written.
+ *
+ * @param c the app/activity/service context
+ * @return true if the application can write an OBB file, false otherwise
+ */
+ static public boolean canWriteOBBFile(Context c) {
+ String path = getSaveFilePath(c);
+ File fileForNewFile = new File(path);
+ boolean canWrite;
+ if (fileForNewFile.exists()) {
+ canWrite = fileForNewFile.isDirectory() && fileForNewFile.canWrite();
+ } else {
+ canWrite = fileForNewFile.mkdirs();
+ }
+ return canWrite;
+ }
+
+ /**
+ * Converts download states that are returned by the
+ * {@link IDownloaderClient#onDownloadStateChanged} callback into usable strings. This is useful
+ * if using the state strings built into the library to display user messages.
+ *
+ * @param state One of the STATE_* constants from {@link IDownloaderClient}.
+ * @return string resource ID for the corresponding string.
+ */
+ static public int getDownloaderStringResourceIDFromState(int state) {
+ switch (state) {
+ case IDownloaderClient.STATE_IDLE:
+ return R.string.state_idle;
+ case IDownloaderClient.STATE_FETCHING_URL:
+ return R.string.state_fetching_url;
+ case IDownloaderClient.STATE_CONNECTING:
+ return R.string.state_connecting;
+ case IDownloaderClient.STATE_DOWNLOADING:
+ return R.string.state_downloading;
+ case IDownloaderClient.STATE_COMPLETED:
+ return R.string.state_completed;
+ case IDownloaderClient.STATE_PAUSED_NETWORK_UNAVAILABLE:
+ return R.string.state_paused_network_unavailable;
+ case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
+ return R.string.state_paused_by_request;
+ case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
+ return R.string.state_paused_wifi_disabled;
+ case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
+ return R.string.state_paused_wifi_unavailable;
+ case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED:
+ return R.string.state_paused_wifi_disabled;
+ case IDownloaderClient.STATE_PAUSED_NEED_WIFI:
+ return R.string.state_paused_wifi_unavailable;
+ case IDownloaderClient.STATE_PAUSED_ROAMING:
+ return R.string.state_paused_roaming;
+ case IDownloaderClient.STATE_PAUSED_NETWORK_SETUP_FAILURE:
+ return R.string.state_paused_network_setup_failure;
+ case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
+ return R.string.state_paused_sdcard_unavailable;
+ case IDownloaderClient.STATE_FAILED_UNLICENSED:
+ return R.string.state_failed_unlicensed;
+ case IDownloaderClient.STATE_FAILED_FETCHING_URL:
+ return R.string.state_failed_fetching_url;
+ case IDownloaderClient.STATE_FAILED_SDCARD_FULL:
+ return R.string.state_failed_sdcard_full;
+ case IDownloaderClient.STATE_FAILED_CANCELED:
+ return R.string.state_failed_cancelled;
+ default:
+ return R.string.state_unknown;
+ }
+ }
+
+}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java
index bae93f633a..cef3794701 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderClient.java
@@ -23,26 +23,26 @@ import android.os.Messenger;
* downloader. It is used to pass status from the service to the client.
*/
public interface IDownloaderClient {
- static final int STATE_IDLE = 1;
- static final int STATE_FETCHING_URL = 2;
- static final int STATE_CONNECTING = 3;
- static final int STATE_DOWNLOADING = 4;
- static final int STATE_COMPLETED = 5;
+ static final int STATE_IDLE = 1;
+ static final int STATE_FETCHING_URL = 2;
+ static final int STATE_CONNECTING = 3;
+ static final int STATE_DOWNLOADING = 4;
+ static final int STATE_COMPLETED = 5;
- static final int STATE_PAUSED_NETWORK_UNAVAILABLE = 6;
- static final int STATE_PAUSED_BY_REQUEST = 7;
+ static final int STATE_PAUSED_NETWORK_UNAVAILABLE = 6;
+ static final int STATE_PAUSED_BY_REQUEST = 7;
- /**
+ /**
* Both STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION and
* STATE_PAUSED_NEED_CELLULAR_PERMISSION imply that Wi-Fi is unavailable and
* cellular permission will restart the service. Wi-Fi disabled means that
* the Wi-Fi manager is returning that Wi-Fi is not enabled, while in the
* other case Wi-Fi is enabled but not available.
*/
- static final int STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION = 8;
- static final int STATE_PAUSED_NEED_CELLULAR_PERMISSION = 9;
+ static final int STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION = 8;
+ static final int STATE_PAUSED_NEED_CELLULAR_PERMISSION = 9;
- /**
+ /**
* Both STATE_PAUSED_WIFI_DISABLED and STATE_PAUSED_NEED_WIFI imply that
* Wi-Fi is unavailable and cellular permission will NOT restart the
* service. Wi-Fi disabled means that the Wi-Fi manager is returning that
@@ -53,27 +53,27 @@ public interface IDownloaderClient {
* developers with very large payloads do not allow these payloads to be
* downloaded over cellular connections.
*/
- static final int STATE_PAUSED_WIFI_DISABLED = 10;
- static final int STATE_PAUSED_NEED_WIFI = 11;
+ static final int STATE_PAUSED_WIFI_DISABLED = 10;
+ static final int STATE_PAUSED_NEED_WIFI = 11;
- static final int STATE_PAUSED_ROAMING = 12;
+ static final int STATE_PAUSED_ROAMING = 12;
- /**
+ /**
* Scary case. We were on a network that redirected us to another website
* that delivered us the wrong file.
*/
- static final int STATE_PAUSED_NETWORK_SETUP_FAILURE = 13;
+ static final int STATE_PAUSED_NETWORK_SETUP_FAILURE = 13;
- static final int STATE_PAUSED_SDCARD_UNAVAILABLE = 14;
+ static final int STATE_PAUSED_SDCARD_UNAVAILABLE = 14;
- static final int STATE_FAILED_UNLICENSED = 15;
- static final int STATE_FAILED_FETCHING_URL = 16;
- static final int STATE_FAILED_SDCARD_FULL = 17;
- static final int STATE_FAILED_CANCELED = 18;
+ static final int STATE_FAILED_UNLICENSED = 15;
+ static final int STATE_FAILED_FETCHING_URL = 16;
+ static final int STATE_FAILED_SDCARD_FULL = 17;
+ static final int STATE_FAILED_CANCELED = 18;
- static final int STATE_FAILED = 19;
+ static final int STATE_FAILED = 19;
- /**
+ /**
* Called internally by the stub when the service is bound to the client.
* <p>
* Critical implementation detail. In onServiceConnected we create the
@@ -90,9 +90,9 @@ public interface IDownloaderClient {
* @param m the service Messenger. This Messenger is used to call the
* service API from the client.
*/
- void onServiceConnected(Messenger m);
+ void onServiceConnected(Messenger m);
- /**
+ /**
* Called when the download state changes. Depending on the state, there may
* be user requests. The service is free to change the download state in the
* middle of a user request, so the client should be able to handle this.
@@ -112,9 +112,9 @@ public interface IDownloaderClient {
*
* @param newState one of the STATE_* values defined in IDownloaderClient
*/
- void onDownloadStateChanged(int newState);
+ void onDownloadStateChanged(int newState);
- /**
+ /**
* Shows the download progress. This is intended to be used to fill out a
* client UI. This progress should only be shown in a few states such as
* STATE_DOWNLOADING.
@@ -122,5 +122,5 @@ public interface IDownloaderClient {
* @param progress the DownloadProgressInfo object containing the current
* progress of all downloads.
*/
- void onDownloadProgress(DownloadProgressInfo progress);
+ void onDownloadProgress(DownloadProgressInfo progress);
}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderService.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderService.java
index a84fb32728..4de9de0c62 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/IDownloaderService.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IDownloaderService.java
@@ -31,47 +31,47 @@ import android.os.Messenger;
* should immediately call {@link #onClientUpdated}.
*/
public interface IDownloaderService {
- /**
+ /**
* Set this flag in response to the
* IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION state and then
* call RequestContinueDownload to resume a download
*/
- public static final int FLAGS_DOWNLOAD_OVER_CELLULAR = 1;
+ public static final int FLAGS_DOWNLOAD_OVER_CELLULAR = 1;
- /**
+ /**
* Request that the service abort the current download. The service should
* respond by changing the state to {@link IDownloaderClient.STATE_ABORTED}.
*/
- void requestAbortDownload();
+ void requestAbortDownload();
- /**
+ /**
* Request that the service pause the current download. The service should
* respond by changing the state to
* {@link IDownloaderClient.STATE_PAUSED_BY_REQUEST}.
*/
- void requestPauseDownload();
+ void requestPauseDownload();
- /**
+ /**
* Request that the service continue a paused download, when in any paused
* or failed state, including
* {@link IDownloaderClient.STATE_PAUSED_BY_REQUEST}.
*/
- void requestContinueDownload();
+ void requestContinueDownload();
- /**
+ /**
* Set the flags for this download (e.g.
* {@link DownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR}).
*
* @param flags
*/
- void setDownloadFlags(int flags);
+ void setDownloadFlags(int flags);
- /**
+ /**
* Requests that the download status be sent to the client.
*/
- void requestDownloadStatus();
+ void requestDownloadStatus();
- /**
+ /**
* Call this when you get {@link
* IDownloaderClient.onServiceConnected(Messenger m)} from the
* DownloaderClient to register the client with the service. It will
@@ -79,5 +79,5 @@ public interface IDownloaderService {
*
* @param clientMessenger
*/
- void onClientUpdated(Messenger clientMessenger);
+ void onClientUpdated(Messenger clientMessenger);
}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/IStub.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IStub.java
index dcdef1bfcf..d5bc3a843e 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/IStub.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/IStub.java
@@ -33,9 +33,9 @@ import android.os.Messenger;
* {@link IDownloaderService#onClientUpdated}.
*/
public interface IStub {
- Messenger getMessenger();
+ Messenger getMessenger();
- void connect(Context c);
+ void connect(Context c);
- void disconnect(Context c);
+ void disconnect(Context c);
}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/SystemFacade.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/SystemFacade.java
new file mode 100644
index 0000000000..a0e1165cc4
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/SystemFacade.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+// -- GODOT start --
+import android.annotation.SuppressLint;
+// -- GODOT end --
+
+/**
+ * Contains useful helper functions, typically tied to the application context.
+ */
+class SystemFacade {
+ private Context mContext;
+ private NotificationManager mNotificationManager;
+
+ public SystemFacade(Context context) {
+ mContext = context;
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ public Integer getActiveNetworkType() {
+ ConnectivityManager connectivity =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity == null) {
+ Log.w(Constants.TAG, "couldn't get connectivity manager");
+ return null;
+ }
+
+ @SuppressLint("MissingPermission")
+ NetworkInfo activeInfo = connectivity.getActiveNetworkInfo();
+ if (activeInfo == null) {
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG, "network is not available");
+ }
+ return null;
+ }
+ return activeInfo.getType();
+ }
+
+ public boolean isNetworkRoaming() {
+ ConnectivityManager connectivity =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity == null) {
+ Log.w(Constants.TAG, "couldn't get connectivity manager");
+ return false;
+ }
+
+ @SuppressLint("MissingPermission")
+ NetworkInfo info = connectivity.getActiveNetworkInfo();
+ boolean isMobile = (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE);
+ TelephonyManager tm = (TelephonyManager) mContext
+ .getSystemService(Context.TELEPHONY_SERVICE);
+ if (null == tm) {
+ Log.w(Constants.TAG, "couldn't get telephony manager");
+ return false;
+ }
+ boolean isRoaming = isMobile && tm.isNetworkRoaming();
+ if (Constants.LOGVV && isRoaming) {
+ Log.v(Constants.TAG, "network is roaming");
+ }
+ return isRoaming;
+ }
+
+ public Long getMaxBytesOverMobile() {
+ return (long) Integer.MAX_VALUE;
+ }
+
+ public Long getRecommendedMaxBytesOverMobile() {
+ return 2097152L;
+ }
+
+ public void sendBroadcast(Intent intent) {
+ mContext.sendBroadcast(intent);
+ }
+
+ public boolean userOwnsPackage(int uid, String packageName) throws NameNotFoundException {
+ return mContext.getPackageManager().getApplicationInfo(packageName, 0).uid == uid;
+ }
+
+ public void postNotification(long id, Notification notification) {
+ /**
+ * TODO: The system notification manager takes ints, not longs, as IDs,
+ * but the download manager uses IDs take straight from the database,
+ * which are longs. This will have to be dealt with at some point.
+ */
+ mNotificationManager.notify((int) id, notification);
+ }
+
+ public void cancelNotification(long id) {
+ mNotificationManager.cancel((int) id);
+ }
+
+ public void cancelAllNotifications() {
+ mNotificationManager.cancelAll();
+ }
+
+ public void startThread(Thread thread) {
+ thread.start();
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java
new file mode 100644
index 0000000000..3ccc191c60
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * This service differs from IntentService in a few minor ways/ It will not
+ * auto-stop itself after the intent is handled unless the target returns "true"
+ * in should stop. Since the goal of this service is to handle a single kind of
+ * intent, it does not queue up batches of intents of the same type.
+ */
+public abstract class CustomIntentService extends Service {
+ private String mName;
+ private boolean mRedelivery;
+ private volatile ServiceHandler mServiceHandler;
+ private volatile Looper mServiceLooper;
+ private static final String LOG_TAG = "CustomIntentService";
+ private static final int WHAT_MESSAGE = -10;
+
+ public CustomIntentService(String paramString) {
+ this.mName = paramString;
+ }
+
+ @Override
+ public IBinder onBind(Intent paramIntent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ HandlerThread localHandlerThread = new HandlerThread("IntentService["
+ + this.mName + "]");
+ localHandlerThread.start();
+ this.mServiceLooper = localHandlerThread.getLooper();
+ this.mServiceHandler = new ServiceHandler(this.mServiceLooper);
+ }
+
+ @Override
+ public void onDestroy() {
+ Thread localThread = this.mServiceLooper.getThread();
+ if ((localThread != null) && (localThread.isAlive())) {
+ localThread.interrupt();
+ }
+ this.mServiceLooper.quit();
+ Log.d(LOG_TAG, "onDestroy");
+ }
+
+ protected abstract void onHandleIntent(Intent paramIntent);
+
+ protected abstract boolean shouldStop();
+
+ @Override
+ public void onStart(Intent paramIntent, int startId) {
+ if (!this.mServiceHandler.hasMessages(WHAT_MESSAGE)) {
+ Message localMessage = this.mServiceHandler.obtainMessage();
+ localMessage.arg1 = startId;
+ localMessage.obj = paramIntent;
+ localMessage.what = WHAT_MESSAGE;
+ this.mServiceHandler.sendMessage(localMessage);
+ }
+ }
+
+ @Override
+ public int onStartCommand(Intent paramIntent, int flags, int startId) {
+ onStart(paramIntent, startId);
+ return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
+ }
+
+ public void setIntentRedelivery(boolean enabled) {
+ this.mRedelivery = enabled;
+ }
+
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message paramMessage) {
+ CustomIntentService.this
+ .onHandleIntent((Intent) paramMessage.obj);
+ if (shouldStop()) {
+ Log.d(LOG_TAG, "stopSelf");
+ CustomIntentService.this.stopSelf(paramMessage.arg1);
+ Log.d(LOG_TAG, "afterStopSelf");
+ }
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java
new file mode 100644
index 0000000000..45111b16a3
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import com.google.android.vending.expansion.downloader.Constants;
+import com.google.android.vending.expansion.downloader.Helpers;
+
+import android.util.Log;
+
+/**
+ * Representation of information about an individual download from the database.
+ */
+public class DownloadInfo {
+ public String mUri;
+ public final int mIndex;
+ public final String mFileName;
+ public String mETag;
+ public long mTotalBytes;
+ public long mCurrentBytes;
+ public long mLastMod;
+ public int mStatus;
+ public int mControl;
+ public int mNumFailed;
+ public int mRetryAfter;
+ public int mRedirectCount;
+
+ boolean mInitialized;
+
+ public int mFuzz;
+
+ public DownloadInfo(int index, String fileName, String pkg) {
+ mFuzz = Helpers.sRandom.nextInt(1001);
+ mFileName = fileName;
+ mIndex = index;
+ }
+
+ public void resetDownload() {
+ mCurrentBytes = 0;
+ mETag = "";
+ mLastMod = 0;
+ mStatus = 0;
+ mControl = 0;
+ mNumFailed = 0;
+ mRetryAfter = 0;
+ mRedirectCount = 0;
+ }
+
+ /**
+ * Returns the time when a download should be restarted.
+ */
+ public long restartTime(long now) {
+ if (mNumFailed == 0) {
+ return now;
+ }
+ if (mRetryAfter > 0) {
+ return mLastMod + mRetryAfter;
+ }
+ return mLastMod +
+ Constants.RETRY_FIRST_DELAY *
+ (1000 + mFuzz) * (1 << (mNumFailed - 1));
+ }
+
+ public void logVerboseInfo() {
+ Log.v(Constants.TAG, "Service adding new entry");
+ Log.v(Constants.TAG, "FILENAME: " + mFileName);
+ Log.v(Constants.TAG, "URI : " + mUri);
+ Log.v(Constants.TAG, "FILENAME: " + mFileName);
+ Log.v(Constants.TAG, "CONTROL : " + mControl);
+ Log.v(Constants.TAG, "STATUS : " + mStatus);
+ Log.v(Constants.TAG, "FAILED_C: " + mNumFailed);
+ Log.v(Constants.TAG, "RETRY_AF: " + mRetryAfter);
+ Log.v(Constants.TAG, "REDIRECT: " + mRedirectCount);
+ Log.v(Constants.TAG, "LAST_MOD: " + mLastMod);
+ Log.v(Constants.TAG, "TOTAL : " + mTotalBytes);
+ Log.v(Constants.TAG, "CURRENT : " + mCurrentBytes);
+ Log.v(Constants.TAG, "ETAG : " + mETag);
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
new file mode 100644
index 0000000000..0abaf2e052
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+// -- GODOT start --
+//import com.android.vending.expansion.downloader.R;
+import org.godotengine.godot.R;
+// -- GODOT end --
+
+import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
+import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
+import com.google.android.vending.expansion.downloader.Helpers;
+import com.google.android.vending.expansion.downloader.IDownloaderClient;
+
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.os.Build;
+import android.os.Messenger;
+import android.support.v4.app.NotificationCompat;
+
+/**
+ * This class handles displaying the notification associated with the download
+ * queue going on in the download manager. It handles multiple status types;
+ * Some require user interaction and some do not. Some of the user interactions
+ * may be transient. (for example: the user is queried to continue the download
+ * on 3G when it started on WiFi, but then the phone locks onto WiFi again so
+ * the prompt automatically goes away)
+ * <p/>
+ * The application interface for the downloader also needs to understand and
+ * handle these transient states.
+ */
+public class DownloadNotification implements IDownloaderClient {
+
+ private int mState;
+ private final Context mContext;
+ private final NotificationManager mNotificationManager;
+ private CharSequence mCurrentTitle;
+
+ private IDownloaderClient mClientProxy;
+ private NotificationCompat.Builder mActiveDownloadBuilder;
+ private NotificationCompat.Builder mBuilder;
+ private NotificationCompat.Builder mCurrentBuilder;
+ private CharSequence mLabel;
+ private String mCurrentText;
+ private DownloadProgressInfo mProgressInfo;
+ private PendingIntent mContentIntent;
+
+ static final String LOGTAG = "DownloadNotification";
+ static final int NOTIFICATION_ID = LOGTAG.hashCode();
+
+ public PendingIntent getClientIntent() {
+ return mContentIntent;
+ }
+
+ public void setClientIntent(PendingIntent clientIntent) {
+ this.mBuilder.setContentIntent(clientIntent);
+ this.mActiveDownloadBuilder.setContentIntent(clientIntent);
+ this.mContentIntent = clientIntent;
+ }
+
+ public void resendState() {
+ if (null != mClientProxy) {
+ mClientProxy.onDownloadStateChanged(mState);
+ }
+ }
+
+ @Override
+ public void onDownloadStateChanged(int newState) {
+ if (null != mClientProxy) {
+ mClientProxy.onDownloadStateChanged(newState);
+ }
+ if (newState != mState) {
+ mState = newState;
+ if (newState == IDownloaderClient.STATE_IDLE || null == mContentIntent) {
+ return;
+ }
+ int stringDownloadID;
+ int iconResource;
+ boolean ongoingEvent;
+
+ // get the new title string and paused text
+ switch (newState) {
+ case 0:
+ iconResource = android.R.drawable.stat_sys_warning;
+ stringDownloadID = R.string.state_unknown;
+ ongoingEvent = false;
+ break;
+
+ case IDownloaderClient.STATE_DOWNLOADING:
+ iconResource = android.R.drawable.stat_sys_download;
+ stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
+ ongoingEvent = true;
+ break;
+
+ case IDownloaderClient.STATE_FETCHING_URL:
+ case IDownloaderClient.STATE_CONNECTING:
+ iconResource = android.R.drawable.stat_sys_download_done;
+ stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
+ ongoingEvent = true;
+ break;
+
+ case IDownloaderClient.STATE_COMPLETED:
+ case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
+ iconResource = android.R.drawable.stat_sys_download_done;
+ stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
+ ongoingEvent = false;
+ break;
+
+ case IDownloaderClient.STATE_FAILED:
+ case IDownloaderClient.STATE_FAILED_CANCELED:
+ case IDownloaderClient.STATE_FAILED_FETCHING_URL:
+ case IDownloaderClient.STATE_FAILED_SDCARD_FULL:
+ case IDownloaderClient.STATE_FAILED_UNLICENSED:
+ iconResource = android.R.drawable.stat_sys_warning;
+ stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
+ ongoingEvent = false;
+ break;
+
+ default:
+ iconResource = android.R.drawable.stat_sys_warning;
+ stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
+ ongoingEvent = true;
+ break;
+ }
+
+ mCurrentText = mContext.getString(stringDownloadID);
+ mCurrentTitle = mLabel;
+ mCurrentBuilder.setTicker(mLabel + ": " + mCurrentText);
+ mCurrentBuilder.setSmallIcon(iconResource);
+ mCurrentBuilder.setContentTitle(mCurrentTitle);
+ mCurrentBuilder.setContentText(mCurrentText);
+ if (ongoingEvent) {
+ mCurrentBuilder.setOngoing(true);
+ } else {
+ mCurrentBuilder.setOngoing(false);
+ mCurrentBuilder.setAutoCancel(true);
+ }
+ mNotificationManager.notify(NOTIFICATION_ID, mCurrentBuilder.build());
+ }
+ }
+
+ @Override
+ public void onDownloadProgress(DownloadProgressInfo progress) {
+ mProgressInfo = progress;
+ if (null != mClientProxy) {
+ mClientProxy.onDownloadProgress(progress);
+ }
+ if (progress.mOverallTotal <= 0) {
+ // we just show the text
+ mBuilder.setTicker(mCurrentTitle);
+ mBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
+ mBuilder.setContentTitle(mCurrentTitle);
+ mBuilder.setContentText(mCurrentText);
+ mCurrentBuilder = mBuilder;
+ } else {
+ mActiveDownloadBuilder.setProgress((int) progress.mOverallTotal, (int) progress.mOverallProgress, false);
+ mActiveDownloadBuilder.setContentText(Helpers.getDownloadProgressString(progress.mOverallProgress, progress.mOverallTotal));
+ mActiveDownloadBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
+ mActiveDownloadBuilder.setTicker(mLabel + ": " + mCurrentText);
+ mActiveDownloadBuilder.setContentTitle(mLabel);
+ mActiveDownloadBuilder.setContentInfo(mContext.getString(R.string.time_remaining_notification,
+ Helpers.getTimeRemaining(progress.mTimeRemaining)));
+ mCurrentBuilder = mActiveDownloadBuilder;
+ }
+ mNotificationManager.notify(NOTIFICATION_ID, mCurrentBuilder.build());
+ }
+
+ /**
+ * Called in response to onClientUpdated. Creates a new proxy and notifies
+ * it of the current state.
+ *
+ * @param msg the client Messenger to notify
+ */
+ public void setMessenger(Messenger msg) {
+ mClientProxy = DownloaderClientMarshaller.CreateProxy(msg);
+ if (null != mProgressInfo) {
+ mClientProxy.onDownloadProgress(mProgressInfo);
+ }
+ if (mState != -1) {
+ mClientProxy.onDownloadStateChanged(mState);
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param ctx The context to use to obtain access to the Notification
+ * Service
+ */
+ DownloadNotification(Context ctx, CharSequence applicationLabel) {
+ mState = -1;
+ mContext = ctx;
+ mLabel = applicationLabel;
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ mActiveDownloadBuilder = new NotificationCompat.Builder(ctx);
+ mBuilder = new NotificationCompat.Builder(ctx);
+
+ // Set Notification category and priorities to something that makes sense for a long
+ // lived background task.
+ mActiveDownloadBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
+ mActiveDownloadBuilder.setCategory(NotificationCompat.CATEGORY_PROGRESS);
+
+ mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
+ mBuilder.setCategory(NotificationCompat.CATEGORY_PROGRESS);
+
+ mCurrentBuilder = mBuilder;
+ }
+
+ @Override
+ public void onServiceConnected(Messenger m) {
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
new file mode 100644
index 0000000000..c114b8a64a
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
@@ -0,0 +1,852 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import com.google.android.vending.expansion.downloader.Constants;
+import com.google.android.vending.expansion.downloader.Helpers;
+import com.google.android.vending.expansion.downloader.IDownloaderClient;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.os.Process;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SyncFailedException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Locale;
+
+/**
+ * Runs an actual download
+ */
+public class DownloadThread {
+
+ private Context mContext;
+ private DownloadInfo mInfo;
+ private DownloaderService mService;
+ private final DownloadsDB mDB;
+ private final DownloadNotification mNotification;
+ private String mUserAgent;
+
+ public DownloadThread(DownloadInfo info, DownloaderService service,
+ DownloadNotification notification) {
+ mContext = service;
+ mInfo = info;
+ mService = service;
+ mNotification = notification;
+ mDB = DownloadsDB.getDB(service);
+ mUserAgent = "APKXDL (Linux; U; Android " + android.os.Build.VERSION.RELEASE + ";"
+ + Locale.getDefault().toString() + "; " + android.os.Build.DEVICE + "/"
+ + android.os.Build.ID + ")" +
+ service.getPackageName();
+ }
+
+ /**
+ * Returns the default user agent
+ */
+ private String userAgent() {
+ return mUserAgent;
+ }
+
+ /**
+ * State for the entire run() method.
+ */
+ private static class State {
+ public String mFilename;
+ public FileOutputStream mStream;
+ public boolean mCountRetry = false;
+ public int mRetryAfter = 0;
+ public int mRedirectCount = 0;
+ public String mNewUri;
+ public boolean mGotData = false;
+ public String mRequestUri;
+
+ public State(DownloadInfo info, DownloaderService service) {
+ mRedirectCount = info.mRedirectCount;
+ mRequestUri = info.mUri;
+ mFilename = service.generateTempSaveFileName(info.mFileName);
+ }
+ }
+
+ /**
+ * State within executeDownload()
+ */
+ private static class InnerState {
+ public int mBytesSoFar = 0;
+ public int mBytesThisSession = 0;
+ public String mHeaderETag;
+ public boolean mContinuingDownload = false;
+ public String mHeaderContentLength;
+ public String mHeaderContentDisposition;
+ public String mHeaderContentLocation;
+ public int mBytesNotified = 0;
+ public long mTimeLastNotification = 0;
+ }
+
+ /**
+ * Raised from methods called by run() to indicate that the current request
+ * should be stopped immediately. Note the message passed to this exception
+ * will be logged and therefore must be guaranteed not to contain any PII,
+ * meaning it generally can't include any information about the request URI,
+ * headers, or destination filename.
+ */
+ private class StopRequest extends Throwable {
+
+ private static final long serialVersionUID = 6338592678988347973L;
+ public int mFinalStatus;
+
+ public StopRequest(int finalStatus, String message) {
+ super(message);
+ mFinalStatus = finalStatus;
+ }
+
+ public StopRequest(int finalStatus, String message, Throwable throwable) {
+ super(message, throwable);
+ mFinalStatus = finalStatus;
+ }
+ }
+
+ /**
+ * Raised from methods called by executeDownload() to indicate that the
+ * download should be retried immediately.
+ */
+ private class RetryDownload extends Throwable {
+
+ private static final long serialVersionUID = 6196036036517540229L;
+ }
+
+ /**
+ * Executes the download in a separate thread
+ */
+ public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+ State state = new State(mInfo, mService);
+ PowerManager.WakeLock wakeLock = null;
+ int finalStatus = DownloaderService.STATUS_UNKNOWN_ERROR;
+
+ try {
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ // -- GODOT start --
+ //wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
+ //wakeLock.acquire();
+ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "org.godot.game:wakelock");
+ wakeLock.acquire(20 * 60 * 1000L /*20 minutes*/);
+ // -- GODOT end --
+
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
+ Log.v(Constants.TAG, " at " + mInfo.mUri);
+ }
+
+ boolean finished = false;
+ while (!finished) {
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
+ Log.v(Constants.TAG, " at " + mInfo.mUri);
+ }
+ // Set or unset proxy, which may have changed since last GET
+ // request.
+ // setDefaultProxy() supports null as proxy parameter.
+ URL url = new URL(state.mRequestUri);
+ HttpURLConnection request = (HttpURLConnection)url.openConnection();
+ request.setRequestProperty("User-Agent", userAgent());
+ try {
+ executeDownload(state, request);
+ finished = true;
+ } catch (RetryDownload exc) {
+ // fall through
+ } finally {
+ request.disconnect();
+ request = null;
+ }
+ }
+
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "download completed for " + mInfo.mFileName);
+ Log.v(Constants.TAG, " at " + mInfo.mUri);
+ }
+ finalizeDestinationFile(state);
+ finalStatus = DownloaderService.STATUS_SUCCESS;
+ } catch (StopRequest error) {
+ // remove the cause before printing, in case it contains PII
+ Log.w(Constants.TAG,
+ "Aborting request for download " + mInfo.mFileName + ": " + error.getMessage());
+ error.printStackTrace();
+ finalStatus = error.mFinalStatus;
+ // fall through to finally block
+ } catch (Throwable ex) { // sometimes the socket code throws unchecked
+ // exceptions
+ Log.w(Constants.TAG, "Exception for " + mInfo.mFileName + ": " + ex);
+ finalStatus = DownloaderService.STATUS_UNKNOWN_ERROR;
+ // falls through to the code that reports an error
+ } finally {
+ if (wakeLock != null) {
+ wakeLock.release();
+ wakeLock = null;
+ }
+ cleanupDestination(state, finalStatus);
+ notifyDownloadCompleted(finalStatus, state.mCountRetry, state.mRetryAfter,
+ state.mRedirectCount, state.mGotData, state.mFilename);
+ }
+ }
+
+ /**
+ * Fully execute a single download request - setup and send the request,
+ * handle the response, and transfer the data to the destination file.
+ */
+ private void executeDownload(State state, HttpURLConnection request)
+ throws StopRequest, RetryDownload {
+ InnerState innerState = new InnerState();
+ byte data[] = new byte[Constants.BUFFER_SIZE];
+
+ checkPausedOrCanceled(state);
+
+ setupDestinationFile(state, innerState);
+ addRequestHeaders(innerState, request);
+
+ // check just before sending the request to avoid using an invalid
+ // connection at all
+ checkConnectivity(state);
+
+ mNotification.onDownloadStateChanged(IDownloaderClient.STATE_CONNECTING);
+ int responseCode = sendRequest(state, request);
+ handleExceptionalStatus(state, innerState, request, responseCode);
+
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "received response for " + mInfo.mUri);
+ }
+
+ processResponseHeaders(state, innerState, request);
+ InputStream entityStream = openResponseEntity(state, request);
+ mNotification.onDownloadStateChanged(IDownloaderClient.STATE_DOWNLOADING);
+ transferData(state, innerState, data, entityStream);
+ }
+
+ /**
+ * Check if current connectivity is valid for this request.
+ */
+ private void checkConnectivity(State state) throws StopRequest {
+ switch (mService.getNetworkAvailabilityState(mDB)) {
+ case DownloaderService.NETWORK_OK:
+ return;
+ case DownloaderService.NETWORK_NO_CONNECTION:
+ throw new StopRequest(DownloaderService.STATUS_WAITING_FOR_NETWORK,
+ "waiting for network to return");
+ case DownloaderService.NETWORK_TYPE_DISALLOWED_BY_REQUESTOR:
+ throw new StopRequest(
+ DownloaderService.STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION,
+ "waiting for wifi or for download over cellular to be authorized");
+ case DownloaderService.NETWORK_CANNOT_USE_ROAMING:
+ throw new StopRequest(DownloaderService.STATUS_WAITING_FOR_NETWORK,
+ "roaming is not allowed");
+ case DownloaderService.NETWORK_UNUSABLE_DUE_TO_SIZE:
+ throw new StopRequest(DownloaderService.STATUS_QUEUED_FOR_WIFI, "waiting for wifi");
+ }
+ }
+
+ /**
+ * Transfer as much data as possible from the HTTP response to the
+ * destination file.
+ *
+ * @param data buffer to use to read data
+ * @param entityStream stream for reading the HTTP response entity
+ */
+ private void transferData(State state, InnerState innerState, byte[] data,
+ InputStream entityStream) throws StopRequest {
+ for (;;) {
+ int bytesRead = readFromResponse(state, innerState, data, entityStream);
+ if (bytesRead == -1) { // success, end of stream already reached
+ handleEndOfStream(state, innerState);
+ return;
+ }
+
+ state.mGotData = true;
+ writeDataToDestination(state, data, bytesRead);
+ innerState.mBytesSoFar += bytesRead;
+ innerState.mBytesThisSession += bytesRead;
+ reportProgress(state, innerState);
+
+ checkPausedOrCanceled(state);
+ }
+ }
+
+ /**
+ * Called after a successful completion to take any necessary action on the
+ * downloaded file.
+ */
+ private void finalizeDestinationFile(State state) throws StopRequest {
+ syncDestination(state);
+ String tempFilename = state.mFilename;
+ String finalFilename = Helpers.generateSaveFileName(mService, mInfo.mFileName);
+ if (!state.mFilename.equals(finalFilename)) {
+ File startFile = new File(tempFilename);
+ File destFile = new File(finalFilename);
+ if (mInfo.mTotalBytes != -1 && mInfo.mCurrentBytes == mInfo.mTotalBytes) {
+ if (!startFile.renameTo(destFile)) {
+ throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
+ "unable to finalize destination file");
+ }
+ } else {
+ throw new StopRequest(DownloaderService.STATUS_FILE_DELIVERED_INCORRECTLY,
+ "file delivered with incorrect size. probably due to network not browser configured");
+ }
+ }
+ }
+
+ /**
+ * Called just before the thread finishes, regardless of status, to take any
+ * necessary action on the downloaded file.
+ */
+ private void cleanupDestination(State state, int finalStatus) {
+ closeDestination(state);
+ if (state.mFilename != null && DownloaderService.isStatusError(finalStatus)) {
+ new File(state.mFilename).delete();
+ state.mFilename = null;
+ }
+ }
+
+ /**
+ * Sync the destination file to storage.
+ */
+ private void syncDestination(State state) {
+ FileOutputStream downloadedFileStream = null;
+ try {
+ downloadedFileStream = new FileOutputStream(state.mFilename, true);
+ downloadedFileStream.getFD().sync();
+ } catch (FileNotFoundException ex) {
+ Log.w(Constants.TAG, "file " + state.mFilename + " not found: " + ex);
+ } catch (SyncFailedException ex) {
+ Log.w(Constants.TAG, "file " + state.mFilename + " sync failed: " + ex);
+ } catch (IOException ex) {
+ Log.w(Constants.TAG, "IOException trying to sync " + state.mFilename + ": " + ex);
+ } catch (RuntimeException ex) {
+ Log.w(Constants.TAG, "exception while syncing file: ", ex);
+ } finally {
+ if (downloadedFileStream != null) {
+ try {
+ downloadedFileStream.close();
+ } catch (IOException ex) {
+ Log.w(Constants.TAG, "IOException while closing synced file: ", ex);
+ } catch (RuntimeException ex) {
+ Log.w(Constants.TAG, "exception while closing file: ", ex);
+ }
+ }
+ }
+ }
+
+ /**
+ * Close the destination output stream.
+ */
+ private void closeDestination(State state) {
+ try {
+ // close the file
+ if (state.mStream != null) {
+ state.mStream.close();
+ state.mStream = null;
+ }
+ } catch (IOException ex) {
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "exception when closing the file after download : " + ex);
+ }
+ // nothing can really be done if the file can't be closed
+ }
+ }
+
+ /**
+ * Check if the download has been paused or canceled, stopping the request
+ * appropriately if it has been.
+ */
+ private void checkPausedOrCanceled(State state) throws StopRequest {
+ if (mService.getControl() == DownloaderService.CONTROL_PAUSED) {
+ int status = mService.getStatus();
+ switch (status) {
+ case DownloaderService.STATUS_PAUSED_BY_APP:
+ throw new StopRequest(mService.getStatus(),
+ "download paused");
+ }
+ }
+ }
+
+ /**
+ * Report download progress through the database if necessary.
+ */
+ private void reportProgress(State state, InnerState innerState) {
+ long now = System.currentTimeMillis();
+ if (innerState.mBytesSoFar - innerState.mBytesNotified
+ > Constants.MIN_PROGRESS_STEP
+ && now - innerState.mTimeLastNotification
+ > Constants.MIN_PROGRESS_TIME) {
+ // we store progress updates to the database here
+ mInfo.mCurrentBytes = innerState.mBytesSoFar;
+ mDB.updateDownloadCurrentBytes(mInfo);
+
+ innerState.mBytesNotified = innerState.mBytesSoFar;
+ innerState.mTimeLastNotification = now;
+
+ long totalBytesSoFar = innerState.mBytesThisSession + mService.mBytesSoFar;
+
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG, "downloaded " + mInfo.mCurrentBytes + " out of "
+ + mInfo.mTotalBytes);
+ Log.v(Constants.TAG, " total " + totalBytesSoFar + " out of "
+ + mService.mTotalLength);
+ }
+
+ mService.notifyUpdateBytes(totalBytesSoFar);
+ }
+ }
+
+ /**
+ * Write a data buffer to the destination file.
+ *
+ * @param data buffer containing the data to write
+ * @param bytesRead how many bytes to write from the buffer
+ */
+ private void writeDataToDestination(State state, byte[] data, int bytesRead)
+ throws StopRequest {
+ for (;;) {
+ try {
+ if (state.mStream == null) {
+ state.mStream = new FileOutputStream(state.mFilename, true);
+ }
+ state.mStream.write(data, 0, bytesRead);
+ // we close after every write --- this may be too inefficient
+ closeDestination(state);
+ return;
+ } catch (IOException ex) {
+ if (!Helpers.isExternalMediaMounted()) {
+ throw new StopRequest(DownloaderService.STATUS_DEVICE_NOT_FOUND_ERROR,
+ "external media not mounted while writing destination file");
+ }
+
+ long availableBytes =
+ Helpers.getAvailableBytes(Helpers.getFilesystemRoot(state.mFilename));
+ if (availableBytes < bytesRead) {
+ throw new StopRequest(DownloaderService.STATUS_INSUFFICIENT_SPACE_ERROR,
+ "insufficient space while writing destination file", ex);
+ }
+ throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
+ "while writing destination file: " + ex.toString(), ex);
+ }
+ }
+ }
+
+ /**
+ * Called when we've reached the end of the HTTP response stream, to update
+ * the database and check for consistency.
+ */
+ private void handleEndOfStream(State state, InnerState innerState) throws StopRequest {
+ mInfo.mCurrentBytes = innerState.mBytesSoFar;
+ // this should always be set from the market
+ // if ( innerState.mHeaderContentLength == null ) {
+ // mInfo.mTotalBytes = innerState.mBytesSoFar;
+ // }
+ mDB.updateDownload(mInfo);
+
+ boolean lengthMismatched = (innerState.mHeaderContentLength != null)
+ && (innerState.mBytesSoFar != Integer.parseInt(innerState.mHeaderContentLength));
+ if (lengthMismatched) {
+ if (cannotResume(innerState)) {
+ throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
+ "mismatched content length");
+ } else {
+ throw new StopRequest(getFinalStatusForHttpError(state),
+ "closed socket before end of file");
+ }
+ }
+ }
+
+ private boolean cannotResume(InnerState innerState) {
+ return innerState.mBytesSoFar > 0 && innerState.mHeaderETag == null;
+ }
+
+ /**
+ * Read some data from the HTTP response stream, handling I/O errors.
+ *
+ * @param data buffer to use to read data
+ * @param entityStream stream for reading the HTTP response entity
+ * @return the number of bytes actually read or -1 if the end of the stream
+ * has been reached
+ */
+ private int readFromResponse(State state, InnerState innerState, byte[] data,
+ InputStream entityStream) throws StopRequest {
+ try {
+ return entityStream.read(data);
+ } catch (IOException ex) {
+ logNetworkState();
+ mInfo.mCurrentBytes = innerState.mBytesSoFar;
+ mDB.updateDownload(mInfo);
+ if (cannotResume(innerState)) {
+ String message = "while reading response: " + ex.toString()
+ + ", can't resume interrupted download with no ETag";
+ throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
+ message, ex);
+ } else {
+ throw new StopRequest(getFinalStatusForHttpError(state),
+ "while reading response: " + ex.toString(), ex);
+ }
+ }
+ }
+
+ /**
+ * Open a stream for the HTTP response entity, handling I/O errors.
+ *
+ * @return an InputStream to read the response entity
+ */
+ private InputStream openResponseEntity(State state, HttpURLConnection response)
+ throws StopRequest {
+ try {
+ return response.getInputStream();
+ } catch (IOException ex) {
+ logNetworkState();
+ throw new StopRequest(getFinalStatusForHttpError(state),
+ "while getting entity: " + ex.toString(), ex);
+ }
+ }
+
+ private void logNetworkState() {
+ if (Constants.LOGX) {
+ Log.i(Constants.TAG,
+ "Net "
+ + (mService.getNetworkAvailabilityState(mDB) == DownloaderService.NETWORK_OK ? "Up"
+ : "Down"));
+ }
+ }
+
+ /**
+ * Read HTTP response headers and take appropriate action, including setting
+ * up the destination file and updating the database.
+ */
+ private void processResponseHeaders(State state, InnerState innerState, HttpURLConnection response)
+ throws StopRequest {
+ if (innerState.mContinuingDownload) {
+ // ignore response headers on resume requests
+ return;
+ }
+
+ readResponseHeaders(state, innerState, response);
+
+ try {
+ state.mFilename = mService.generateSaveFile(mInfo.mFileName, mInfo.mTotalBytes);
+ } catch (DownloaderService.GenerateSaveFileError exc) {
+ throw new StopRequest(exc.mStatus, exc.mMessage);
+ }
+ try {
+ state.mStream = new FileOutputStream(state.mFilename);
+ } catch (FileNotFoundException exc) {
+ // make sure the directory exists
+ File pathFile = new File(Helpers.getSaveFilePath(mService));
+ try {
+ if (pathFile.mkdirs()) {
+ state.mStream = new FileOutputStream(state.mFilename);
+ }
+ } catch (Exception ex) {
+ throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
+ "while opening destination file: " + exc.toString(), exc);
+ }
+ }
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "writing " + mInfo.mUri + " to " + state.mFilename);
+ }
+
+ updateDatabaseFromHeaders(state, innerState);
+ // check connectivity again now that we know the total size
+ checkConnectivity(state);
+ }
+
+ /**
+ * Update necessary database fields based on values of HTTP response headers
+ * that have been read.
+ */
+ private void updateDatabaseFromHeaders(State state, InnerState innerState) {
+ mInfo.mETag = innerState.mHeaderETag;
+ mDB.updateDownload(mInfo);
+ }
+
+ /**
+ * Read headers from the HTTP response and store them into local state.
+ */
+ private void readResponseHeaders(State state, InnerState innerState, HttpURLConnection response)
+ throws StopRequest {
+ String value = response.getHeaderField("Content-Disposition");
+ if (value != null) {
+ innerState.mHeaderContentDisposition = value;
+ }
+ value = response.getHeaderField("Content-Location");
+ if (value != null) {
+ innerState.mHeaderContentLocation = value;
+ }
+ value = response.getHeaderField("ETag");
+ if (value != null) {
+ innerState.mHeaderETag = value;
+ }
+ String headerTransferEncoding = null;
+ value = response.getHeaderField("Transfer-Encoding");
+ if (value != null) {
+ headerTransferEncoding = value;
+ }
+ String headerContentType = null;
+ value = response.getHeaderField("Content-Type");
+ if (value != null) {
+ headerContentType = value;
+ if (!headerContentType.equals("application/vnd.android.obb")) {
+ throw new StopRequest(DownloaderService.STATUS_FILE_DELIVERED_INCORRECTLY,
+ "file delivered with incorrect Mime type");
+ }
+ }
+
+ if (headerTransferEncoding == null) {
+ long contentLength = response.getContentLength();
+ if (value != null) {
+ // this is always set from Market
+ if (contentLength != -1 && contentLength != mInfo.mTotalBytes) {
+ // we're most likely on a bad wifi connection -- we should
+ // probably
+ // also look at the mime type --- but the size mismatch is
+ // enough
+ // to tell us that something is wrong here
+ Log.e(Constants.TAG, "Incorrect file size delivered.");
+ } else {
+ innerState.mHeaderContentLength = Long.toString(contentLength);
+ }
+ }
+ } else {
+ // Ignore content-length with transfer-encoding - 2616 4.4 3
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG,
+ "ignoring content-length because of xfer-encoding");
+ }
+ }
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG, "Content-Disposition: " +
+ innerState.mHeaderContentDisposition);
+ Log.v(Constants.TAG, "Content-Length: " + innerState.mHeaderContentLength);
+ Log.v(Constants.TAG, "Content-Location: " + innerState.mHeaderContentLocation);
+ Log.v(Constants.TAG, "ETag: " + innerState.mHeaderETag);
+ Log.v(Constants.TAG, "Transfer-Encoding: " + headerTransferEncoding);
+ }
+
+ boolean noSizeInfo = innerState.mHeaderContentLength == null
+ && (headerTransferEncoding == null
+ || !headerTransferEncoding.equalsIgnoreCase("chunked"));
+ if (noSizeInfo) {
+ throw new StopRequest(DownloaderService.STATUS_HTTP_DATA_ERROR,
+ "can't know size of download, giving up");
+ }
+ }
+
+ /**
+ * Check the HTTP response status and handle anything unusual (e.g. not
+ * 200/206).
+ */
+ private void handleExceptionalStatus(State state, InnerState innerState, HttpURLConnection connection, int responseCode)
+ throws StopRequest, RetryDownload {
+ if (responseCode == 503 && mInfo.mNumFailed < Constants.MAX_RETRIES) {
+ handleServiceUnavailable(state, connection);
+ }
+ int expectedStatus = innerState.mContinuingDownload ? 206
+ : DownloaderService.STATUS_SUCCESS;
+ if (responseCode != expectedStatus) {
+ handleOtherStatus(state, innerState, responseCode);
+ } else {
+ // no longer redirected
+ state.mRedirectCount = 0;
+ }
+ }
+
+ /**
+ * Handle a status that we don't know how to deal with properly.
+ */
+ private void handleOtherStatus(State state, InnerState innerState, int statusCode)
+ throws StopRequest {
+ int finalStatus;
+ if (DownloaderService.isStatusError(statusCode)) {
+ finalStatus = statusCode;
+ } else if (statusCode >= 300 && statusCode < 400) {
+ finalStatus = DownloaderService.STATUS_UNHANDLED_REDIRECT;
+ } else if (innerState.mContinuingDownload && statusCode == DownloaderService.STATUS_SUCCESS) {
+ finalStatus = DownloaderService.STATUS_CANNOT_RESUME;
+ } else {
+ finalStatus = DownloaderService.STATUS_UNHANDLED_HTTP_CODE;
+ }
+ throw new StopRequest(finalStatus, "http error " + statusCode);
+ }
+
+ /**
+ * Add headers for this download to the HTTP request to allow for resume.
+ */
+ private void addRequestHeaders(InnerState innerState, HttpURLConnection request) {
+ if (innerState.mContinuingDownload) {
+ if (innerState.mHeaderETag != null) {
+ request.setRequestProperty("If-Match", innerState.mHeaderETag);
+ }
+ request.setRequestProperty("Range", "bytes=" + innerState.mBytesSoFar + "-");
+ }
+ }
+
+ /**
+ * Handle a 503 Service Unavailable status by processing the Retry-After
+ * header.
+ */
+ private void handleServiceUnavailable(State state, HttpURLConnection connection) throws StopRequest {
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG, "got HTTP response code 503");
+ }
+ state.mCountRetry = true;
+ String retryAfterValue = connection.getHeaderField("Retry-After");
+ if (retryAfterValue != null) {
+ try {
+ if (Constants.LOGVV) {
+ Log.v(Constants.TAG, "Retry-After :" + retryAfterValue);
+ }
+ state.mRetryAfter = Integer.parseInt(retryAfterValue);
+ if (state.mRetryAfter < 0) {
+ state.mRetryAfter = 0;
+ } else {
+ if (state.mRetryAfter < Constants.MIN_RETRY_AFTER) {
+ state.mRetryAfter = Constants.MIN_RETRY_AFTER;
+ } else if (state.mRetryAfter > Constants.MAX_RETRY_AFTER) {
+ state.mRetryAfter = Constants.MAX_RETRY_AFTER;
+ }
+ state.mRetryAfter += Helpers.sRandom.nextInt(Constants.MIN_RETRY_AFTER + 1);
+ state.mRetryAfter *= 1000;
+ }
+ } catch (NumberFormatException ex) {
+ // ignored - retryAfter stays 0 in this case.
+ }
+ }
+ throw new StopRequest(DownloaderService.STATUS_WAITING_TO_RETRY,
+ "got 503 Service Unavailable, will retry later");
+ }
+
+ /**
+ * Send the request to the server, handling any I/O exceptions.
+ */
+ private int sendRequest(State state, HttpURLConnection request)
+ throws StopRequest {
+ try {
+ return request.getResponseCode();
+ } catch (IllegalArgumentException ex) {
+ throw new StopRequest(DownloaderService.STATUS_HTTP_DATA_ERROR,
+ "while trying to execute request: " + ex.toString(), ex);
+ } catch (IOException ex) {
+ logNetworkState();
+ throw new StopRequest(getFinalStatusForHttpError(state),
+ "while trying to execute request: " + ex.toString(), ex);
+ }
+ }
+
+ private int getFinalStatusForHttpError(State state) {
+ if (mService.getNetworkAvailabilityState(mDB) != DownloaderService.NETWORK_OK) {
+ return DownloaderService.STATUS_WAITING_FOR_NETWORK;
+ } else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
+ state.mCountRetry = true;
+ return DownloaderService.STATUS_WAITING_TO_RETRY;
+ } else {
+ Log.w(Constants.TAG, "reached max retries for " + mInfo.mNumFailed);
+ return DownloaderService.STATUS_HTTP_DATA_ERROR;
+ }
+ }
+
+ /**
+ * Prepare the destination file to receive data. If the file already exists,
+ * we'll set up appropriately for resumption.
+ */
+ private void setupDestinationFile(State state, InnerState innerState)
+ throws StopRequest {
+ if (state.mFilename != null) { // only true if we've already run a
+ // thread for this download
+ if (!Helpers.isFilenameValid(state.mFilename)) {
+ // this should never happen
+ throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
+ "found invalid internal destination filename");
+ }
+ // We're resuming a download that got interrupted
+ File f = new File(state.mFilename);
+ if (f.exists()) {
+ long fileLength = f.length();
+ if (fileLength == 0) {
+ // The download hadn't actually started, we can restart from
+ // scratch
+ f.delete();
+ state.mFilename = null;
+ } else if (mInfo.mETag == null) {
+ // This should've been caught upon failure
+ f.delete();
+ throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
+ "Trying to resume a download that can't be resumed");
+ } else {
+ // All right, we'll be able to resume this download
+ try {
+ state.mStream = new FileOutputStream(state.mFilename, true);
+ } catch (FileNotFoundException exc) {
+ throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
+ "while opening destination for resuming: " + exc.toString(), exc);
+ }
+ innerState.mBytesSoFar = (int) fileLength;
+ if (mInfo.mTotalBytes != -1) {
+ innerState.mHeaderContentLength = Long.toString(mInfo.mTotalBytes);
+ }
+ innerState.mHeaderETag = mInfo.mETag;
+ innerState.mContinuingDownload = true;
+ }
+ }
+ }
+
+ if (state.mStream != null) {
+ closeDestination(state);
+ }
+ }
+
+ /**
+ * Stores information about the completed download, and notifies the
+ * initiating application.
+ */
+ private void notifyDownloadCompleted(
+ int status, boolean countRetry, int retryAfter, int redirectCount, boolean gotData,
+ String filename) {
+ updateDownloadDatabase(
+ status, countRetry, retryAfter, redirectCount, gotData, filename);
+ if (DownloaderService.isStatusCompleted(status)) {
+ // TBD: send status update?
+ }
+ }
+
+ private void updateDownloadDatabase(
+ int status, boolean countRetry, int retryAfter, int redirectCount, boolean gotData,
+ String filename) {
+ mInfo.mStatus = status;
+ mInfo.mRetryAfter = retryAfter;
+ mInfo.mRedirectCount = redirectCount;
+ mInfo.mLastMod = System.currentTimeMillis();
+ if (!countRetry) {
+ mInfo.mNumFailed = 0;
+ } else if (gotData) {
+ mInfo.mNumFailed = 1;
+ } else {
+ mInfo.mNumFailed++;
+ }
+ mDB.updateDownload(mInfo);
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
new file mode 100644
index 0000000000..8d41a76900
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import com.google.android.vending.expansion.downloader.Constants;
+import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
+import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller;
+import com.google.android.vending.expansion.downloader.Helpers;
+import com.google.android.vending.expansion.downloader.IDownloaderClient;
+import com.google.android.vending.expansion.downloader.IDownloaderService;
+import com.google.android.vending.expansion.downloader.IStub;
+import com.google.android.vending.licensing.AESObfuscator;
+import com.google.android.vending.licensing.APKExpansionPolicy;
+import com.google.android.vending.licensing.LicenseChecker;
+import com.google.android.vending.licensing.LicenseCheckerCallback;
+import com.google.android.vending.licensing.Policy;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Messenger;
+import android.os.SystemClock;
+import android.provider.Settings.Secure;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+// -- GODOT start --
+import android.annotation.SuppressLint;
+// -- GODOT end --
+
+import java.io.File;
+
+/**
+ * Performs the background downloads requested by applications that use the
+ * Downloads provider. This service does not run as a foreground task, so
+ * Android may kill it off at will, but it will try to restart itself if it can.
+ * Note that Android by default will kill off any process that has an open file
+ * handle on the shared (SD Card) partition if the partition is unmounted.
+ */
+public abstract class DownloaderService extends CustomIntentService implements IDownloaderService {
+
+ public DownloaderService() {
+ super("LVLDownloadService");
+ }
+
+ private static final String LOG_TAG = "LVLDL";
+
+ // the following NETWORK_* constants are used to indicates specific reasons
+ // for disallowing a
+ // download from using a network, since specific causes can require special
+ // handling
+
+ /**
+ * The network is usable for the given download.
+ */
+ public static final int NETWORK_OK = 1;
+
+ /**
+ * There is no network connectivity.
+ */
+ public static final int NETWORK_NO_CONNECTION = 2;
+
+ /**
+ * The download exceeds the maximum size for this network.
+ */
+ public static final int NETWORK_UNUSABLE_DUE_TO_SIZE = 3;
+
+ /**
+ * The download exceeds the recommended maximum size for this network, the
+ * user must confirm for this download to proceed without WiFi.
+ */
+ public static final int NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE = 4;
+
+ /**
+ * The current connection is roaming, and the download can't proceed over a
+ * roaming connection.
+ */
+ public static final int NETWORK_CANNOT_USE_ROAMING = 5;
+
+ /**
+ * The app requesting the download specific that it can't use the current
+ * network connection.
+ */
+ public static final int NETWORK_TYPE_DISALLOWED_BY_REQUESTOR = 6;
+
+ /**
+ * For intents used to notify the user that a download exceeds a size
+ * threshold, if this extra is true, WiFi is required for this download
+ * size; otherwise, it is only recommended.
+ */
+ public static final String EXTRA_IS_WIFI_REQUIRED = "isWifiRequired";
+ public static final String EXTRA_FILE_NAME = "downloadId";
+
+ /**
+ * Used with DOWNLOAD_STATUS
+ */
+ public static final String EXTRA_STATUS_STATE = "ESS";
+ public static final String EXTRA_STATUS_TOTAL_SIZE = "ETS";
+ public static final String EXTRA_STATUS_CURRENT_FILE_SIZE = "CFS";
+ public static final String EXTRA_STATUS_TOTAL_PROGRESS = "TFP";
+ public static final String EXTRA_STATUS_CURRENT_PROGRESS = "CFP";
+
+ public static final String ACTION_DOWNLOADS_CHANGED = "downloadsChanged";
+
+ /**
+ * Broadcast intent action sent by the download manager when a download
+ * completes.
+ */
+ public final static String ACTION_DOWNLOAD_COMPLETE = "lvldownloader.intent.action.DOWNLOAD_COMPLETE";
+
+ /**
+ * Broadcast intent action sent by the download manager when download status
+ * changes.
+ */
+ public final static String ACTION_DOWNLOAD_STATUS = "lvldownloader.intent.action.DOWNLOAD_STATUS";
+
+ /*
+ * Lists the states that the download manager can set on a download to
+ * notify applications of the download progress. The codes follow the HTTP
+ * families:<br> 1xx: informational<br> 2xx: success<br> 3xx: redirects (not
+ * used by the download manager)<br> 4xx: client errors<br> 5xx: server
+ * errors
+ */
+
+ /**
+ * Returns whether the status is informational (i.e. 1xx).
+ */
+ public static boolean isStatusInformational(int status) {
+ return (status >= 100 && status < 200);
+ }
+
+ /**
+ * Returns whether the status is a success (i.e. 2xx).
+ */
+ public static boolean isStatusSuccess(int status) {
+ return (status >= 200 && status < 300);
+ }
+
+ /**
+ * Returns whether the status is an error (i.e. 4xx or 5xx).
+ */
+ public static boolean isStatusError(int status) {
+ return (status >= 400 && status < 600);
+ }
+
+ /**
+ * Returns whether the status is a client error (i.e. 4xx).
+ */
+ public static boolean isStatusClientError(int status) {
+ return (status >= 400 && status < 500);
+ }
+
+ /**
+ * Returns whether the status is a server error (i.e. 5xx).
+ */
+ public static boolean isStatusServerError(int status) {
+ return (status >= 500 && status < 600);
+ }
+
+ /**
+ * Returns whether the download has completed (either with success or
+ * error).
+ */
+ public static boolean isStatusCompleted(int status) {
+ return (status >= 200 && status < 300)
+ || (status >= 400 && status < 600);
+ }
+
+ /**
+ * This download hasn't stated yet
+ */
+ public static final int STATUS_PENDING = 190;
+
+ /**
+ * This download has started
+ */
+ public static final int STATUS_RUNNING = 192;
+
+ /**
+ * This download has been paused by the owning app.
+ */
+ public static final int STATUS_PAUSED_BY_APP = 193;
+
+ /**
+ * This download encountered some network error and is waiting before
+ * retrying the request.
+ */
+ public static final int STATUS_WAITING_TO_RETRY = 194;
+
+ /**
+ * This download is waiting for network connectivity to proceed.
+ */
+ public static final int STATUS_WAITING_FOR_NETWORK = 195;
+
+ /**
+ * This download is waiting for a Wi-Fi connection to proceed or for
+ * permission to download over cellular.
+ */
+ public static final int STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION = 196;
+
+ /**
+ * This download is waiting for a Wi-Fi connection to proceed.
+ */
+ public static final int STATUS_QUEUED_FOR_WIFI = 197;
+
+ /**
+ * This download has successfully completed. Warning: there might be other
+ * status values that indicate success in the future. Use isSucccess() to
+ * capture the entire category.
+ *
+ * @hide
+ */
+ public static final int STATUS_SUCCESS = 200;
+
+ /**
+ * The requested URL is no longer available
+ */
+ public static final int STATUS_FORBIDDEN = 403;
+
+ /**
+ * The file was delivered incorrectly
+ */
+ public static final int STATUS_FILE_DELIVERED_INCORRECTLY = 487;
+
+ /**
+ * The requested destination file already exists.
+ */
+ public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
+
+ /**
+ * Some possibly transient error occurred, but we can't resume the download.
+ */
+ public static final int STATUS_CANNOT_RESUME = 489;
+
+ /**
+ * This download was canceled
+ *
+ * @hide
+ */
+ public static final int STATUS_CANCELED = 490;
+
+ /**
+ * This download has completed with an error. Warning: there will be other
+ * status values that indicate errors in the future. Use isStatusError() to
+ * capture the entire category.
+ */
+ public static final int STATUS_UNKNOWN_ERROR = 491;
+
+ /**
+ * This download couldn't be completed because of a storage issue.
+ * Typically, that's because the filesystem is missing or full. Use the more
+ * specific {@link #STATUS_INSUFFICIENT_SPACE_ERROR} and
+ * {@link #STATUS_DEVICE_NOT_FOUND_ERROR} when appropriate.
+ *
+ * @hide
+ */
+ public static final int STATUS_FILE_ERROR = 492;
+
+ /**
+ * This download couldn't be completed because of an HTTP redirect response
+ * that the download manager couldn't handle.
+ *
+ * @hide
+ */
+ public static final int STATUS_UNHANDLED_REDIRECT = 493;
+
+ /**
+ * This download couldn't be completed because of an unspecified unhandled
+ * HTTP code.
+ *
+ * @hide
+ */
+ public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
+
+ /**
+ * This download couldn't be completed because of an error receiving or
+ * processing data at the HTTP level.
+ *
+ * @hide
+ */
+ public static final int STATUS_HTTP_DATA_ERROR = 495;
+
+ /**
+ * This download couldn't be completed because of an HttpException while
+ * setting up the request.
+ *
+ * @hide
+ */
+ public static final int STATUS_HTTP_EXCEPTION = 496;
+
+ /**
+ * This download couldn't be completed because there were too many
+ * redirects.
+ *
+ * @hide
+ */
+ public static final int STATUS_TOO_MANY_REDIRECTS = 497;
+
+ /**
+ * This download couldn't be completed due to insufficient storage space.
+ * Typically, this is because the SD card is full.
+ *
+ * @hide
+ */
+ public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
+
+ /**
+ * This download couldn't be completed because no external storage device
+ * was found. Typically, this is because the SD card is not mounted.
+ *
+ * @hide
+ */
+ public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
+
+ /**
+ * This download is allowed to run.
+ *
+ * @hide
+ */
+ public static final int CONTROL_RUN = 0;
+
+ /**
+ * This download must pause at the first opportunity.
+ *
+ * @hide
+ */
+ public static final int CONTROL_PAUSED = 1;
+
+ /**
+ * This download is visible but only shows in the notifications while it's
+ * in progress.
+ *
+ * @hide
+ */
+ public static final int VISIBILITY_VISIBLE = 0;
+
+ /**
+ * This download is visible and shows in the notifications while in progress
+ * and after completion.
+ *
+ * @hide
+ */
+ public static final int VISIBILITY_VISIBLE_NOTIFY_COMPLETED = 1;
+
+ /**
+ * This download doesn't show in the UI or in the notifications.
+ *
+ * @hide
+ */
+ public static final int VISIBILITY_HIDDEN = 2;
+
+ /**
+ * Bit flag for setAllowedNetworkTypes corresponding to
+ * {@link ConnectivityManager#TYPE_MOBILE}.
+ */
+ public static final int NETWORK_MOBILE = 1 << 0;
+
+ /**
+ * Bit flag for setAllowedNetworkTypes corresponding to
+ * {@link ConnectivityManager#TYPE_WIFI}.
+ */
+ public static final int NETWORK_WIFI = 1 << 1;
+
+ private final static String TEMP_EXT = ".tmp";
+
+ /**
+ * Service thread status
+ */
+ private static boolean sIsRunning;
+
+ @Override
+ public IBinder onBind(Intent paramIntent) {
+ Log.d(Constants.TAG, "Service Bound");
+ return this.mServiceMessenger.getBinder();
+ }
+
+ /**
+ * Network state.
+ */
+ private boolean mIsConnected;
+ private boolean mIsFailover;
+ private boolean mIsCellularConnection;
+ private boolean mIsRoaming;
+ private boolean mIsAtLeast3G;
+ private boolean mIsAtLeast4G;
+ private boolean mStateChanged;
+
+ /**
+ * Download state
+ */
+ private int mControl;
+ private int mStatus;
+
+ public boolean isWiFi() {
+ return mIsConnected && !mIsCellularConnection;
+ }
+
+ /**
+ * Bindings to important services
+ */
+ private ConnectivityManager mConnectivityManager;
+ private WifiManager mWifiManager;
+
+ /**
+ * Package we are downloading for (defaults to package of application)
+ */
+ private PackageInfo mPackageInfo;
+
+ /**
+ * Byte counts
+ */
+ long mBytesSoFar;
+ long mTotalLength;
+ int mFileCount;
+
+ /**
+ * Used for calculating time remaining and speed
+ */
+ long mBytesAtSample;
+ long mMillisecondsAtSample;
+ float mAverageDownloadSpeed;
+
+ /**
+ * Our binding to the network state broadcasts
+ */
+ private BroadcastReceiver mConnReceiver;
+ final private IStub mServiceStub = DownloaderServiceMarshaller.CreateStub(this);
+ final private Messenger mServiceMessenger = mServiceStub.getMessenger();
+ private Messenger mClientMessenger;
+ private DownloadNotification mNotification;
+ private PendingIntent mPendingIntent;
+ private PendingIntent mAlarmIntent;
+
+ /**
+ * Updates the network type based upon the type and subtype returned from
+ * the connectivity manager. Subtype is only used for cellular signals.
+ *
+ * @param type
+ * @param subType
+ */
+ private void updateNetworkType(int type, int subType) {
+ switch (type) {
+ case ConnectivityManager.TYPE_WIFI:
+ case ConnectivityManager.TYPE_ETHERNET:
+ case ConnectivityManager.TYPE_BLUETOOTH:
+ mIsCellularConnection = false;
+ mIsAtLeast3G = false;
+ mIsAtLeast4G = false;
+ break;
+ case ConnectivityManager.TYPE_WIMAX:
+ mIsCellularConnection = true;
+ mIsAtLeast3G = true;
+ mIsAtLeast4G = true;
+ break;
+ case ConnectivityManager.TYPE_MOBILE:
+ mIsCellularConnection = true;
+ switch (subType) {
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ mIsAtLeast3G = false;
+ mIsAtLeast4G = false;
+ break;
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ mIsAtLeast3G = true;
+ mIsAtLeast4G = false;
+ break;
+ case TelephonyManager.NETWORK_TYPE_LTE: // 4G
+ case TelephonyManager.NETWORK_TYPE_EHRPD: // 3G ++ interop
+ // with 4G
+ case TelephonyManager.NETWORK_TYPE_HSPAP: // 3G ++ but
+ // marketed as
+ // 4G
+ mIsAtLeast3G = true;
+ mIsAtLeast4G = true;
+ break;
+ default:
+ mIsCellularConnection = false;
+ mIsAtLeast3G = false;
+ mIsAtLeast4G = false;
+ }
+ }
+ }
+
+ private void updateNetworkState(NetworkInfo info) {
+ boolean isConnected = mIsConnected;
+ boolean isFailover = mIsFailover;
+ boolean isCellularConnection = mIsCellularConnection;
+ boolean isRoaming = mIsRoaming;
+ boolean isAtLeast3G = mIsAtLeast3G;
+ if (null != info) {
+ mIsRoaming = info.isRoaming();
+ mIsFailover = info.isFailover();
+ mIsConnected = info.isConnected();
+ updateNetworkType(info.getType(), info.getSubtype());
+ } else {
+ mIsRoaming = false;
+ mIsFailover = false;
+ mIsConnected = false;
+ updateNetworkType(-1, -1);
+ }
+ mStateChanged = (mStateChanged || isConnected != mIsConnected
+ || isFailover != mIsFailover
+ || isCellularConnection != mIsCellularConnection
+ || isRoaming != mIsRoaming || isAtLeast3G != mIsAtLeast3G);
+ if (Constants.LOGVV) {
+ if (mStateChanged) {
+ Log.v(LOG_TAG, "Network state changed: ");
+ Log.v(LOG_TAG, "Starting State: " +
+ (isConnected ? "Connected " : "Not Connected ") +
+ (isCellularConnection ? "Cellular " : "WiFi ") +
+ (isRoaming ? "Roaming " : "Local ") +
+ (isAtLeast3G ? "3G+ " : "<3G "));
+ Log.v(LOG_TAG, "Ending State: " +
+ (mIsConnected ? "Connected " : "Not Connected ") +
+ (mIsCellularConnection ? "Cellular " : "WiFi ") +
+ (mIsRoaming ? "Roaming " : "Local ") +
+ (mIsAtLeast3G ? "3G+ " : "<3G "));
+
+ if (isServiceRunning()) {
+ if (mIsRoaming) {
+ mStatus = STATUS_WAITING_FOR_NETWORK;
+ mControl = CONTROL_PAUSED;
+ } else if (mIsCellularConnection) {
+ DownloadsDB db = DownloadsDB.getDB(this);
+ int flags = db.getFlags();
+ if (0 == (flags & FLAGS_DOWNLOAD_OVER_CELLULAR)) {
+ mStatus = STATUS_QUEUED_FOR_WIFI;
+ mControl = CONTROL_PAUSED;
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Polls the network state, setting the flags appropriately.
+ */
+ void pollNetworkState() {
+ if (null == mConnectivityManager) {
+ mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+ if (null == mWifiManager) {
+ mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ }
+ if (mConnectivityManager == null) {
+ Log.w(Constants.TAG,
+ "couldn't get connectivity manager to poll network state");
+ } else {
+ @SuppressLint("MissingPermission")
+ NetworkInfo activeInfo = mConnectivityManager
+ .getActiveNetworkInfo();
+ updateNetworkState(activeInfo);
+ }
+ }
+
+ public static final int NO_DOWNLOAD_REQUIRED = 0;
+ public static final int LVL_CHECK_REQUIRED = 1;
+ public static final int DOWNLOAD_REQUIRED = 2;
+
+ public static final String EXTRA_PACKAGE_NAME = "EPN";
+ public static final String EXTRA_PENDING_INTENT = "EPI";
+ public static final String EXTRA_MESSAGE_HANDLER = "EMH";
+
+ /**
+ * Returns true if the LVL check is required
+ *
+ * @param db a downloads DB synchronized with the latest state
+ * @param pi the package info for the project
+ * @return returns true if the filenames need to be returned
+ */
+ private static boolean isLVLCheckRequired(DownloadsDB db, PackageInfo pi) {
+ // we need to update the LVL check and get a successful status to
+ // proceed
+ if (db.mVersionCode != pi.versionCode) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Careful! Only use this internally.
+ *
+ * @return whether we think the service is running
+ */
+ private static synchronized boolean isServiceRunning() {
+ return sIsRunning;
+ }
+
+ private static synchronized void setServiceRunning(boolean isRunning) {
+ sIsRunning = isRunning;
+ }
+
+ public static int startDownloadServiceIfRequired(Context context,
+ Intent intent, Class<?> serviceClass) throws NameNotFoundException {
+ final PendingIntent pendingIntent = (PendingIntent) intent
+ .getParcelableExtra(EXTRA_PENDING_INTENT);
+ return startDownloadServiceIfRequired(context, pendingIntent,
+ serviceClass);
+ }
+
+ public static int startDownloadServiceIfRequired(Context context,
+ PendingIntent pendingIntent, Class<?> serviceClass)
+ throws NameNotFoundException
+ {
+ String packageName = context.getPackageName();
+ String className = serviceClass.getName();
+
+ return startDownloadServiceIfRequired(context, pendingIntent,
+ packageName, className);
+ }
+
+ /**
+ * Starts the download if necessary. This function starts a flow that does `
+ * many things. 1) Checks to see if the APK version has been checked and the
+ * metadata database updated 2) If the APK version does not match, checks
+ * the new LVL status to see if a new download is required 3) If the APK
+ * version does match, then checks to see if the download(s) have been
+ * completed 4) If the downloads have been completed, returns
+ * NO_DOWNLOAD_REQUIRED The idea is that this can be called during the
+ * startup of an application to quickly ascertain if the application needs
+ * to wait to hear about any updated APK expansion files. Note that this
+ * does mean that the application MUST be run for the first time with a
+ * network connection, even if Market delivers all of the files.
+ *
+ * @param context
+ * @param pendingIntent
+ * @return true if the app should wait for more guidance from the
+ * downloader, false if the app can continue
+ * @throws NameNotFoundException
+ */
+ public static int startDownloadServiceIfRequired(Context context,
+ PendingIntent pendingIntent, String classPackage, String className)
+ throws NameNotFoundException {
+ // first: do we need to do an LVL update?
+ // we begin by getting our APK version from the package manager
+ final PackageInfo pi = context.getPackageManager().getPackageInfo(
+ context.getPackageName(), 0);
+
+ int status = NO_DOWNLOAD_REQUIRED;
+
+ // the database automatically reads the metadata for version code
+ // and download status when the instance is created
+ DownloadsDB db = DownloadsDB.getDB(context);
+
+ // we need to update the LVL check and get a successful status to
+ // proceed
+ if (isLVLCheckRequired(db, pi)) {
+ status = LVL_CHECK_REQUIRED;
+ }
+ // we don't have to update LVL. do we still have a download to start?
+ if (db.mStatus == 0) {
+ DownloadInfo[] infos = db.getDownloads();
+ if (null != infos) {
+ for (DownloadInfo info : infos) {
+ if (!Helpers.doesFileExist(context, info.mFileName, info.mTotalBytes, true)) {
+ status = DOWNLOAD_REQUIRED;
+ db.updateStatus(-1);
+ break;
+ }
+ }
+ }
+ } else {
+ status = DOWNLOAD_REQUIRED;
+ }
+ switch (status) {
+ case DOWNLOAD_REQUIRED:
+ case LVL_CHECK_REQUIRED:
+ Intent fileIntent = new Intent();
+ fileIntent.setClassName(classPackage, className);
+ fileIntent.putExtra(EXTRA_PENDING_INTENT, pendingIntent);
+ context.startService(fileIntent);
+ break;
+ }
+ return status;
+ }
+
+ @Override
+ public void requestAbortDownload() {
+ mControl = CONTROL_PAUSED;
+ mStatus = STATUS_CANCELED;
+ }
+
+ @Override
+ public void requestPauseDownload() {
+ mControl = CONTROL_PAUSED;
+ mStatus = STATUS_PAUSED_BY_APP;
+ }
+
+ @Override
+ public void setDownloadFlags(int flags) {
+ DownloadsDB.getDB(this).updateFlags(flags);
+ }
+
+ @Override
+ public void requestContinueDownload() {
+ if (mControl == CONTROL_PAUSED) {
+ mControl = CONTROL_RUN;
+ }
+ Intent fileIntent = new Intent(this, this.getClass());
+ fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
+ this.startService(fileIntent);
+ }
+
+ public abstract String getPublicKey();
+
+ public abstract byte[] getSALT();
+
+ public abstract String getAlarmReceiverClassName();
+
+ private class LVLRunnable implements Runnable {
+ LVLRunnable(Context context, PendingIntent intent) {
+ mContext = context;
+ mPendingIntent = intent;
+ }
+
+ final Context mContext;
+
+ @Override
+ public void run() {
+ setServiceRunning(true);
+ mNotification.onDownloadStateChanged(IDownloaderClient.STATE_FETCHING_URL);
+ String deviceId = Secure.getString(mContext.getContentResolver(),
+ Secure.ANDROID_ID);
+
+ final APKExpansionPolicy aep = new APKExpansionPolicy(mContext,
+ new AESObfuscator(getSALT(), mContext.getPackageName(), deviceId));
+
+ // reset our policy back to the start of the world to force a
+ // re-check
+ aep.resetPolicy();
+
+ // let's try and get the OBB file from LVL first
+ // Construct the LicenseChecker with a Policy.
+ final LicenseChecker checker = new LicenseChecker(mContext, aep,
+ getPublicKey() // Your public licensing key.
+ );
+ checker.checkAccess(new LicenseCheckerCallback() {
+
+ @Override
+ public void allow(int reason) {
+ try {
+ int count = aep.getExpansionURLCount();
+ DownloadsDB db = DownloadsDB.getDB(mContext);
+ int status = 0;
+ if (count != 0) {
+ for (int i = 0; i < count; i++) {
+ String currentFileName = aep
+ .getExpansionFileName(i);
+ if (null != currentFileName) {
+ DownloadInfo di = new DownloadInfo(i,
+ currentFileName, mContext.getPackageName());
+
+ long fileSize = aep.getExpansionFileSize(i);
+ if (handleFileUpdated(db, i, currentFileName,
+ fileSize)) {
+ status |= -1;
+ di.resetDownload();
+ di.mUri = aep.getExpansionURL(i);
+ di.mTotalBytes = fileSize;
+ di.mStatus = status;
+ db.updateDownload(di);
+ } else {
+ // we need to read the download
+ // information
+ // from
+ // the database
+ DownloadInfo dbdi = db
+ .getDownloadInfoByFileName(di.mFileName);
+ if (null == dbdi) {
+ // the file exists already and is
+ // the
+ // correct size
+ // was delivered by Market or
+ // through
+ // another mechanism
+ Log.d(LOG_TAG, "file " + di.mFileName
+ + " found. Not downloading.");
+ di.mStatus = STATUS_SUCCESS;
+ di.mTotalBytes = fileSize;
+ di.mCurrentBytes = fileSize;
+ di.mUri = aep.getExpansionURL(i);
+ db.updateDownload(di);
+ } else if (dbdi.mStatus != STATUS_SUCCESS) {
+ // we just update the URL
+ dbdi.mUri = aep.getExpansionURL(i);
+ db.updateDownload(dbdi);
+ status |= -1;
+ }
+ }
+ }
+ }
+ }
+ // first: do we need to do an LVL update?
+ // we begin by getting our APK version from the package
+ // manager
+ PackageInfo pi;
+ try {
+ pi = mContext.getPackageManager().getPackageInfo(
+ mContext.getPackageName(), 0);
+ db.updateMetadata(pi.versionCode, status);
+ Class<?> serviceClass = DownloaderService.this.getClass();
+ switch (startDownloadServiceIfRequired(mContext, mPendingIntent,
+ serviceClass)) {
+ case NO_DOWNLOAD_REQUIRED:
+ mNotification
+ .onDownloadStateChanged(IDownloaderClient.STATE_COMPLETED);
+ break;
+ case LVL_CHECK_REQUIRED:
+ // DANGER WILL ROBINSON!
+ Log.e(LOG_TAG, "In LVL checking loop!");
+ mNotification
+ .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_UNLICENSED);
+ throw new RuntimeException(
+ "Error with LVL checking and database integrity");
+ case DOWNLOAD_REQUIRED:
+ // do nothing. the download will notify the
+ // application
+ // when things are done
+ break;
+ }
+ } catch (NameNotFoundException e1) {
+ e1.printStackTrace();
+ throw new RuntimeException(
+ "Error with getting information from package name");
+ }
+ } finally {
+ setServiceRunning(false);
+ }
+ }
+
+ @Override
+ public void dontAllow(int reason) {
+ try
+ {
+ switch (reason) {
+ case Policy.NOT_LICENSED:
+ mNotification
+ .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_UNLICENSED);
+ break;
+ case Policy.RETRY:
+ mNotification
+ .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_FETCHING_URL);
+ break;
+ }
+ } finally {
+ setServiceRunning(false);
+ }
+
+ }
+
+ @Override
+ public void applicationError(int errorCode) {
+ try {
+ mNotification
+ .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_FETCHING_URL);
+ } finally {
+ setServiceRunning(false);
+ }
+ }
+
+ });
+
+ }
+
+ };
+
+ /**
+ * Updates the LVL information from the server.
+ *
+ * @param context
+ */
+ public void updateLVL(final Context context) {
+ Context c = context.getApplicationContext();
+ Handler h = new Handler(c.getMainLooper());
+ h.post(new LVLRunnable(c, mPendingIntent));
+ }
+
+ /**
+ * The APK has been updated and a filename has been sent down from the
+ * Market call. If the file has the same name as the previous file, we do
+ * nothing as the file is guaranteed to be the same. If the file does not
+ * have the same name, we download it if it hasn't already been delivered by
+ * Market.
+ *
+ * @param index the index of the file from market (0 = main, 1 = patch)
+ * @param filename the name of the new file
+ * @param fileSize the size of the new file
+ * @return
+ */
+ public boolean handleFileUpdated(DownloadsDB db, int index,
+ String filename, long fileSize) {
+ DownloadInfo di = db.getDownloadInfoByFileName(filename);
+ if (null != di) {
+ String oldFile = di.mFileName;
+ // cleanup
+ if (null != oldFile) {
+ if (filename.equals(oldFile)) {
+ return false;
+ }
+
+ // remove partially downloaded file if it is there
+ String deleteFile = Helpers.generateSaveFileName(this, oldFile);
+ File f = new File(deleteFile);
+ if (f.exists())
+ f.delete();
+ }
+ }
+ return !Helpers.doesFileExist(this, filename, fileSize, true);
+ }
+
+ private void scheduleAlarm(long wakeUp) {
+ AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ if (alarms == null) {
+ Log.e(Constants.TAG, "couldn't get alarm manager");
+ return;
+ }
+
+ if (Constants.LOGV) {
+ Log.v(Constants.TAG, "scheduling retry in " + wakeUp + "ms");
+ }
+
+ String className = getAlarmReceiverClassName();
+ Intent intent = new Intent(Constants.ACTION_RETRY);
+ intent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
+ intent.setClassName(this.getPackageName(),
+ className);
+ mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent,
+ PendingIntent.FLAG_ONE_SHOT);
+ alarms.set(
+ AlarmManager.RTC_WAKEUP,
+ System.currentTimeMillis() + wakeUp, mAlarmIntent
+ );
+ }
+
+ private void cancelAlarms() {
+ if (null != mAlarmIntent) {
+ AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ if (alarms == null) {
+ Log.e(Constants.TAG, "couldn't get alarm manager");
+ return;
+ }
+ alarms.cancel(mAlarmIntent);
+ mAlarmIntent = null;
+ }
+ }
+
+ /**
+ * We use this to track network state, such as when WiFi, Cellular, etc. is
+ * enabled when downloads are paused or in progress.
+ */
+ private class InnerBroadcastReceiver extends BroadcastReceiver {
+ final Service mService;
+
+ InnerBroadcastReceiver(Service service) {
+ mService = service;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ pollNetworkState();
+ if (mStateChanged
+ && !isServiceRunning()) {
+ Log.d(Constants.TAG, "InnerBroadcastReceiver Called");
+ Intent fileIntent = new Intent(context, mService.getClass());
+ fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
+ // send a new intent to the service
+ context.startService(fileIntent);
+ }
+ }
+ };
+
+ /**
+ * This is the main thread for the Downloader. This thread is responsible
+ * for queuing up downloads and other goodness.
+ */
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ setServiceRunning(true);
+ try {
+ // the database automatically reads the metadata for version code
+ // and download status when the instance is created
+ DownloadsDB db = DownloadsDB.getDB(this);
+ final PendingIntent pendingIntent = (PendingIntent) intent
+ .getParcelableExtra(EXTRA_PENDING_INTENT);
+
+ if (null != pendingIntent)
+ {
+ mNotification.setClientIntent(pendingIntent);
+ mPendingIntent = pendingIntent;
+ } else if (null != mPendingIntent) {
+ mNotification.setClientIntent(mPendingIntent);
+ } else {
+ Log.e(LOG_TAG, "Downloader started in bad state without notification intent.");
+ return;
+ }
+
+ // when the LVL check completes, a successful response will update
+ // the service
+ if (isLVLCheckRequired(db, mPackageInfo)) {
+ updateLVL(this);
+ return;
+ }
+
+ // get each download
+ DownloadInfo[] infos = db.getDownloads();
+ mBytesSoFar = 0;
+ mTotalLength = 0;
+ mFileCount = infos.length;
+ for (DownloadInfo info : infos) {
+ // We do an (simple) integrity check on each file, just to make
+ // sure
+ if (info.mStatus == STATUS_SUCCESS) {
+ // verify that the file matches the state
+ if (!Helpers.doesFileExist(this, info.mFileName, info.mTotalBytes, true)) {
+ info.mStatus = 0;
+ info.mCurrentBytes = 0;
+ }
+ }
+ // get aggregate data
+ mTotalLength += info.mTotalBytes;
+ mBytesSoFar += info.mCurrentBytes;
+ }
+
+ // loop through all downloads and fetch them
+ pollNetworkState();
+ if (null == mConnReceiver) {
+
+ /**
+ * We use this to track network state, such as when WiFi,
+ * Cellular, etc. is enabled when downloads are paused or in
+ * progress.
+ */
+ mConnReceiver = new InnerBroadcastReceiver(this);
+ IntentFilter intentFilter = new IntentFilter(
+ ConnectivityManager.CONNECTIVITY_ACTION);
+ intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ registerReceiver(mConnReceiver, intentFilter);
+ }
+
+ for (DownloadInfo info : infos) {
+ long startingCount = info.mCurrentBytes;
+
+ if (info.mStatus != STATUS_SUCCESS) {
+ DownloadThread dt = new DownloadThread(info, this, mNotification);
+ cancelAlarms();
+ scheduleAlarm(Constants.ACTIVE_THREAD_WATCHDOG);
+ dt.run();
+ cancelAlarms();
+ }
+ db.updateFromDb(info);
+ boolean setWakeWatchdog = false;
+ int notifyStatus;
+ switch (info.mStatus) {
+ case STATUS_FORBIDDEN:
+ // the URL is out of date
+ updateLVL(this);
+ return;
+ case STATUS_SUCCESS:
+ mBytesSoFar += info.mCurrentBytes - startingCount;
+ db.updateMetadata(mPackageInfo.versionCode, 0);
+ continue;
+ case STATUS_FILE_DELIVERED_INCORRECTLY:
+ // we may be on a network that is returning us a web
+ // page on redirect
+ notifyStatus = IDownloaderClient.STATE_PAUSED_NETWORK_SETUP_FAILURE;
+ info.mCurrentBytes = 0;
+ db.updateDownload(info);
+ setWakeWatchdog = true;
+ break;
+ case STATUS_PAUSED_BY_APP:
+ notifyStatus = IDownloaderClient.STATE_PAUSED_BY_REQUEST;
+ break;
+ case STATUS_WAITING_FOR_NETWORK:
+ case STATUS_WAITING_TO_RETRY:
+ notifyStatus = IDownloaderClient.STATE_PAUSED_NETWORK_UNAVAILABLE;
+ setWakeWatchdog = true;
+ break;
+ case STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION:
+ case STATUS_QUEUED_FOR_WIFI:
+ // look for more detail here
+ if (null != mWifiManager) {
+ if (!mWifiManager.isWifiEnabled()) {
+ notifyStatus = IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION;
+ setWakeWatchdog = true;
+ break;
+ }
+ }
+ notifyStatus = IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION;
+ setWakeWatchdog = true;
+ break;
+ case STATUS_CANCELED:
+ notifyStatus = IDownloaderClient.STATE_FAILED_CANCELED;
+ setWakeWatchdog = true;
+ break;
+
+ case STATUS_INSUFFICIENT_SPACE_ERROR:
+ notifyStatus = IDownloaderClient.STATE_FAILED_SDCARD_FULL;
+ setWakeWatchdog = true;
+ break;
+
+ case STATUS_DEVICE_NOT_FOUND_ERROR:
+ notifyStatus = IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE;
+ setWakeWatchdog = true;
+ break;
+
+ default:
+ notifyStatus = IDownloaderClient.STATE_FAILED;
+ break;
+ }
+ if (setWakeWatchdog) {
+ scheduleAlarm(Constants.WATCHDOG_WAKE_TIMER);
+ } else {
+ cancelAlarms();
+ }
+ // failure or pause state
+ mNotification.onDownloadStateChanged(notifyStatus);
+ return;
+ }
+
+ // all downloads complete
+ mNotification.onDownloadStateChanged(IDownloaderClient.STATE_COMPLETED);
+ } finally {
+ setServiceRunning(false);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (null != mConnReceiver) {
+ unregisterReceiver(mConnReceiver);
+ mConnReceiver = null;
+ }
+ mServiceStub.disconnect(this);
+ super.onDestroy();
+ }
+
+ public int getNetworkAvailabilityState(DownloadsDB db) {
+ if (mIsConnected) {
+ if (!mIsCellularConnection)
+ return NETWORK_OK;
+ int flags = db.mFlags;
+ if (mIsRoaming)
+ return NETWORK_CANNOT_USE_ROAMING;
+ if (0 != (flags & FLAGS_DOWNLOAD_OVER_CELLULAR)) {
+ return NETWORK_OK;
+ } else {
+ return NETWORK_TYPE_DISALLOWED_BY_REQUESTOR;
+ }
+ }
+ return NETWORK_NO_CONNECTION;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ mPackageInfo = getPackageManager().getPackageInfo(
+ getPackageName(), 0);
+ ApplicationInfo ai = getApplicationInfo();
+ CharSequence applicationLabel = getPackageManager().getApplicationLabel(ai);
+ mNotification = new DownloadNotification(this, applicationLabel);
+
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Exception thrown from methods called by generateSaveFile() for any fatal
+ * error.
+ */
+ public static class GenerateSaveFileError extends Exception {
+ private static final long serialVersionUID = 3465966015408936540L;
+ int mStatus;
+ String mMessage;
+
+ public GenerateSaveFileError(int status, String message) {
+ mStatus = status;
+ mMessage = message;
+ }
+ }
+
+ /**
+ * Returns the filename (where the file should be saved) from info about a
+ * download
+ */
+ public String generateTempSaveFileName(String fileName) {
+ String path = Helpers.getSaveFilePath(this)
+ + File.separator + fileName + TEMP_EXT;
+ return path;
+ }
+
+ /**
+ * Creates a filename (where the file should be saved) from info about a
+ * download.
+ */
+ public String generateSaveFile(String filename, long filesize)
+ throws GenerateSaveFileError {
+ String path = generateTempSaveFileName(filename);
+ File expPath = new File(path);
+ if (!Helpers.isExternalMediaMounted()) {
+ Log.d(Constants.TAG, "External media not mounted: " + path);
+ throw new GenerateSaveFileError(STATUS_DEVICE_NOT_FOUND_ERROR,
+ "external media is not yet mounted");
+
+ }
+ if (expPath.exists()) {
+ Log.d(Constants.TAG, "File already exists: " + path);
+ throw new GenerateSaveFileError(STATUS_FILE_ALREADY_EXISTS_ERROR,
+ "requested destination file already exists");
+ }
+ if (Helpers.getAvailableBytes(Helpers.getFilesystemRoot(path)) < filesize) {
+ throw new GenerateSaveFileError(STATUS_INSUFFICIENT_SPACE_ERROR,
+ "insufficient space on external storage");
+ }
+ return path;
+ }
+
+ /**
+ * @return a non-localized string appropriate for logging corresponding to
+ * one of the NETWORK_* constants.
+ */
+ public String getLogMessageForNetworkError(int networkError) {
+ switch (networkError) {
+ case NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE:
+ return "download size exceeds recommended limit for mobile network";
+
+ case NETWORK_UNUSABLE_DUE_TO_SIZE:
+ return "download size exceeds limit for mobile network";
+
+ case NETWORK_NO_CONNECTION:
+ return "no network connection available";
+
+ case NETWORK_CANNOT_USE_ROAMING:
+ return "download cannot use the current network connection because it is roaming";
+
+ case NETWORK_TYPE_DISALLOWED_BY_REQUESTOR:
+ return "download was requested to not use the current network type";
+
+ default:
+ return "unknown error with network connectivity";
+ }
+ }
+
+ public int getControl() {
+ return mControl;
+ }
+
+ public int getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Calculating a moving average for the speed so we don't get jumpy
+ * calculations for time etc.
+ */
+ static private final float SMOOTHING_FACTOR = 0.005f;
+
+ public void notifyUpdateBytes(long totalBytesSoFar) {
+ long timeRemaining;
+ long currentTime = SystemClock.uptimeMillis();
+ if (0 != mMillisecondsAtSample) {
+ // we have a sample.
+ long timePassed = currentTime - mMillisecondsAtSample;
+ long bytesInSample = totalBytesSoFar - mBytesAtSample;
+ float currentSpeedSample = (float) bytesInSample / (float) timePassed;
+ if (0 != mAverageDownloadSpeed) {
+ mAverageDownloadSpeed = SMOOTHING_FACTOR * currentSpeedSample
+ + (1 - SMOOTHING_FACTOR) * mAverageDownloadSpeed;
+ } else {
+ mAverageDownloadSpeed = currentSpeedSample;
+ }
+ timeRemaining = (long) ((mTotalLength - totalBytesSoFar) / mAverageDownloadSpeed);
+ } else {
+ timeRemaining = -1;
+ }
+ mMillisecondsAtSample = currentTime;
+ mBytesAtSample = totalBytesSoFar;
+ mNotification.onDownloadProgress(
+ new DownloadProgressInfo(mTotalLength,
+ totalBytesSoFar,
+ timeRemaining,
+ mAverageDownloadSpeed)
+ );
+
+ }
+
+ @Override
+ protected boolean shouldStop() {
+ // the database automatically reads the metadata for version code
+ // and download status when the instance is created
+ DownloadsDB db = DownloadsDB.getDB(this);
+ if (db.mStatus == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void requestDownloadStatus() {
+ mNotification.resendState();
+ }
+
+ @Override
+ public void onClientUpdated(Messenger clientMessenger) {
+ this.mClientMessenger = clientMessenger;
+ mNotification.setMessenger(mClientMessenger);
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java
new file mode 100644
index 0000000000..c658b4cc43
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDoneException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteStatement;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+public class DownloadsDB {
+ private static final String DATABASE_NAME = "DownloadsDB";
+ private static final int DATABASE_VERSION = 7;
+ public static final String LOG_TAG = DownloadsDB.class.getName();
+ final SQLiteOpenHelper mHelper;
+ SQLiteStatement mGetDownloadByIndex;
+ SQLiteStatement mUpdateCurrentBytes;
+ private static DownloadsDB mDownloadsDB;
+ long mMetadataRowID = -1;
+ int mVersionCode = -1;
+ int mStatus = -1;
+ int mFlags;
+
+ static public synchronized DownloadsDB getDB(Context paramContext) {
+ if (null == mDownloadsDB) {
+ return new DownloadsDB(paramContext);
+ }
+ return mDownloadsDB;
+ }
+
+ private SQLiteStatement getDownloadByIndexStatement() {
+ if (null == mGetDownloadByIndex) {
+ mGetDownloadByIndex = mHelper.getReadableDatabase().compileStatement(
+ "SELECT " + BaseColumns._ID + " FROM "
+ + DownloadColumns.TABLE_NAME + " WHERE "
+ + DownloadColumns.INDEX + " = ?");
+ }
+ return mGetDownloadByIndex;
+ }
+
+ private SQLiteStatement getUpdateCurrentBytesStatement() {
+ if (null == mUpdateCurrentBytes) {
+ mUpdateCurrentBytes = mHelper.getReadableDatabase().compileStatement(
+ "UPDATE " + DownloadColumns.TABLE_NAME + " SET " + DownloadColumns.CURRENTBYTES
+ + " = ?" +
+ " WHERE " + DownloadColumns.INDEX + " = ?");
+ }
+ return mUpdateCurrentBytes;
+ }
+
+ private DownloadsDB(Context paramContext) {
+ this.mHelper = new DownloadsContentDBHelper(paramContext);
+ final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
+ // Query for the version code, the row ID of the metadata (for future
+ // updating) the status and the flags
+ Cursor cur = sqldb.rawQuery("SELECT " +
+ MetadataColumns.APKVERSION + "," +
+ BaseColumns._ID + "," +
+ MetadataColumns.DOWNLOAD_STATUS + "," +
+ MetadataColumns.FLAGS +
+ " FROM "
+ + MetadataColumns.TABLE_NAME + " LIMIT 1", null);
+ if (null != cur && cur.moveToFirst()) {
+ mVersionCode = cur.getInt(0);
+ mMetadataRowID = cur.getLong(1);
+ mStatus = cur.getInt(2);
+ mFlags = cur.getInt(3);
+ cur.close();
+ }
+ mDownloadsDB = this;
+ }
+
+ protected DownloadInfo getDownloadInfoByFileName(String fileName) {
+ final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
+ Cursor itemcur = null;
+ try {
+ itemcur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
+ DownloadColumns.FILENAME + " = ?",
+ new String[] {
+ fileName
+ }, null, null, null);
+ if (null != itemcur && itemcur.moveToFirst()) {
+ return getDownloadInfoFromCursor(itemcur);
+ }
+ } finally {
+ if (null != itemcur)
+ itemcur.close();
+ }
+ return null;
+ }
+
+ public long getIDForDownloadInfo(final DownloadInfo di) {
+ return getIDByIndex(di.mIndex);
+ }
+
+ public long getIDByIndex(int index) {
+ SQLiteStatement downloadByIndex = getDownloadByIndexStatement();
+ downloadByIndex.clearBindings();
+ downloadByIndex.bindLong(1, index);
+ try {
+ return downloadByIndex.simpleQueryForLong();
+ } catch (SQLiteDoneException e) {
+ return -1;
+ }
+ }
+
+ public void updateDownloadCurrentBytes(final DownloadInfo di) {
+ SQLiteStatement downloadCurrentBytes = getUpdateCurrentBytesStatement();
+ downloadCurrentBytes.clearBindings();
+ downloadCurrentBytes.bindLong(1, di.mCurrentBytes);
+ downloadCurrentBytes.bindLong(2, di.mIndex);
+ downloadCurrentBytes.execute();
+ }
+
+ public void close() {
+ this.mHelper.close();
+ }
+
+ protected static class DownloadsContentDBHelper extends SQLiteOpenHelper {
+ DownloadsContentDBHelper(Context paramContext) {
+ super(paramContext, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ private String createTableQueryFromArray(String paramString,
+ String[][] paramArrayOfString) {
+ StringBuilder localStringBuilder = new StringBuilder();
+ localStringBuilder.append("CREATE TABLE ");
+ localStringBuilder.append(paramString);
+ localStringBuilder.append(" (");
+ int i = paramArrayOfString.length;
+ for (int j = 0;; j++) {
+ if (j >= i) {
+ localStringBuilder
+ .setLength(localStringBuilder.length() - 1);
+ localStringBuilder.append(");");
+ return localStringBuilder.toString();
+ }
+ String[] arrayOfString = paramArrayOfString[j];
+ localStringBuilder.append(' ');
+ localStringBuilder.append(arrayOfString[0]);
+ localStringBuilder.append(' ');
+ localStringBuilder.append(arrayOfString[1]);
+ localStringBuilder.append(',');
+ }
+ }
+
+ /**
+ * These two arrays must match and have the same order. For every Schema
+ * there must be a corresponding table name.
+ */
+ static final private String[][][] sSchemas = {
+ DownloadColumns.SCHEMA, MetadataColumns.SCHEMA
+ };
+
+ static final private String[] sTables = {
+ DownloadColumns.TABLE_NAME, MetadataColumns.TABLE_NAME
+ };
+
+ /**
+ * Goes through all of the tables in sTables and drops each table if it
+ * exists. Altered to no longer make use of reflection.
+ */
+ private void dropTables(SQLiteDatabase paramSQLiteDatabase) {
+ for (String table : sTables) {
+ try {
+ paramSQLiteDatabase.execSQL("DROP TABLE IF EXISTS " + table);
+ } catch (Exception localException) {
+ localException.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Goes through all of the tables in sTables and creates a database with
+ * the corresponding schema described in sSchemas. Altered to no longer
+ * make use of reflection.
+ */
+ public void onCreate(SQLiteDatabase paramSQLiteDatabase) {
+ int numSchemas = sSchemas.length;
+ for (int i = 0; i < numSchemas; i++) {
+ try {
+ String[][] schema = (String[][]) sSchemas[i];
+ paramSQLiteDatabase.execSQL(createTableQueryFromArray(
+ sTables[i], schema));
+ } catch (Exception localException) {
+ while (true)
+ localException.printStackTrace();
+ }
+ }
+ }
+
+ public void onUpgrade(SQLiteDatabase paramSQLiteDatabase,
+ int paramInt1, int paramInt2) {
+ Log.w(DownloadsContentDBHelper.class.getName(),
+ "Upgrading database from version " + paramInt1 + " to "
+ + paramInt2 + ", which will destroy all old data");
+ dropTables(paramSQLiteDatabase);
+ onCreate(paramSQLiteDatabase);
+ }
+ }
+
+ public static class MetadataColumns implements BaseColumns {
+ public static final String APKVERSION = "APKVERSION";
+ public static final String DOWNLOAD_STATUS = "DOWNLOADSTATUS";
+ public static final String FLAGS = "DOWNLOADFLAGS";
+
+ public static final String[][] SCHEMA = {
+ {
+ BaseColumns._ID, "INTEGER PRIMARY KEY"
+ },
+ {
+ APKVERSION, "INTEGER"
+ }, {
+ DOWNLOAD_STATUS, "INTEGER"
+ },
+ {
+ FLAGS, "INTEGER"
+ }
+ };
+ public static final String TABLE_NAME = "MetadataColumns";
+ public static final String _ID = "MetadataColumns._id";
+ }
+
+ public static class DownloadColumns implements BaseColumns {
+ public static final String INDEX = "FILEIDX";
+ public static final String URI = "URI";
+ public static final String FILENAME = "FN";
+ public static final String ETAG = "ETAG";
+
+ public static final String TOTALBYTES = "TOTALBYTES";
+ public static final String CURRENTBYTES = "CURRENTBYTES";
+ public static final String LASTMOD = "LASTMOD";
+
+ public static final String STATUS = "STATUS";
+ public static final String CONTROL = "CONTROL";
+ public static final String NUM_FAILED = "FAILCOUNT";
+ public static final String RETRY_AFTER = "RETRYAFTER";
+ public static final String REDIRECT_COUNT = "REDIRECTCOUNT";
+
+ public static final String[][] SCHEMA = {
+ {
+ BaseColumns._ID, "INTEGER PRIMARY KEY"
+ },
+ {
+ INDEX, "INTEGER UNIQUE"
+ }, {
+ URI, "TEXT"
+ },
+ {
+ FILENAME, "TEXT UNIQUE"
+ }, {
+ ETAG, "TEXT"
+ },
+ {
+ TOTALBYTES, "INTEGER"
+ }, {
+ CURRENTBYTES, "INTEGER"
+ },
+ {
+ LASTMOD, "INTEGER"
+ }, {
+ STATUS, "INTEGER"
+ },
+ {
+ CONTROL, "INTEGER"
+ }, {
+ NUM_FAILED, "INTEGER"
+ },
+ {
+ RETRY_AFTER, "INTEGER"
+ }, {
+ REDIRECT_COUNT, "INTEGER"
+ }
+ };
+ public static final String TABLE_NAME = "DownloadColumns";
+ public static final String _ID = "DownloadColumns._id";
+ }
+
+ private static final String[] DC_PROJECTION = {
+ DownloadColumns.FILENAME,
+ DownloadColumns.URI, DownloadColumns.ETAG,
+ DownloadColumns.TOTALBYTES, DownloadColumns.CURRENTBYTES,
+ DownloadColumns.LASTMOD, DownloadColumns.STATUS,
+ DownloadColumns.CONTROL, DownloadColumns.NUM_FAILED,
+ DownloadColumns.RETRY_AFTER, DownloadColumns.REDIRECT_COUNT,
+ DownloadColumns.INDEX
+ };
+
+ private static final int FILENAME_IDX = 0;
+ private static final int URI_IDX = 1;
+ private static final int ETAG_IDX = 2;
+ private static final int TOTALBYTES_IDX = 3;
+ private static final int CURRENTBYTES_IDX = 4;
+ private static final int LASTMOD_IDX = 5;
+ private static final int STATUS_IDX = 6;
+ private static final int CONTROL_IDX = 7;
+ private static final int NUM_FAILED_IDX = 8;
+ private static final int RETRY_AFTER_IDX = 9;
+ private static final int REDIRECT_COUNT_IDX = 10;
+ private static final int INDEX_IDX = 11;
+
+ /**
+ * This function will add a new file to the database if it does not exist.
+ *
+ * @param di DownloadInfo that we wish to store
+ * @return the row id of the record to be updated/inserted, or -1
+ */
+ public boolean updateDownload(DownloadInfo di) {
+ ContentValues cv = new ContentValues();
+ cv.put(DownloadColumns.INDEX, di.mIndex);
+ cv.put(DownloadColumns.FILENAME, di.mFileName);
+ cv.put(DownloadColumns.URI, di.mUri);
+ cv.put(DownloadColumns.ETAG, di.mETag);
+ cv.put(DownloadColumns.TOTALBYTES, di.mTotalBytes);
+ cv.put(DownloadColumns.CURRENTBYTES, di.mCurrentBytes);
+ cv.put(DownloadColumns.LASTMOD, di.mLastMod);
+ cv.put(DownloadColumns.STATUS, di.mStatus);
+ cv.put(DownloadColumns.CONTROL, di.mControl);
+ cv.put(DownloadColumns.NUM_FAILED, di.mNumFailed);
+ cv.put(DownloadColumns.RETRY_AFTER, di.mRetryAfter);
+ cv.put(DownloadColumns.REDIRECT_COUNT, di.mRedirectCount);
+ return updateDownload(di, cv);
+ }
+
+ public boolean updateDownload(DownloadInfo di, ContentValues cv) {
+ long id = di == null ? -1 : getIDForDownloadInfo(di);
+ try {
+ final SQLiteDatabase sqldb = mHelper.getWritableDatabase();
+ if (id != -1) {
+ if (1 != sqldb.update(DownloadColumns.TABLE_NAME,
+ cv, DownloadColumns._ID + " = " + id, null)) {
+ return false;
+ }
+ } else {
+ return -1 != sqldb.insert(DownloadColumns.TABLE_NAME,
+ DownloadColumns.URI, cv);
+ }
+ } catch (android.database.sqlite.SQLiteException ex) {
+ ex.printStackTrace();
+ }
+ return false;
+ }
+
+ public int getLastCheckedVersionCode() {
+ return mVersionCode;
+ }
+
+ public boolean isDownloadRequired() {
+ final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
+ Cursor cur = sqldb.rawQuery("SELECT Count(*) FROM "
+ + DownloadColumns.TABLE_NAME + " WHERE "
+ + DownloadColumns.STATUS + " <> 0", null);
+ try {
+ if (null != cur && cur.moveToFirst()) {
+ return 0 == cur.getInt(0);
+ }
+ } finally {
+ if (null != cur)
+ cur.close();
+ }
+ return true;
+ }
+
+ public int getFlags() {
+ return mFlags;
+ }
+
+ public boolean updateFlags(int flags) {
+ if (mFlags != flags) {
+ ContentValues cv = new ContentValues();
+ cv.put(MetadataColumns.FLAGS, flags);
+ if (updateMetadata(cv)) {
+ mFlags = flags;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ };
+
+ public boolean updateStatus(int status) {
+ if (mStatus != status) {
+ ContentValues cv = new ContentValues();
+ cv.put(MetadataColumns.DOWNLOAD_STATUS, status);
+ if (updateMetadata(cv)) {
+ mStatus = status;
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ };
+
+ public boolean updateMetadata(ContentValues cv) {
+ final SQLiteDatabase sqldb = mHelper.getWritableDatabase();
+ if (-1 == this.mMetadataRowID) {
+ long newID = sqldb.insert(MetadataColumns.TABLE_NAME,
+ MetadataColumns.APKVERSION, cv);
+ if (-1 == newID)
+ return false;
+ mMetadataRowID = newID;
+ } else {
+ if (0 == sqldb.update(MetadataColumns.TABLE_NAME, cv,
+ BaseColumns._ID + " = " + mMetadataRowID, null))
+ return false;
+ }
+ return true;
+ }
+
+ public boolean updateMetadata(int apkVersion, int downloadStatus) {
+ ContentValues cv = new ContentValues();
+ cv.put(MetadataColumns.APKVERSION, apkVersion);
+ cv.put(MetadataColumns.DOWNLOAD_STATUS, downloadStatus);
+ if (updateMetadata(cv)) {
+ mVersionCode = apkVersion;
+ mStatus = downloadStatus;
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ public boolean updateFromDb(DownloadInfo di) {
+ final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
+ Cursor cur = null;
+ try {
+ cur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
+ DownloadColumns.FILENAME + "= ?",
+ new String[] {
+ di.mFileName
+ }, null, null, null);
+ if (null != cur && cur.moveToFirst()) {
+ setDownloadInfoFromCursor(di, cur);
+ return true;
+ }
+ return false;
+ } finally {
+ if (null != cur) {
+ cur.close();
+ }
+ }
+ }
+
+ public void setDownloadInfoFromCursor(DownloadInfo di, Cursor cur) {
+ di.mUri = cur.getString(URI_IDX);
+ di.mETag = cur.getString(ETAG_IDX);
+ di.mTotalBytes = cur.getLong(TOTALBYTES_IDX);
+ di.mCurrentBytes = cur.getLong(CURRENTBYTES_IDX);
+ di.mLastMod = cur.getLong(LASTMOD_IDX);
+ di.mStatus = cur.getInt(STATUS_IDX);
+ di.mControl = cur.getInt(CONTROL_IDX);
+ di.mNumFailed = cur.getInt(NUM_FAILED_IDX);
+ di.mRetryAfter = cur.getInt(RETRY_AFTER_IDX);
+ di.mRedirectCount = cur.getInt(REDIRECT_COUNT_IDX);
+ }
+
+ public DownloadInfo getDownloadInfoFromCursor(Cursor cur) {
+ DownloadInfo di = new DownloadInfo(cur.getInt(INDEX_IDX),
+ cur.getString(FILENAME_IDX), this.getClass().getPackage()
+ .getName());
+ setDownloadInfoFromCursor(di, cur);
+ return di;
+ }
+
+ public DownloadInfo[] getDownloads() {
+ final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
+ Cursor cur = null;
+ try {
+ cur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION, null,
+ null, null, null, null);
+ if (null != cur && cur.moveToFirst()) {
+ DownloadInfo[] retInfos = new DownloadInfo[cur.getCount()];
+ int idx = 0;
+ do {
+ DownloadInfo di = getDownloadInfoFromCursor(cur);
+ retInfos[idx++] = di;
+ } while (cur.moveToNext());
+ return retInfos;
+ }
+ return null;
+ } finally {
+ if (null != cur) {
+ cur.close();
+ }
+ }
+ }
+
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java
new file mode 100644
index 0000000000..3f440e9893
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.expansion.downloader.impl;
+
+import android.text.format.Time;
+
+import java.util.Calendar;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Helper for parsing an HTTP date.
+ */
+public final class HttpDateTime {
+
+ /*
+ * Regular expression for parsing HTTP-date. Wdy, DD Mon YYYY HH:MM:SS GMT
+ * RFC 822, updated by RFC 1123 Weekday, DD-Mon-YY HH:MM:SS GMT RFC 850,
+ * obsoleted by RFC 1036 Wdy Mon DD HH:MM:SS YYYY ANSI C's asctime() format
+ * with following variations Wdy, DD-Mon-YYYY HH:MM:SS GMT Wdy, (SP)D Mon
+ * YYYY HH:MM:SS GMT Wdy,DD Mon YYYY HH:MM:SS GMT Wdy, DD-Mon-YY HH:MM:SS
+ * GMT Wdy, DD Mon YYYY HH:MM:SS -HHMM Wdy, DD Mon YYYY HH:MM:SS Wdy Mon
+ * (SP)D HH:MM:SS YYYY Wdy Mon DD HH:MM:SS YYYY GMT HH can be H if the first
+ * digit is zero. Mon can be the full name of the month.
+ */
+ private static final String HTTP_DATE_RFC_REGEXP =
+ "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
+ + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
+
+ private static final String HTTP_DATE_ANSIC_REGEXP =
+ "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
+ + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
+
+ /**
+ * The compiled version of the HTTP-date regular expressions.
+ */
+ private static final Pattern HTTP_DATE_RFC_PATTERN =
+ Pattern.compile(HTTP_DATE_RFC_REGEXP);
+ private static final Pattern HTTP_DATE_ANSIC_PATTERN =
+ Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
+
+ private static class TimeOfDay {
+ TimeOfDay(int h, int m, int s) {
+ this.hour = h;
+ this.minute = m;
+ this.second = s;
+ }
+
+ int hour;
+ int minute;
+ int second;
+ }
+
+ public static long parse(String timeString)
+ throws IllegalArgumentException {
+
+ int date = 1;
+ int month = Calendar.JANUARY;
+ int year = 1970;
+ TimeOfDay timeOfDay;
+
+ Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
+ if (rfcMatcher.find()) {
+ date = getDate(rfcMatcher.group(1));
+ month = getMonth(rfcMatcher.group(2));
+ year = getYear(rfcMatcher.group(3));
+ timeOfDay = getTime(rfcMatcher.group(4));
+ } else {
+ Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
+ if (ansicMatcher.find()) {
+ month = getMonth(ansicMatcher.group(1));
+ date = getDate(ansicMatcher.group(2));
+ timeOfDay = getTime(ansicMatcher.group(3));
+ year = getYear(ansicMatcher.group(4));
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // FIXME: Y2038 BUG!
+ if (year >= 2038) {
+ year = 2038;
+ month = Calendar.JANUARY;
+ date = 1;
+ }
+
+ Time time = new Time(Time.TIMEZONE_UTC);
+ time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
+ month, year);
+ return time.toMillis(false /* use isDst */);
+ }
+
+ private static int getDate(String dateString) {
+ if (dateString.length() == 2) {
+ return (dateString.charAt(0) - '0') * 10
+ + (dateString.charAt(1) - '0');
+ } else {
+ return (dateString.charAt(0) - '0');
+ }
+ }
+
+ /*
+ * jan = 9 + 0 + 13 = 22 feb = 5 + 4 + 1 = 10 mar = 12 + 0 + 17 = 29 apr = 0
+ * + 15 + 17 = 32 may = 12 + 0 + 24 = 36 jun = 9 + 20 + 13 = 42 jul = 9 + 20
+ * + 11 = 40 aug = 0 + 20 + 6 = 26 sep = 18 + 4 + 15 = 37 oct = 14 + 2 + 19
+ * = 35 nov = 13 + 14 + 21 = 48 dec = 3 + 4 + 2 = 9
+ */
+ private static int getMonth(String monthString) {
+ int hash = Character.toLowerCase(monthString.charAt(0)) +
+ Character.toLowerCase(monthString.charAt(1)) +
+ Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
+ switch (hash) {
+ case 22:
+ return Calendar.JANUARY;
+ case 10:
+ return Calendar.FEBRUARY;
+ case 29:
+ return Calendar.MARCH;
+ case 32:
+ return Calendar.APRIL;
+ case 36:
+ return Calendar.MAY;
+ case 42:
+ return Calendar.JUNE;
+ case 40:
+ return Calendar.JULY;
+ case 26:
+ return Calendar.AUGUST;
+ case 37:
+ return Calendar.SEPTEMBER;
+ case 35:
+ return Calendar.OCTOBER;
+ case 48:
+ return Calendar.NOVEMBER;
+ case 9:
+ return Calendar.DECEMBER;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private static int getYear(String yearString) {
+ if (yearString.length() == 2) {
+ int year = (yearString.charAt(0) - '0') * 10
+ + (yearString.charAt(1) - '0');
+ if (year >= 70) {
+ return year + 1900;
+ } else {
+ return year + 2000;
+ }
+ } else if (yearString.length() == 3) {
+ // According to RFC 2822, three digit years should be added to 1900.
+ int year = (yearString.charAt(0) - '0') * 100
+ + (yearString.charAt(1) - '0') * 10
+ + (yearString.charAt(2) - '0');
+ return year + 1900;
+ } else if (yearString.length() == 4) {
+ return (yearString.charAt(0) - '0') * 1000
+ + (yearString.charAt(1) - '0') * 100
+ + (yearString.charAt(2) - '0') * 10
+ + (yearString.charAt(3) - '0');
+ } else {
+ return 1970;
+ }
+ }
+
+ private static TimeOfDay getTime(String timeString) {
+ // HH might be H
+ int i = 0;
+ int hour = timeString.charAt(i++) - '0';
+ if (timeString.charAt(i) != ':')
+ hour = hour * 10 + (timeString.charAt(i++) - '0');
+ // Skip ':'
+ i++;
+
+ int minute = (timeString.charAt(i++) - '0') * 10
+ + (timeString.charAt(i++) - '0');
+ // Skip ':'
+ i++;
+
+ int second = (timeString.charAt(i++) - '0') * 10
+ + (timeString.charAt(i++) - '0');
+
+ return new TimeOfDay(hour, minute, second);
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/AESObfuscator.java b/platform/android/java/lib/src/com/google/android/vending/licensing/AESObfuscator.java
new file mode 100644
index 0000000000..d6ccb0c5e4
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/AESObfuscator.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import com.google.android.vending.licensing.util.Base64;
+import com.google.android.vending.licensing.util.Base64DecoderException;
+
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * An Obfuscator that uses AES to encrypt data.
+ */
+public class AESObfuscator implements Obfuscator {
+ private static final String UTF8 = "UTF-8";
+ private static final String KEYGEN_ALGORITHM = "PBEWITHSHAAND256BITAES-CBC-BC";
+ private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
+ private static final byte[] IV =
+ { 16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74 };
+ private static final String header = "com.google.android.vending.licensing.AESObfuscator-1|";
+
+ private Cipher mEncryptor;
+ private Cipher mDecryptor;
+
+ /**
+ * @param salt an array of random bytes to use for each (un)obfuscation
+ * @param applicationId application identifier, e.g. the package name
+ * @param deviceId device identifier. Use as many sources as possible to
+ * create this unique identifier.
+ */
+ public AESObfuscator(byte[] salt, String applicationId, String deviceId) {
+ try {
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM);
+ KeySpec keySpec =
+ new PBEKeySpec((applicationId + deviceId).toCharArray(), salt, 1024, 256);
+ SecretKey tmp = factory.generateSecret(keySpec);
+ SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
+ mEncryptor = Cipher.getInstance(CIPHER_ALGORITHM);
+ mEncryptor.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(IV));
+ mDecryptor = Cipher.getInstance(CIPHER_ALGORITHM);
+ mDecryptor.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV));
+ } catch (GeneralSecurityException e) {
+ // This can't happen on a compatible Android device.
+ throw new RuntimeException("Invalid environment", e);
+ }
+ }
+
+ public String obfuscate(String original, String key) {
+ if (original == null) {
+ return null;
+ }
+ try {
+ // Header is appended as an integrity check
+ return Base64.encode(mEncryptor.doFinal((header + key + original).getBytes(UTF8)));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Invalid environment", e);
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException("Invalid environment", e);
+ }
+ }
+
+ public String unobfuscate(String obfuscated, String key) throws ValidationException {
+ if (obfuscated == null) {
+ return null;
+ }
+ try {
+ String result = new String(mDecryptor.doFinal(Base64.decode(obfuscated)), UTF8);
+ // Check for presence of header. This serves as a final integrity check, for cases
+ // where the block size is correct during decryption.
+ int headerIndex = result.indexOf(header+key);
+ if (headerIndex != 0) {
+ throw new ValidationException("Header not found (invalid data or key)" + ":" +
+ obfuscated);
+ }
+ return result.substring(header.length()+key.length(), result.length());
+ } catch (Base64DecoderException e) {
+ throw new ValidationException(e.getMessage() + ":" + obfuscated);
+ } catch (IllegalBlockSizeException e) {
+ throw new ValidationException(e.getMessage() + ":" + obfuscated);
+ } catch (BadPaddingException e) {
+ throw new ValidationException(e.getMessage() + ":" + obfuscated);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Invalid environment", e);
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/APKExpansionPolicy.java b/platform/android/java/lib/src/com/google/android/vending/licensing/APKExpansionPolicy.java
new file mode 100644
index 0000000000..37fad8926a
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/APKExpansionPolicy.java
@@ -0,0 +1,414 @@
+
+package com.google.android.vending.licensing;
+
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import com.google.android.vending.licensing.util.URIQueryDecoder;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Default policy. All policy decisions are based off of response data received
+ * from the licensing service. Specifically, the licensing server sends the
+ * following information: response validity period, error retry period,
+ * error retry count and a URL for restoring app access in unlicensed cases.
+ * <p>
+ * These values will vary based on the the way the application is configured in
+ * the Google Play publishing console, such as whether the application is
+ * marked as free or is within its refund period, as well as how often an
+ * application is checking with the licensing service.
+ * <p>
+ * Developers who need more fine grained control over their application's
+ * licensing policy should implement a custom Policy.
+ */
+public class APKExpansionPolicy implements Policy {
+
+ private static final String TAG = "APKExpansionPolicy";
+ private static final String PREFS_FILE = "com.google.android.vending.licensing.APKExpansionPolicy";
+ private static final String PREF_LAST_RESPONSE = "lastResponse";
+ private static final String PREF_VALIDITY_TIMESTAMP = "validityTimestamp";
+ private static final String PREF_RETRY_UNTIL = "retryUntil";
+ private static final String PREF_MAX_RETRIES = "maxRetries";
+ private static final String PREF_RETRY_COUNT = "retryCount";
+ private static final String PREF_LICENSING_URL = "licensingUrl";
+ private static final String DEFAULT_VALIDITY_TIMESTAMP = "0";
+ private static final String DEFAULT_RETRY_UNTIL = "0";
+ private static final String DEFAULT_MAX_RETRIES = "0";
+ private static final String DEFAULT_RETRY_COUNT = "0";
+
+ private static final long MILLIS_PER_MINUTE = 60 * 1000;
+
+ private long mValidityTimestamp;
+ private long mRetryUntil;
+ private long mMaxRetries;
+ private long mRetryCount;
+ private long mLastResponseTime = 0;
+ private int mLastResponse;
+ private String mLicensingUrl;
+ private PreferenceObfuscator mPreferences;
+ private Vector<String> mExpansionURLs = new Vector<String>();
+ private Vector<String> mExpansionFileNames = new Vector<String>();
+ private Vector<Long> mExpansionFileSizes = new Vector<Long>();
+
+ /**
+ * The design of the protocol supports n files. Currently the market can
+ * only deliver two files. To accommodate this, we have these two constants,
+ * but the order is the only relevant thing here.
+ */
+ public static final int MAIN_FILE_URL_INDEX = 0;
+ public static final int PATCH_FILE_URL_INDEX = 1;
+
+ /**
+ * @param context The context for the current application
+ * @param obfuscator An obfuscator to be used with preferences.
+ */
+ public APKExpansionPolicy(Context context, Obfuscator obfuscator) {
+ // Import old values
+ SharedPreferences sp = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);
+ mPreferences = new PreferenceObfuscator(sp, obfuscator);
+ mLastResponse = Integer.parseInt(
+ mPreferences.getString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY)));
+ mValidityTimestamp = Long.parseLong(mPreferences.getString(PREF_VALIDITY_TIMESTAMP,
+ DEFAULT_VALIDITY_TIMESTAMP));
+ mRetryUntil = Long.parseLong(mPreferences.getString(PREF_RETRY_UNTIL, DEFAULT_RETRY_UNTIL));
+ mMaxRetries = Long.parseLong(mPreferences.getString(PREF_MAX_RETRIES, DEFAULT_MAX_RETRIES));
+ mRetryCount = Long.parseLong(mPreferences.getString(PREF_RETRY_COUNT, DEFAULT_RETRY_COUNT));
+ mLicensingUrl = mPreferences.getString(PREF_LICENSING_URL, null);
+ }
+
+ /**
+ * We call this to guarantee that we fetch a fresh policy from the server.
+ * This is to be used if the URL is invalid.
+ */
+ public void resetPolicy() {
+ mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY));
+ setRetryUntil(DEFAULT_RETRY_UNTIL);
+ setMaxRetries(DEFAULT_MAX_RETRIES);
+ setRetryCount(Long.parseLong(DEFAULT_RETRY_COUNT));
+ setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
+ mPreferences.commit();
+ }
+
+ /**
+ * Process a new response from the license server.
+ * <p>
+ * This data will be used for computing future policy decisions. The
+ * following parameters are processed:
+ * <ul>
+ * <li>VT: the timestamp that the client should consider the response valid
+ * until
+ * <li>GT: the timestamp that the client should ignore retry errors until
+ * <li>GR: the number of retry errors that the client should ignore
+ * <li>LU: a deep link URL that can enable access for unlicensed apps (e.g.
+ * buy app on the Play Store)
+ * </ul>
+ *
+ * @param response the result from validating the server response
+ * @param rawData the raw server response data
+ */
+ public void processServerResponse(int response,
+ com.google.android.vending.licensing.ResponseData rawData) {
+
+ // Update retry counter
+ if (response != Policy.RETRY) {
+ setRetryCount(0);
+ } else {
+ setRetryCount(mRetryCount + 1);
+ }
+
+ // Update server policy data
+ Map<String, String> extras = decodeExtras(rawData);
+ if (response == Policy.LICENSED) {
+ mLastResponse = response;
+ // Reset the licensing URL since it is only applicable for NOT_LICENSED responses.
+ setLicensingUrl(null);
+ setValidityTimestamp(Long.toString(System.currentTimeMillis() + MILLIS_PER_MINUTE));
+ Set<String> keys = extras.keySet();
+ for (String key : keys) {
+ if (key.equals("VT")) {
+ setValidityTimestamp(extras.get(key));
+ } else if (key.equals("GT")) {
+ setRetryUntil(extras.get(key));
+ } else if (key.equals("GR")) {
+ setMaxRetries(extras.get(key));
+ } else if (key.startsWith("FILE_URL")) {
+ int index = Integer.parseInt(key.substring("FILE_URL".length())) - 1;
+ setExpansionURL(index, extras.get(key));
+ } else if (key.startsWith("FILE_NAME")) {
+ int index = Integer.parseInt(key.substring("FILE_NAME".length())) - 1;
+ setExpansionFileName(index, extras.get(key));
+ } else if (key.startsWith("FILE_SIZE")) {
+ int index = Integer.parseInt(key.substring("FILE_SIZE".length())) - 1;
+ setExpansionFileSize(index, Long.parseLong(extras.get(key)));
+ }
+ }
+ } else if (response == Policy.NOT_LICENSED) {
+ // Clear out stale retry params
+ setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
+ setRetryUntil(DEFAULT_RETRY_UNTIL);
+ setMaxRetries(DEFAULT_MAX_RETRIES);
+ // Update the licensing URL
+ setLicensingUrl(extras.get("LU"));
+ }
+
+ setLastResponse(response);
+ mPreferences.commit();
+ }
+
+ /**
+ * Set the last license response received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param l the response
+ */
+ private void setLastResponse(int l) {
+ mLastResponseTime = System.currentTimeMillis();
+ mLastResponse = l;
+ mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(l));
+ }
+
+ /**
+ * Set the current retry count and add to preferences. You must manually
+ * call PreferenceObfuscator.commit() to commit these changes to disk.
+ *
+ * @param c the new retry count
+ */
+ private void setRetryCount(long c) {
+ mRetryCount = c;
+ mPreferences.putString(PREF_RETRY_COUNT, Long.toString(c));
+ }
+
+ public long getRetryCount() {
+ return mRetryCount;
+ }
+
+ /**
+ * Set the last validity timestamp (VT) received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param validityTimestamp the VT string received
+ */
+ private void setValidityTimestamp(String validityTimestamp) {
+ Long lValidityTimestamp;
+ try {
+ lValidityTimestamp = Long.parseLong(validityTimestamp);
+ } catch (NumberFormatException e) {
+ // No response or not parseable, expire in one minute.
+ Log.w(TAG, "License validity timestamp (VT) missing, caching for a minute");
+ lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE;
+ validityTimestamp = Long.toString(lValidityTimestamp);
+ }
+
+ mValidityTimestamp = lValidityTimestamp;
+ mPreferences.putString(PREF_VALIDITY_TIMESTAMP, validityTimestamp);
+ }
+
+ public long getValidityTimestamp() {
+ return mValidityTimestamp;
+ }
+
+ /**
+ * Set the retry until timestamp (GT) received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param retryUntil the GT string received
+ */
+ private void setRetryUntil(String retryUntil) {
+ Long lRetryUntil;
+ try {
+ lRetryUntil = Long.parseLong(retryUntil);
+ } catch (NumberFormatException e) {
+ // No response or not parseable, expire immediately
+ Log.w(TAG, "License retry timestamp (GT) missing, grace period disabled");
+ retryUntil = "0";
+ lRetryUntil = 0l;
+ }
+
+ mRetryUntil = lRetryUntil;
+ mPreferences.putString(PREF_RETRY_UNTIL, retryUntil);
+ }
+
+ public long getRetryUntil() {
+ return mRetryUntil;
+ }
+
+ /**
+ * Set the max retries value (GR) as received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param maxRetries the GR string received
+ */
+ private void setMaxRetries(String maxRetries) {
+ Long lMaxRetries;
+ try {
+ lMaxRetries = Long.parseLong(maxRetries);
+ } catch (NumberFormatException e) {
+ // No response or not parseable, expire immediately
+ Log.w(TAG, "Licence retry count (GR) missing, grace period disabled");
+ maxRetries = "0";
+ lMaxRetries = 0l;
+ }
+
+ mMaxRetries = lMaxRetries;
+ mPreferences.putString(PREF_MAX_RETRIES, maxRetries);
+ }
+
+ public long getMaxRetries() {
+ return mMaxRetries;
+ }
+
+ /**
+ * Set the licensing URL that displays a Play Store UI for the user to regain app access.
+ *
+ * @param url the LU string received
+ */
+ private void setLicensingUrl(String url) {
+ mLicensingUrl = url;
+ mPreferences.putString(PREF_LICENSING_URL, url);
+ }
+
+ public String getLicensingUrl() {
+ return mLicensingUrl;
+ }
+
+ /**
+ * Gets the count of expansion URLs. Since expansionURLs are not committed
+ * to preferences, this will return zero if there has been no LVL fetch
+ * in the current session.
+ *
+ * @return the number of expansion URLs. (0,1,2)
+ */
+ public int getExpansionURLCount() {
+ return mExpansionURLs.size();
+ }
+
+ /**
+ * Gets the expansion URL. Since these URLs are not committed to
+ * preferences, this will always return null if there has not been an LVL
+ * fetch in the current session.
+ *
+ * @param index the index of the URL to fetch. This value will be either
+ * MAIN_FILE_URL_INDEX or PATCH_FILE_URL_INDEX
+ */
+ public String getExpansionURL(int index) {
+ if (index < mExpansionURLs.size()) {
+ return mExpansionURLs.elementAt(index);
+ }
+ return null;
+ }
+
+ /**
+ * Sets the expansion URL. Expansion URL's are not committed to preferences,
+ * but are instead intended to be stored when the license response is
+ * processed by the front-end.
+ *
+ * @param index the index of the expansion URL. This value will be either
+ * MAIN_FILE_URL_INDEX or PATCH_FILE_URL_INDEX
+ * @param URL the URL to set
+ */
+ public void setExpansionURL(int index, String URL) {
+ if (index >= mExpansionURLs.size()) {
+ mExpansionURLs.setSize(index + 1);
+ }
+ mExpansionURLs.set(index, URL);
+ }
+
+ public String getExpansionFileName(int index) {
+ if (index < mExpansionFileNames.size()) {
+ return mExpansionFileNames.elementAt(index);
+ }
+ return null;
+ }
+
+ public void setExpansionFileName(int index, String name) {
+ if (index >= mExpansionFileNames.size()) {
+ mExpansionFileNames.setSize(index + 1);
+ }
+ mExpansionFileNames.set(index, name);
+ }
+
+ public long getExpansionFileSize(int index) {
+ if (index < mExpansionFileSizes.size()) {
+ return mExpansionFileSizes.elementAt(index);
+ }
+ return -1;
+ }
+
+ public void setExpansionFileSize(int index, long size) {
+ if (index >= mExpansionFileSizes.size()) {
+ mExpansionFileSizes.setSize(index + 1);
+ }
+ mExpansionFileSizes.set(index, size);
+ }
+
+ /**
+ * {@inheritDoc} This implementation allows access if either:<br>
+ * <ol>
+ * <li>a LICENSED response was received within the validity period
+ * <li>a RETRY response was received in the last minute, and we are under
+ * the RETRY count or in the RETRY period.
+ * </ol>
+ */
+ public boolean allowAccess() {
+ long ts = System.currentTimeMillis();
+ if (mLastResponse == Policy.LICENSED) {
+ // Check if the LICENSED response occurred within the validity
+ // timeout.
+ if (ts <= mValidityTimestamp) {
+ // Cached LICENSED response is still valid.
+ return true;
+ }
+ } else if (mLastResponse == Policy.RETRY &&
+ ts < mLastResponseTime + MILLIS_PER_MINUTE) {
+ // Only allow access if we are within the retry period or we haven't
+ // used up our
+ // max retries.
+ return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
+ }
+ return false;
+ }
+
+ private Map<String, String> decodeExtras(
+ com.google.android.vending.licensing.ResponseData rawData) {
+ Map<String, String> results = new HashMap<String, String>();
+ if (rawData == null) {
+ return results;
+ }
+
+ try {
+ URI rawExtras = new URI("?" + rawData.extra);
+ URIQueryDecoder.DecodeQuery(rawExtras, results);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
+ }
+ return results;
+ }
+
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/DeviceLimiter.java b/platform/android/java/lib/src/com/google/android/vending/licensing/DeviceLimiter.java
index 2384b8b82f..e5c5e2d7ca 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/DeviceLimiter.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/DeviceLimiter.java
@@ -37,11 +37,11 @@ package com.google.android.vending.licensing;
*/
public interface DeviceLimiter {
- /**
+ /**
* Checks if this device is allowed to use the given user's license.
*
* @param userId the user whose license the server responded with
* @return LICENSED if the device is allowed, NOT_LICENSED if not, RETRY if an error occurs
*/
- int isDeviceAllowed(String userId);
+ int isDeviceAllowed(String userId);
}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseChecker.java b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseChecker.java
new file mode 100644
index 0000000000..15017b3425
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseChecker.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.provider.Settings.Secure;
+import android.util.Log;
+
+import com.android.vending.licensing.ILicenseResultListener;
+import com.android.vending.licensing.ILicensingService;
+import com.google.android.vending.licensing.util.Base64;
+import com.google.android.vending.licensing.util.Base64DecoderException;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * Client library for Google Play license verifications.
+ * <p>
+ * The LicenseChecker is configured via a {@link Policy} which contains the logic to determine
+ * whether a user should have access to the application. For example, the Policy can define a
+ * threshold for allowable number of server or client failures before the library reports the user
+ * as not having access.
+ * <p>
+ * Must also provide the Base64-encoded RSA public key associated with your developer account. The
+ * public key is obtainable from the publisher site.
+ */
+public class LicenseChecker implements ServiceConnection {
+ private static final String TAG = "LicenseChecker";
+
+ private static final String KEY_FACTORY_ALGORITHM = "RSA";
+
+ // Timeout value (in milliseconds) for calls to service.
+ private static final int TIMEOUT_MS = 10 * 1000;
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+ private static final boolean DEBUG_LICENSE_ERROR = false;
+
+ private ILicensingService mService;
+
+ private PublicKey mPublicKey;
+ private final Context mContext;
+ private final Policy mPolicy;
+ /**
+ * A handler for running tasks on a background thread. We don't want license processing to block
+ * the UI thread.
+ */
+ private Handler mHandler;
+ private final String mPackageName;
+ private final String mVersionCode;
+ private final Set<LicenseValidator> mChecksInProgress = new HashSet<LicenseValidator>();
+ private final Queue<LicenseValidator> mPendingChecks = new LinkedList<LicenseValidator>();
+
+ /**
+ * @param context a Context
+ * @param policy implementation of Policy
+ * @param encodedPublicKey Base64-encoded RSA public key
+ * @throws IllegalArgumentException if encodedPublicKey is invalid
+ */
+ public LicenseChecker(Context context, Policy policy, String encodedPublicKey) {
+ mContext = context;
+ mPolicy = policy;
+ mPublicKey = generatePublicKey(encodedPublicKey);
+ mPackageName = mContext.getPackageName();
+ mVersionCode = getVersionCode(context, mPackageName);
+ HandlerThread handlerThread = new HandlerThread("background thread");
+ handlerThread.start();
+ mHandler = new Handler(handlerThread.getLooper());
+ }
+
+ /**
+ * Generates a PublicKey instance from a string containing the Base64-encoded public key.
+ *
+ * @param encodedPublicKey Base64-encoded public key
+ * @throws IllegalArgumentException if encodedPublicKey is invalid
+ */
+ private static PublicKey generatePublicKey(String encodedPublicKey) {
+ try {
+ byte[] decodedKey = Base64.decode(encodedPublicKey);
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
+
+ return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
+ } catch (NoSuchAlgorithmException e) {
+ // This won't happen in an Android-compatible environment.
+ throw new RuntimeException(e);
+ } catch (Base64DecoderException e) {
+ Log.e(TAG, "Could not decode from Base64.");
+ throw new IllegalArgumentException(e);
+ } catch (InvalidKeySpecException e) {
+ Log.e(TAG, "Invalid key specification.");
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Checks if the user should have access to the app. Binds the service if necessary.
+ * <p>
+ * NOTE: This call uses a trivially obfuscated string (base64-encoded). For best security, we
+ * recommend obfuscating the string that is passed into bindService using another method of your
+ * own devising.
+ * <p>
+ * source string: "com.android.vending.licensing.ILicensingService"
+ * <p>
+ *
+ * @param callback
+ */
+ public synchronized void checkAccess(LicenseCheckerCallback callback) {
+ // If we have a valid recent LICENSED response, we can skip asking
+ // Market.
+ if (mPolicy.allowAccess()) {
+ Log.i(TAG, "Using cached license response");
+ callback.allow(Policy.LICENSED);
+ } else {
+ LicenseValidator validator = new LicenseValidator(mPolicy, new NullDeviceLimiter(),
+ callback, generateNonce(), mPackageName, mVersionCode);
+
+ if (mService == null) {
+ Log.i(TAG, "Binding to licensing service.");
+ try {
+ boolean bindResult = mContext
+ .bindService(
+ new Intent(
+ new String(
+ // Base64 encoded -
+ // com.android.vending.licensing.ILicensingService
+ // Consider encoding this in another way in your
+ // code to improve security
+ Base64.decode(
+ "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")))
+ // As of Android 5.0, implicit
+ // Service Intents are no longer
+ // allowed because it's not
+ // possible for the user to
+ // participate in disambiguating
+ // them. This does mean we break
+ // compatibility with Android
+ // Cupcake devices with this
+ // release, since setPackage was
+ // added in Donut.
+ .setPackage(
+ new String(
+ // Base64
+ // encoded -
+ // com.android.vending
+ Base64.decode(
+ "Y29tLmFuZHJvaWQudmVuZGluZw=="))),
+ this, // ServiceConnection.
+ Context.BIND_AUTO_CREATE);
+ if (bindResult) {
+ mPendingChecks.offer(validator);
+ } else {
+ Log.e(TAG, "Could not bind to service.");
+ handleServiceConnectionError(validator);
+ }
+ } catch (SecurityException e) {
+ callback.applicationError(LicenseCheckerCallback.ERROR_MISSING_PERMISSION);
+ } catch (Base64DecoderException e) {
+ e.printStackTrace();
+ }
+ } else {
+ mPendingChecks.offer(validator);
+ runChecks();
+ }
+ }
+ }
+
+ /**
+ * Triggers the last deep link licensing URL returned from the server, which redirects users to a
+ * page which enables them to gain access to the app. If no such URL is returned by the server, it
+ * will go to the details page of the app in the Play Store.
+ */
+ public void followLastLicensingUrl(Context context) {
+ String licensingUrl = mPolicy.getLicensingUrl();
+ if (licensingUrl == null) {
+ licensingUrl = "https://play.google.com/store/apps/details?id=" + context.getPackageName();
+ }
+ Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(licensingUrl));
+ context.startActivity(marketIntent);
+ }
+
+ private void runChecks() {
+ LicenseValidator validator;
+ while ((validator = mPendingChecks.poll()) != null) {
+ try {
+ Log.i(TAG, "Calling checkLicense on service for " + validator.getPackageName());
+ mService.checkLicense(
+ validator.getNonce(), validator.getPackageName(),
+ new ResultListener(validator));
+ mChecksInProgress.add(validator);
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException in checkLicense call.", e);
+ handleServiceConnectionError(validator);
+ }
+ }
+ }
+
+ private synchronized void finishCheck(LicenseValidator validator) {
+ mChecksInProgress.remove(validator);
+ if (mChecksInProgress.isEmpty()) {
+ cleanupService();
+ }
+ }
+
+ private class ResultListener extends ILicenseResultListener.Stub {
+ private final LicenseValidator mValidator;
+ private Runnable mOnTimeout;
+
+ public ResultListener(LicenseValidator validator) {
+ mValidator = validator;
+ mOnTimeout = new Runnable() {
+ public void run() {
+ Log.i(TAG, "Check timed out.");
+ handleServiceConnectionError(mValidator);
+ finishCheck(mValidator);
+ }
+ };
+ startTimeout();
+ }
+
+ private static final int ERROR_CONTACTING_SERVER = 0x101;
+ private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
+ private static final int ERROR_NON_MATCHING_UID = 0x103;
+
+ // Runs in IPC thread pool. Post it to the Handler, so we can guarantee
+ // either this or the timeout runs.
+ public void verifyLicense(final int responseCode, final String signedData,
+ final String signature) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ Log.i(TAG, "Received response.");
+ // Make sure it hasn't already timed out.
+ if (mChecksInProgress.contains(mValidator)) {
+ clearTimeout();
+ mValidator.verify(mPublicKey, responseCode, signedData, signature);
+ finishCheck(mValidator);
+ }
+ if (DEBUG_LICENSE_ERROR) {
+ boolean logResponse;
+ String stringError = null;
+ switch (responseCode) {
+ case ERROR_CONTACTING_SERVER:
+ logResponse = true;
+ stringError = "ERROR_CONTACTING_SERVER";
+ break;
+ case ERROR_INVALID_PACKAGE_NAME:
+ logResponse = true;
+ stringError = "ERROR_INVALID_PACKAGE_NAME";
+ break;
+ case ERROR_NON_MATCHING_UID:
+ logResponse = true;
+ stringError = "ERROR_NON_MATCHING_UID";
+ break;
+ default:
+ logResponse = false;
+ }
+
+ if (logResponse) {
+ String android_id = Secure.getString(mContext.getContentResolver(),
+ Secure.ANDROID_ID);
+ Date date = new Date();
+ Log.d(TAG, "Server Failure: " + stringError);
+ Log.d(TAG, "Android ID: " + android_id);
+ Log.d(TAG, "Time: " + date.toGMTString());
+ }
+ }
+
+ }
+ });
+ }
+
+ private void startTimeout() {
+ Log.i(TAG, "Start monitoring timeout.");
+ mHandler.postDelayed(mOnTimeout, TIMEOUT_MS);
+ }
+
+ private void clearTimeout() {
+ Log.i(TAG, "Clearing timeout.");
+ mHandler.removeCallbacks(mOnTimeout);
+ }
+ }
+
+ public synchronized void onServiceConnected(ComponentName name, IBinder service) {
+ mService = ILicensingService.Stub.asInterface(service);
+ runChecks();
+ }
+
+ public synchronized void onServiceDisconnected(ComponentName name) {
+ // Called when the connection with the service has been
+ // unexpectedly disconnected. That is, Market crashed.
+ // If there are any checks in progress, the timeouts will handle them.
+ Log.w(TAG, "Service unexpectedly disconnected.");
+ mService = null;
+ }
+
+ /**
+ * Generates policy response for service connection errors, as a result of disconnections or
+ * timeouts.
+ */
+ private synchronized void handleServiceConnectionError(LicenseValidator validator) {
+ mPolicy.processServerResponse(Policy.RETRY, null);
+
+ if (mPolicy.allowAccess()) {
+ validator.getCallback().allow(Policy.RETRY);
+ } else {
+ validator.getCallback().dontAllow(Policy.RETRY);
+ }
+ }
+
+ /** Unbinds service if necessary and removes reference to it. */
+ private void cleanupService() {
+ if (mService != null) {
+ try {
+ mContext.unbindService(this);
+ } catch (IllegalArgumentException e) {
+ // Somehow we've already been unbound. This is a non-fatal
+ // error.
+ Log.e(TAG, "Unable to unbind from licensing service (already unbound)");
+ }
+ mService = null;
+ }
+ }
+
+ /**
+ * Inform the library that the context is about to be destroyed, so that any open connections
+ * can be cleaned up.
+ * <p>
+ * Failure to call this method can result in a crash under certain circumstances, such as during
+ * screen rotation if an Activity requests the license check or when the user exits the
+ * application.
+ */
+ public synchronized void onDestroy() {
+ cleanupService();
+ mHandler.getLooper().quit();
+ }
+
+ /** Generates a nonce (number used once). */
+ private int generateNonce() {
+ return RANDOM.nextInt();
+ }
+
+ /**
+ * Get version code for the application package name.
+ *
+ * @param context
+ * @param packageName application package name
+ * @return the version code or empty string if package not found
+ */
+ private static String getVersionCode(Context context, String packageName) {
+ try {
+ return String.valueOf(
+ context.getPackageManager().getPackageInfo(packageName, 0).versionCode);
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Package not found. could not get version code.");
+ return "";
+ }
+ }
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/LicenseCheckerCallback.java b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseCheckerCallback.java
index dc2c2d70bf..8b869ddaaf 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/LicenseCheckerCallback.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseCheckerCallback.java
@@ -34,34 +34,34 @@ package com.google.android.vending.licensing;
*/
public interface LicenseCheckerCallback {
- /**
+ /**
* Allow use. App should proceed as normal.
*
* @param reason Policy.LICENSED or Policy.RETRY typically. (although in
* theory the policy can return Policy.NOT_LICENSED here as well)
*/
- public void allow(int reason);
+ public void allow(int reason);
- /**
+ /**
* Don't allow use. App should inform user and take appropriate action.
*
* @param reason Policy.NOT_LICENSED or Policy.RETRY. (although in theory
* the policy can return Policy.LICENSED here as well ---
* perhaps the call to the LVL took too long, for example)
*/
- public void dontAllow(int reason);
+ public void dontAllow(int reason);
- /** Application error codes. */
- public static final int ERROR_INVALID_PACKAGE_NAME = 1;
- public static final int ERROR_NON_MATCHING_UID = 2;
- public static final int ERROR_NOT_MARKET_MANAGED = 3;
- public static final int ERROR_CHECK_IN_PROGRESS = 4;
- public static final int ERROR_INVALID_PUBLIC_KEY = 5;
- public static final int ERROR_MISSING_PERMISSION = 6;
+ /** Application error codes. */
+ public static final int ERROR_INVALID_PACKAGE_NAME = 1;
+ public static final int ERROR_NON_MATCHING_UID = 2;
+ public static final int ERROR_NOT_MARKET_MANAGED = 3;
+ public static final int ERROR_CHECK_IN_PROGRESS = 4;
+ public static final int ERROR_INVALID_PUBLIC_KEY = 5;
+ public static final int ERROR_MISSING_PERMISSION = 6;
- /**
+ /**
* Error in application code. Caller did not call or set up license checker
* correctly. Should be considered fatal.
*/
- public void applicationError(int errorCode);
+ public void applicationError(int errorCode);
}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseValidator.java b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseValidator.java
new file mode 100644
index 0000000000..11a00786d0
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/LicenseValidator.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import com.google.android.vending.licensing.util.Base64;
+import com.google.android.vending.licensing.util.Base64DecoderException;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+
+/**
+ * Contains data related to a licensing request and methods to verify
+ * and process the response.
+ */
+class LicenseValidator {
+ private static final String TAG = "LicenseValidator";
+
+ // Server response codes.
+ private static final int LICENSED = 0x0;
+ private static final int NOT_LICENSED = 0x1;
+ private static final int LICENSED_OLD_KEY = 0x2;
+ private static final int ERROR_NOT_MARKET_MANAGED = 0x3;
+ private static final int ERROR_SERVER_FAILURE = 0x4;
+ private static final int ERROR_OVER_QUOTA = 0x5;
+
+ private static final int ERROR_CONTACTING_SERVER = 0x101;
+ private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
+ private static final int ERROR_NON_MATCHING_UID = 0x103;
+
+ private final Policy mPolicy;
+ private final LicenseCheckerCallback mCallback;
+ private final int mNonce;
+ private final String mPackageName;
+ private final String mVersionCode;
+ private final DeviceLimiter mDeviceLimiter;
+
+ LicenseValidator(Policy policy, DeviceLimiter deviceLimiter, LicenseCheckerCallback callback,
+ int nonce, String packageName, String versionCode) {
+ mPolicy = policy;
+ mDeviceLimiter = deviceLimiter;
+ mCallback = callback;
+ mNonce = nonce;
+ mPackageName = packageName;
+ mVersionCode = versionCode;
+ }
+
+ public LicenseCheckerCallback getCallback() {
+ return mCallback;
+ }
+
+ public int getNonce() {
+ return mNonce;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
+
+ /**
+ * Verifies the response from server and calls appropriate callback method.
+ *
+ * @param publicKey public key associated with the developer account
+ * @param responseCode server response code
+ * @param signedData signed data from server
+ * @param signature server signature
+ */
+ public void verify(PublicKey publicKey, int responseCode, String signedData, String signature) {
+ String userId = null;
+ // Skip signature check for unsuccessful requests
+ ResponseData data = null;
+ if (responseCode == LICENSED || responseCode == NOT_LICENSED ||
+ responseCode == LICENSED_OLD_KEY) {
+ // Verify signature.
+ try {
+ if (TextUtils.isEmpty(signedData)) {
+ Log.e(TAG, "Signature verification failed: signedData is empty. " +
+ "(Device not signed-in to any Google accounts?)");
+ handleInvalidResponse();
+ return;
+ }
+
+ Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
+ sig.initVerify(publicKey);
+ sig.update(signedData.getBytes());
+
+ if (!sig.verify(Base64.decode(signature))) {
+ Log.e(TAG, "Signature verification failed.");
+ handleInvalidResponse();
+ return;
+ }
+ } catch (NoSuchAlgorithmException e) {
+ // This can't happen on an Android compatible device.
+ throw new RuntimeException(e);
+ } catch (InvalidKeyException e) {
+ handleApplicationError(LicenseCheckerCallback.ERROR_INVALID_PUBLIC_KEY);
+ return;
+ } catch (SignatureException e) {
+ throw new RuntimeException(e);
+ } catch (Base64DecoderException e) {
+ Log.e(TAG, "Could not Base64-decode signature.");
+ handleInvalidResponse();
+ return;
+ }
+
+ // Parse and validate response.
+ try {
+ data = ResponseData.parse(signedData);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Could not parse response.");
+ handleInvalidResponse();
+ return;
+ }
+
+ if (data.responseCode != responseCode) {
+ Log.e(TAG, "Response codes don't match.");
+ handleInvalidResponse();
+ return;
+ }
+
+ if (data.nonce != mNonce) {
+ Log.e(TAG, "Nonce doesn't match.");
+ handleInvalidResponse();
+ return;
+ }
+
+ if (!data.packageName.equals(mPackageName)) {
+ Log.e(TAG, "Package name doesn't match.");
+ handleInvalidResponse();
+ return;
+ }
+
+ if (!data.versionCode.equals(mVersionCode)) {
+ Log.e(TAG, "Version codes don't match.");
+ handleInvalidResponse();
+ return;
+ }
+
+ // Application-specific user identifier.
+ userId = data.userId;
+ if (TextUtils.isEmpty(userId)) {
+ Log.e(TAG, "User identifier is empty.");
+ handleInvalidResponse();
+ return;
+ }
+ }
+
+ switch (responseCode) {
+ case LICENSED:
+ case LICENSED_OLD_KEY:
+ int limiterResponse = mDeviceLimiter.isDeviceAllowed(userId);
+ handleResponse(limiterResponse, data);
+ break;
+ case NOT_LICENSED:
+ handleResponse(Policy.NOT_LICENSED, data);
+ break;
+ case ERROR_CONTACTING_SERVER:
+ Log.w(TAG, "Error contacting licensing server.");
+ handleResponse(Policy.RETRY, data);
+ break;
+ case ERROR_SERVER_FAILURE:
+ Log.w(TAG, "An error has occurred on the licensing server.");
+ handleResponse(Policy.RETRY, data);
+ break;
+ case ERROR_OVER_QUOTA:
+ Log.w(TAG, "Licensing server is refusing to talk to this device, over quota.");
+ handleResponse(Policy.RETRY, data);
+ break;
+ case ERROR_INVALID_PACKAGE_NAME:
+ handleApplicationError(LicenseCheckerCallback.ERROR_INVALID_PACKAGE_NAME);
+ break;
+ case ERROR_NON_MATCHING_UID:
+ handleApplicationError(LicenseCheckerCallback.ERROR_NON_MATCHING_UID);
+ break;
+ case ERROR_NOT_MARKET_MANAGED:
+ handleApplicationError(LicenseCheckerCallback.ERROR_NOT_MARKET_MANAGED);
+ break;
+ default:
+ Log.e(TAG, "Unknown response code for license check.");
+ handleInvalidResponse();
+ }
+ }
+
+ /**
+ * Confers with policy and calls appropriate callback method.
+ *
+ * @param response
+ * @param rawData
+ */
+ private void handleResponse(int response, ResponseData rawData) {
+ // Update policy data and increment retry counter (if needed)
+ mPolicy.processServerResponse(response, rawData);
+
+ // Given everything we know, including cached data, ask the policy if we should grant
+ // access.
+ if (mPolicy.allowAccess()) {
+ mCallback.allow(response);
+ } else {
+ mCallback.dontAllow(response);
+ }
+ }
+
+ private void handleApplicationError(int code) {
+ mCallback.applicationError(code);
+ }
+
+ private void handleInvalidResponse() {
+ mCallback.dontAllow(Policy.NOT_LICENSED);
+ }
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/NullDeviceLimiter.java b/platform/android/java/lib/src/com/google/android/vending/licensing/NullDeviceLimiter.java
index a43e454228..d87af3153f 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/NullDeviceLimiter.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/NullDeviceLimiter.java
@@ -26,7 +26,7 @@ package com.google.android.vending.licensing;
*/
public class NullDeviceLimiter implements DeviceLimiter {
- public int isDeviceAllowed(String userId) {
- return Policy.LICENSED;
- }
+ public int isDeviceAllowed(String userId) {
+ return Policy.LICENSED;
+ }
}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/Obfuscator.java b/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java
index 8731d03aa6..008c150a8e 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/Obfuscator.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/Obfuscator.java
@@ -27,16 +27,16 @@ package com.google.android.vending.licensing;
*/
public interface Obfuscator {
- /**
+ /**
* Obfuscate a string that is being stored into shared preferences.
*
* @param original The data that is to be obfuscated.
* @param key The key for the data that is to be obfuscated.
* @return A transformed version of the original data.
*/
- String obfuscate(String original, String key);
+ String obfuscate(String original, String key);
- /**
+ /**
* Undo the transformation applied to data by the obfuscate() method.
*
* @param obfuscated The data that is to be un-obfuscated.
@@ -44,5 +44,5 @@ public interface Obfuscator {
* @return The original data transformed by the obfuscate() method.
* @throws ValidationException Optionally thrown if a data integrity check fails.
*/
- String unobfuscate(String obfuscated, String key) throws ValidationException;
+ String unobfuscate(String obfuscated, String key) throws ValidationException;
}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/Policy.java b/platform/android/java/lib/src/com/google/android/vending/licensing/Policy.java
index 65202aceb9..b672a078b7 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/Policy.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/Policy.java
@@ -22,27 +22,27 @@ package com.google.android.vending.licensing;
*/
public interface Policy {
- /**
+ /**
* Change these values to make it more difficult for tools to automatically
* strip LVL protection from your APK.
*/
- /**
+ /**
* LICENSED means that the server returned back a valid license response
*/
- public static final int LICENSED = 0x0100;
- /**
+ public static final int LICENSED = 0x0100;
+ /**
* NOT_LICENSED means that the server returned back a valid license response
* that indicated that the user definitively is not licensed
*/
- public static final int NOT_LICENSED = 0x0231;
- /**
+ public static final int NOT_LICENSED = 0x0231;
+ /**
* RETRY means that the license response was unable to be determined ---
* perhaps as a result of faulty networking
*/
- public static final int RETRY = 0x0123;
+ public static final int RETRY = 0x0123;
- /**
+ /**
* Provide results from contact with the license server. Retry counts are
* incremented if the current value of response is RETRY. Results will be
* used for any future policy decisions.
@@ -50,16 +50,16 @@ public interface Policy {
* @param response the result from validating the server response
* @param rawData the raw server response data, can be null for RETRY
*/
- void processServerResponse(int response, ResponseData rawData);
+ void processServerResponse(int response, ResponseData rawData);
- /**
+ /**
* Check if the user should be allowed access to the application.
*/
- boolean allowAccess();
+ boolean allowAccess();
- /**
+ /**
* Gets the licensing URL returned by the server that can enable access for unlicensed apps (e.g.
* buy app on the Play Store).
*/
- String getLicensingUrl();
+ String getLicensingUrl();
}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/PreferenceObfuscator.java b/platform/android/java/lib/src/com/google/android/vending/licensing/PreferenceObfuscator.java
new file mode 100644
index 0000000000..feb579af04
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/PreferenceObfuscator.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import android.content.SharedPreferences;
+import android.util.Log;
+
+/**
+ * An wrapper for SharedPreferences that transparently performs data obfuscation.
+ */
+public class PreferenceObfuscator {
+
+ private static final String TAG = "PreferenceObfuscator";
+
+ private final SharedPreferences mPreferences;
+ private final Obfuscator mObfuscator;
+ private SharedPreferences.Editor mEditor;
+
+ /**
+ * Constructor.
+ *
+ * @param sp A SharedPreferences instance provided by the system.
+ * @param o The Obfuscator to use when reading or writing data.
+ */
+ public PreferenceObfuscator(SharedPreferences sp, Obfuscator o) {
+ mPreferences = sp;
+ mObfuscator = o;
+ mEditor = null;
+ }
+
+ public void putString(String key, String value) {
+ if (mEditor == null) {
+ mEditor = mPreferences.edit();
+ // -- GODOT start --
+ mEditor.apply();
+ // -- GODOT end --
+ }
+ String obfuscatedValue = mObfuscator.obfuscate(value, key);
+ mEditor.putString(key, obfuscatedValue);
+ }
+
+ public String getString(String key, String defValue) {
+ String result;
+ String value = mPreferences.getString(key, null);
+ if (value != null) {
+ try {
+ result = mObfuscator.unobfuscate(value, key);
+ } catch (ValidationException e) {
+ // Unable to unobfuscate, data corrupt or tampered
+ Log.w(TAG, "Validation error while reading preference: " + key);
+ result = defValue;
+ }
+ } else {
+ // Preference not found
+ result = defValue;
+ }
+ return result;
+ }
+
+ public void commit() {
+ if (mEditor != null) {
+ mEditor.commit();
+ mEditor = null;
+ }
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/ResponseData.java b/platform/android/java/lib/src/com/google/android/vending/licensing/ResponseData.java
new file mode 100644
index 0000000000..3b5d557e76
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/ResponseData.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import android.text.TextUtils;
+
+import java.util.regex.Pattern;
+
+/**
+ * ResponseData from licensing server.
+ */
+public class ResponseData {
+
+ public int responseCode;
+ public int nonce;
+ public String packageName;
+ public String versionCode;
+ public String userId;
+ public long timestamp;
+ /** Response-specific data. */
+ public String extra;
+
+ /**
+ * Parses response string into ResponseData.
+ *
+ * @param responseData response data string
+ * @throws IllegalArgumentException upon parsing error
+ * @return ResponseData object
+ */
+ public static ResponseData parse(String responseData) {
+ // Must parse out main response data and response-specific data.
+ int index = responseData.indexOf(':');
+ String mainData, extraData;
+ if (-1 == index) {
+ mainData = responseData;
+ extraData = "";
+ } else {
+ mainData = responseData.substring(0, index);
+ extraData = index >= responseData.length() ? "" : responseData.substring(index + 1);
+ }
+
+ String[] fields = TextUtils.split(mainData, Pattern.quote("|"));
+ if (fields.length < 6) {
+ throw new IllegalArgumentException("Wrong number of fields.");
+ }
+
+ ResponseData data = new ResponseData();
+ data.extra = extraData;
+ data.responseCode = Integer.parseInt(fields[0]);
+ data.nonce = Integer.parseInt(fields[1]);
+ data.packageName = fields[2];
+ data.versionCode = fields[3];
+ // Application-specific user identifier.
+ data.userId = fields[4];
+ data.timestamp = Long.parseLong(fields[5]);
+
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return TextUtils.join("|", new Object[] {
+ responseCode, nonce, packageName, versionCode,
+ userId, timestamp
+ });
+ }
+}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/ServerManagedPolicy.java b/platform/android/java/lib/src/com/google/android/vending/licensing/ServerManagedPolicy.java
new file mode 100644
index 0000000000..e2f0bfdca8
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/ServerManagedPolicy.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.google.android.vending.licensing;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import com.google.android.vending.licensing.util.URIQueryDecoder;
+
+/**
+ * Default policy. All policy decisions are based off of response data received
+ * from the licensing service. Specifically, the licensing server sends the
+ * following information: response validity period, error retry period,
+ * error retry count and a URL for restoring app access in unlicensed cases.
+ * <p>
+ * These values will vary based on the the way the application is configured in
+ * the Google Play publishing console, such as whether the application is
+ * marked as free or is within its refund period, as well as how often an
+ * application is checking with the licensing service.
+ * <p>
+ * Developers who need more fine grained control over their application's
+ * licensing policy should implement a custom Policy.
+ */
+public class ServerManagedPolicy implements Policy {
+
+ private static final String TAG = "ServerManagedPolicy";
+ private static final String PREFS_FILE = "com.google.android.vending.licensing.ServerManagedPolicy";
+ private static final String PREF_LAST_RESPONSE = "lastResponse";
+ private static final String PREF_VALIDITY_TIMESTAMP = "validityTimestamp";
+ private static final String PREF_RETRY_UNTIL = "retryUntil";
+ private static final String PREF_MAX_RETRIES = "maxRetries";
+ private static final String PREF_RETRY_COUNT = "retryCount";
+ private static final String PREF_LICENSING_URL = "licensingUrl";
+ private static final String DEFAULT_VALIDITY_TIMESTAMP = "0";
+ private static final String DEFAULT_RETRY_UNTIL = "0";
+ private static final String DEFAULT_MAX_RETRIES = "0";
+ private static final String DEFAULT_RETRY_COUNT = "0";
+
+ private static final long MILLIS_PER_MINUTE = 60 * 1000;
+
+ private long mValidityTimestamp;
+ private long mRetryUntil;
+ private long mMaxRetries;
+ private long mRetryCount;
+ private long mLastResponseTime = 0;
+ private int mLastResponse;
+ private String mLicensingUrl;
+ private PreferenceObfuscator mPreferences;
+
+ /**
+ * @param context The context for the current application
+ * @param obfuscator An obfuscator to be used with preferences.
+ */
+ public ServerManagedPolicy(Context context, Obfuscator obfuscator) {
+ // Import old values
+ SharedPreferences sp = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);
+ mPreferences = new PreferenceObfuscator(sp, obfuscator);
+ mLastResponse = Integer.parseInt(
+ mPreferences.getString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY)));
+ mValidityTimestamp = Long.parseLong(mPreferences.getString(PREF_VALIDITY_TIMESTAMP,
+ DEFAULT_VALIDITY_TIMESTAMP));
+ mRetryUntil = Long.parseLong(mPreferences.getString(PREF_RETRY_UNTIL, DEFAULT_RETRY_UNTIL));
+ mMaxRetries = Long.parseLong(mPreferences.getString(PREF_MAX_RETRIES, DEFAULT_MAX_RETRIES));
+ mRetryCount = Long.parseLong(mPreferences.getString(PREF_RETRY_COUNT, DEFAULT_RETRY_COUNT));
+ mLicensingUrl = mPreferences.getString(PREF_LICENSING_URL, null);
+ }
+
+ /**
+ * Process a new response from the license server.
+ * <p>
+ * This data will be used for computing future policy decisions. The
+ * following parameters are processed:
+ * <ul>
+ * <li>VT: the timestamp that the client should consider the response valid
+ * until
+ * <li>GT: the timestamp that the client should ignore retry errors until
+ * <li>GR: the number of retry errors that the client should ignore
+ * <li>LU: a deep link URL that can enable access for unlicensed apps (e.g.
+ * buy app on the Play Store)
+ * </ul>
+ *
+ * @param response the result from validating the server response
+ * @param rawData the raw server response data
+ */
+ public void processServerResponse(int response, ResponseData rawData) {
+
+ // Update retry counter
+ if (response != Policy.RETRY) {
+ setRetryCount(0);
+ } else {
+ setRetryCount(mRetryCount + 1);
+ }
+
+ // Update server policy data
+ Map<String, String> extras = decodeExtras(rawData);
+ if (response == Policy.LICENSED) {
+ mLastResponse = response;
+ // Reset the licensing URL since it is only applicable for NOT_LICENSED responses.
+ setLicensingUrl(null);
+ setValidityTimestamp(extras.get("VT"));
+ setRetryUntil(extras.get("GT"));
+ setMaxRetries(extras.get("GR"));
+ } else if (response == Policy.NOT_LICENSED) {
+ // Clear out stale retry params
+ setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
+ setRetryUntil(DEFAULT_RETRY_UNTIL);
+ setMaxRetries(DEFAULT_MAX_RETRIES);
+ // Update the licensing URL
+ setLicensingUrl(extras.get("LU"));
+ }
+
+ setLastResponse(response);
+ mPreferences.commit();
+ }
+
+ /**
+ * Set the last license response received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param l the response
+ */
+ private void setLastResponse(int l) {
+ mLastResponseTime = System.currentTimeMillis();
+ mLastResponse = l;
+ mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(l));
+ }
+
+ /**
+ * Set the current retry count and add to preferences. You must manually
+ * call PreferenceObfuscator.commit() to commit these changes to disk.
+ *
+ * @param c the new retry count
+ */
+ private void setRetryCount(long c) {
+ mRetryCount = c;
+ mPreferences.putString(PREF_RETRY_COUNT, Long.toString(c));
+ }
+
+ public long getRetryCount() {
+ return mRetryCount;
+ }
+
+ /**
+ * Set the last validity timestamp (VT) received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param validityTimestamp the VT string received
+ */
+ private void setValidityTimestamp(String validityTimestamp) {
+ Long lValidityTimestamp;
+ try {
+ lValidityTimestamp = Long.parseLong(validityTimestamp);
+ } catch (NumberFormatException e) {
+ // No response or not parsable, expire in one minute.
+ Log.w(TAG, "License validity timestamp (VT) missing, caching for a minute");
+ lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE;
+ validityTimestamp = Long.toString(lValidityTimestamp);
+ }
+
+ mValidityTimestamp = lValidityTimestamp;
+ mPreferences.putString(PREF_VALIDITY_TIMESTAMP, validityTimestamp);
+ }
+
+ public long getValidityTimestamp() {
+ return mValidityTimestamp;
+ }
+
+ /**
+ * Set the retry until timestamp (GT) received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param retryUntil the GT string received
+ */
+ private void setRetryUntil(String retryUntil) {
+ Long lRetryUntil;
+ try {
+ lRetryUntil = Long.parseLong(retryUntil);
+ } catch (NumberFormatException e) {
+ // No response or not parsable, expire immediately
+ Log.w(TAG, "License retry timestamp (GT) missing, grace period disabled");
+ retryUntil = "0";
+ lRetryUntil = 0l;
+ }
+
+ mRetryUntil = lRetryUntil;
+ mPreferences.putString(PREF_RETRY_UNTIL, retryUntil);
+ }
+
+ public long getRetryUntil() {
+ return mRetryUntil;
+ }
+
+ /**
+ * Set the max retries value (GR) as received from the server and add to
+ * preferences. You must manually call PreferenceObfuscator.commit() to
+ * commit these changes to disk.
+ *
+ * @param maxRetries the GR string received
+ */
+ private void setMaxRetries(String maxRetries) {
+ Long lMaxRetries;
+ try {
+ lMaxRetries = Long.parseLong(maxRetries);
+ } catch (NumberFormatException e) {
+ // No response or not parsable, expire immediately
+ Log.w(TAG, "Licence retry count (GR) missing, grace period disabled");
+ maxRetries = "0";
+ lMaxRetries = 0l;
+ }
+
+ mMaxRetries = lMaxRetries;
+ mPreferences.putString(PREF_MAX_RETRIES, maxRetries);
+ }
+
+ public long getMaxRetries() {
+ return mMaxRetries;
+ }
+
+ /**
+ * Set the license URL value (LU) as received from the server and add to preferences. You must
+ * manually call PreferenceObfuscator.commit() to commit these changes to disk.
+ *
+ * @param url the LU string received
+ */
+ private void setLicensingUrl(String url) {
+ mLicensingUrl = url;
+ mPreferences.putString(PREF_LICENSING_URL, url);
+ }
+
+ public String getLicensingUrl() {
+ return mLicensingUrl;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation allows access if either:<br>
+ * <ol>
+ * <li>a LICENSED response was received within the validity period
+ * <li>a RETRY response was received in the last minute, and we are under
+ * the RETRY count or in the RETRY period.
+ * </ol>
+ */
+ public boolean allowAccess() {
+ long ts = System.currentTimeMillis();
+ if (mLastResponse == Policy.LICENSED) {
+ // Check if the LICENSED response occurred within the validity timeout.
+ if (ts <= mValidityTimestamp) {
+ // Cached LICENSED response is still valid.
+ return true;
+ }
+ } else if (mLastResponse == Policy.RETRY &&
+ ts < mLastResponseTime + MILLIS_PER_MINUTE) {
+ // Only allow access if we are within the retry period or we haven't used up our
+ // max retries.
+ return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
+ }
+ return false;
+ }
+
+ private Map<String, String> decodeExtras(
+ com.google.android.vending.licensing.ResponseData rawData) {
+ Map<String, String> results = new HashMap<String, String>();
+ if (rawData == null) {
+ return results;
+ }
+
+ try {
+ URI rawExtras = new URI("?" + rawData.extra);
+ URIQueryDecoder.DecodeQuery(rawExtras, results);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
+ }
+ return results;
+ }
+
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/StrictPolicy.java b/platform/android/java/lib/src/com/google/android/vending/licensing/StrictPolicy.java
index 9849730c38..c2d55c37f1 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/StrictPolicy.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/StrictPolicy.java
@@ -38,18 +38,18 @@ import java.util.Map;
*/
public class StrictPolicy implements Policy {
- private static final String TAG = "StrictPolicy";
+ private static final String TAG = "StrictPolicy";
- private int mLastResponse;
- private String mLicensingUrl;
+ private int mLastResponse;
+ private String mLicensingUrl;
- public StrictPolicy() {
- // Set default policy. This will force the application to check the policy on launch.
- mLastResponse = Policy.RETRY;
- mLicensingUrl = null;
- }
+ public StrictPolicy() {
+ // Set default policy. This will force the application to check the policy on launch.
+ mLastResponse = Policy.RETRY;
+ mLicensingUrl = null;
+ }
- /**
+ /**
* Process a new response from the license server. Since we aren't
* performing any caching, this equates to reading the LicenseResponse.
* Any cache-related ResponseData is ignored, but the licensing URL
@@ -58,42 +58,43 @@ public class StrictPolicy implements Policy {
* @param response the result from validating the server response
* @param rawData the raw server response data
*/
- public void processServerResponse(int response, ResponseData rawData) {
- mLastResponse = response;
+ public void processServerResponse(int response, ResponseData rawData) {
+ mLastResponse = response;
- if (response == Policy.NOT_LICENSED) {
- Map<String, String> extras = decodeExtras(rawData);
- mLicensingUrl = extras.get("LU");
- }
- }
+ if (response == Policy.NOT_LICENSED) {
+ Map<String, String> extras = decodeExtras(rawData);
+ mLicensingUrl = extras.get("LU");
+ }
+ }
- /**
+ /**
* {@inheritDoc}
*
* This implementation allows access if and only if a LICENSED response
* was received the last time the server was contacted.
*/
- public boolean allowAccess() {
- return (mLastResponse == Policy.LICENSED);
- }
+ public boolean allowAccess() {
+ return (mLastResponse == Policy.LICENSED);
+ }
- public String getLicensingUrl() {
- return mLicensingUrl;
- }
+ public String getLicensingUrl() {
+ return mLicensingUrl;
+ }
- private Map<String, String> decodeExtras(
- com.google.android.vending.licensing.ResponseData rawData) {
- Map<String, String> results = new HashMap<String, String>();
- if (rawData == null) {
- return results;
- }
+ private Map<String, String> decodeExtras(
+ com.google.android.vending.licensing.ResponseData rawData) {
+ Map<String, String> results = new HashMap<String, String>();
+ if (rawData == null) {
+ return results;
+ }
+
+ try {
+ URI rawExtras = new URI("?" + rawData.extra);
+ URIQueryDecoder.DecodeQuery(rawExtras, results);
+ } catch (URISyntaxException e) {
+ Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
+ }
+ return results;
+ }
- try {
- URI rawExtras = new URI("?" + rawData.extra);
- URIQueryDecoder.DecodeQuery(rawExtras, results);
- } catch (URISyntaxException e) {
- Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
- }
- return results;
- }
}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ValidationException.java b/platform/android/java/lib/src/com/google/android/vending/licensing/ValidationException.java
index 79b70e6804..ee4df47c68 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/ValidationException.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/ValidationException.java
@@ -21,13 +21,13 @@ package com.google.android.vending.licensing;
* {@link Obfuscator}.}
*/
public class ValidationException extends Exception {
- public ValidationException() {
- super();
- }
+ public ValidationException() {
+ super();
+ }
- public ValidationException(String s) {
- super(s);
- }
+ public ValidationException(String s) {
+ super(s);
+ }
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
}
diff --git a/platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64.java b/platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64.java
new file mode 100644
index 0000000000..79efca9621
--- /dev/null
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64.java
@@ -0,0 +1,578 @@
+// Portions copyright 2002, Google, Inc.
+//
+// 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.
+
+package com.google.android.vending.licensing.util;
+
+// This code was converted from code at http://iharder.sourceforge.net/base64/
+// Lots of extraneous features were removed.
+/* The original code said:
+ * <p>
+ * I am placing this code in the Public Domain. Do with it as you will.
+ * This software comes with no guarantees or warranties but with
+ * plenty of well-wishing instead!
+ * Please visit
+ * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
+ * periodically to check for updates or to contribute improvements.
+ * </p>
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.3
+ */
+
+// -- GODOT start --
+import org.godotengine.godot.BuildConfig;
+// -- GODOT end --
+
+/**
+ * Base64 converter class. This code is not a full-blown MIME encoder;
+ * it simply converts binary data to base64 data and back.
+ *
+ * <p>Note {@link CharBase64} is a GWT-compatible implementation of this
+ * class.
+ */
+public class Base64 {
+ /** Specify encoding (value is {@code true}). */
+ public final static boolean ENCODE = true;
+
+ /** Specify decoding (value is {@code false}). */
+ public final static boolean DECODE = false;
+
+ /** The equals sign (=) as a byte. */
+ private final static byte EQUALS_SIGN = (byte) '=';
+
+ /** The new line character (\n) as a byte. */
+ private final static byte NEW_LINE = (byte) '\n';
+
+ /**
+ * The 64 valid Base64 values.
+ */
+ private final static byte[] ALPHABET =
+ {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
+ (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
+ (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
+ (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
+ (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
+ (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
+ (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
+ (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
+ (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
+ (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
+ (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
+ (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
+ (byte) '9', (byte) '+', (byte) '/'};
+
+ /**
+ * The 64 valid web safe Base64 values.
+ */
+ private final static byte[] WEBSAFE_ALPHABET =
+ {(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
+ (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
+ (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
+ (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
+ (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
+ (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
+ (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
+ (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
+ (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
+ (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
+ (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
+ (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
+ (byte) '9', (byte) '-', (byte) '_'};
+
+ /**
+ * Translates a Base64 value to either its 6-bit reconstruction value
+ * or a negative number indicating some other meaning.
+ **/
+ private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
+ -5, -5, // Whitespace: Tab and Linefeed
+ -9, -9, // Decimal 11 - 12
+ -5, // Whitespace: Carriage Return
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
+ -9, -9, -9, -9, -9, // Decimal 27 - 31
+ -5, // Whitespace: Space
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
+ 62, // Plus sign at decimal 43
+ -9, -9, -9, // Decimal 44 - 46
+ 63, // Slash at decimal 47
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
+ -9, -9, -9, // Decimal 58 - 60
+ -1, // Equals sign at decimal 61
+ -9, -9, -9, // Decimal 62 - 64
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
+ -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
+ -9, -9, -9, -9, -9 // Decimal 123 - 127
+ /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
+ };
+
+ /** The web safe decodabet */
+ private final static byte[] WEBSAFE_DECODABET =
+ {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
+ -5, -5, // Whitespace: Tab and Linefeed
+ -9, -9, // Decimal 11 - 12
+ -5, // Whitespace: Carriage Return
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
+ -9, -9, -9, -9, -9, // Decimal 27 - 31
+ -5, // Whitespace: Space
+ -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
+ 62, // Dash '-' sign at decimal 45
+ -9, -9, // Decimal 46-47
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
+ -9, -9, -9, // Decimal 58 - 60
+ -1, // Equals sign at decimal 61
+ -9, -9, -9, // Decimal 62 - 64
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
+ -9, -9, -9, -9, // Decimal 91-94
+ 63, // Underscore '_' at decimal 95
+ -9, // Decimal 96
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
+ -9, -9, -9, -9, -9 // Decimal 123 - 127
+ /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
+ -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
+ };
+
+ // Indicates white space in encoding
+ private final static byte WHITE_SPACE_ENC = -5;
+ // Indicates equals sign in encoding
+ private final static byte EQUALS_SIGN_ENC = -1;
+
+ /** Defeats instantiation. */
+ private Base64() {
+ }
+
+ /* ******** E N C O D I N G M E T H O D S ******** */
+
+ /**
+ * Encodes up to three bytes of the array <var>source</var>
+ * and writes the resulting four Base64 bytes to <var>destination</var>.
+ * The source and destination arrays can be manipulated
+ * anywhere along their length by specifying
+ * <var>srcOffset</var> and <var>destOffset</var>.
+ * This method does not check to make sure your arrays
+ * are large enough to accommodate <var>srcOffset</var> + 3 for
+ * the <var>source</var> array or <var>destOffset</var> + 4 for
+ * the <var>destination</var> array.
+ * The actual number of significant bytes in your array is
+ * given by <var>numSigBytes</var>.
+ *
+ * @param source the array to convert
+ * @param srcOffset the index where conversion begins
+ * @param numSigBytes the number of significant bytes in your array
+ * @param destination the array to hold the conversion
+ * @param destOffset the index where output will be put
+ * @param alphabet is the encoding alphabet
+ * @return the <var>destination</var> array
+ * @since 1.3
+ */
+ private static byte[] encode3to4(byte[] source, int srcOffset,
+ int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
+ // 1 2 3
+ // 01234567890123456789012345678901 Bit position
+ // --------000000001111111122222222 Array position from threeBytes
+ // --------| || || || | Six bit groups to index alphabet
+ // >>18 >>12 >> 6 >> 0 Right shift necessary
+ // 0x3f 0x3f 0x3f Additional AND
+
+ // Create buffer with zero-padding if there are only one or two
+ // significant bytes passed in the array.
+ // We have to shift left 24 in order to flush out the 1's that appear
+ // when Java treats a value as negative that is cast from a byte to an int.
+ int inBuff =
+ (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
+ | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
+ | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
+
+ switch (numSigBytes) {
+ case 3:
+ destination[destOffset] = alphabet[(inBuff >>> 18)];
+ destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
+ destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
+ destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
+ return destination;
+ case 2:
+ destination[destOffset] = alphabet[(inBuff >>> 18)];
+ destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
+ destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
+ destination[destOffset + 3] = EQUALS_SIGN;
+ return destination;
+ case 1:
+ destination[destOffset] = alphabet[(inBuff >>> 18)];
+ destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
+ destination[destOffset + 2] = EQUALS_SIGN;
+ destination[destOffset + 3] = EQUALS_SIGN;
+ return destination;
+ default:
+ return destination;
+ } // end switch
+ } // end encode3to4
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ * Equivalent to calling
+ * {@code encodeBytes(source, 0, source.length)}
+ *
+ * @param source The data to convert
+ * @since 1.4
+ */
+ public static String encode(byte[] source) {
+ return encode(source, 0, source.length, ALPHABET, true);
+ }
+
+ /**
+ * Encodes a byte array into web safe Base64 notation.
+ *
+ * @param source The data to convert
+ * @param doPadding is {@code true} to pad result with '=' chars
+ * if it does not fall on 3 byte boundaries
+ */
+ public static String encodeWebSafe(byte[] source, boolean doPadding) {
+ return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
+ }
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ *
+ * @param source The data to convert
+ * @param off Offset in array where conversion should begin
+ * @param len Length of data to convert
+ * @param alphabet is the encoding alphabet
+ * @param doPadding is {@code true} to pad result with '=' chars
+ * if it does not fall on 3 byte boundaries
+ * @since 1.4
+ */
+ public static String encode(byte[] source, int off, int len, byte[] alphabet,
+ boolean doPadding) {
+ byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
+ int outLen = outBuff.length;
+
+ // If doPadding is false, set length to truncate '='
+ // padding characters
+ while (doPadding == false && outLen > 0) {
+ if (outBuff[outLen - 1] != '=') {
+ break;
+ }
+ outLen -= 1;
+ }
+
+ return new String(outBuff, 0, outLen);
+ }
+
+ /**
+ * Encodes a byte array into Base64 notation.
+ *
+ * @param source The data to convert
+ * @param off Offset in array where conversion should begin
+ * @param len Length of data to convert
+ * @param alphabet is the encoding alphabet
+ * @param maxLineLength maximum length of one line.
+ * @return the BASE64-encoded byte array
+ */
+ public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
+ int maxLineLength) {
+ int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
+ int len43 = lenDiv3 * 4;
+ byte[] outBuff = new byte[len43 // Main 4:3
+ + (len43 / maxLineLength)]; // New lines
+
+ int d = 0;
+ int e = 0;
+ int len2 = len - 2;
+ int lineLength = 0;
+ for (; d < len2; d += 3, e += 4) {
+
+ // The following block of code is the same as
+ // encode3to4( source, d + off, 3, outBuff, e, alphabet );
+ // but inlined for faster encoding (~20% improvement)
+ int inBuff =
+ ((source[d + off] << 24) >>> 8)
+ | ((source[d + 1 + off] << 24) >>> 16)
+ | ((source[d + 2 + off] << 24) >>> 24);
+ outBuff[e] = alphabet[(inBuff >>> 18)];
+ outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
+ outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
+ outBuff[e + 3] = alphabet[(inBuff) & 0x3f];
+
+ lineLength += 4;
+ if (lineLength == maxLineLength) {
+ outBuff[e + 4] = NEW_LINE;
+ e++;
+ lineLength = 0;
+ } // end if: end of line
+ } // end for: each piece of array
+
+ if (d < len) {
+ encode3to4(source, d + off, len - d, outBuff, e, alphabet);
+
+ lineLength += 4;
+ if (lineLength == maxLineLength) {
+ // Add a last newline
+ outBuff[e + 4] = NEW_LINE;
+ e++;
+ }
+ e += 4;
+ }
+
+ // -- GODOT start --
+ //assert (e == outBuff.length);
+ if (BuildConfig.DEBUG && e != outBuff.length)
+ throw new RuntimeException();
+ // -- GODOT end --
+ return outBuff;
+ }
+
+
+ /* ******** D E C O D I N G M E T H O D S ******** */
+
+
+ /**
+ * Decodes four bytes from array <var>source</var>
+ * and writes the resulting bytes (up to three of them)
+ * to <var>destination</var>.
+ * The source and destination arrays can be manipulated
+ * anywhere along their length by specifying
+ * <var>srcOffset</var> and <var>destOffset</var>.
+ * This method does not check to make sure your arrays
+ * are large enough to accommodate <var>srcOffset</var> + 4 for
+ * the <var>source</var> array or <var>destOffset</var> + 3 for
+ * the <var>destination</var> array.
+ * This method returns the actual number of bytes that
+ * were converted from the Base64 encoding.
+ *
+ *
+ * @param source the array to convert
+ * @param srcOffset the index where conversion begins
+ * @param destination the array to hold the conversion
+ * @param destOffset the index where output will be put
+ * @param decodabet the decodabet for decoding Base64 content
+ * @return the number of decoded bytes converted
+ * @since 1.3
+ */
+ private static int decode4to3(byte[] source, int srcOffset,
+ byte[] destination, int destOffset, byte[] decodabet) {
+ // Example: Dk==
+ if (source[srcOffset + 2] == EQUALS_SIGN) {
+ int outBuff =
+ ((decodabet[source[srcOffset]] << 24) >>> 6)
+ | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
+
+ destination[destOffset] = (byte) (outBuff >>> 16);
+ return 1;
+ } else if (source[srcOffset + 3] == EQUALS_SIGN) {
+ // Example: DkL=
+ int outBuff =
+ ((decodabet[source[srcOffset]] << 24) >>> 6)
+ | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
+ | ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
+
+ destination[destOffset] = (byte) (outBuff >>> 16);
+ destination[destOffset + 1] = (byte) (outBuff >>> 8);
+ return 2;
+ } else {
+ // Example: DkLE
+ int outBuff =
+ ((decodabet[source[srcOffset]] << 24) >>> 6)
+ | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
+ | ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
+ | ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
+
+ destination[destOffset] = (byte) (outBuff >> 16);
+ destination[destOffset + 1] = (byte) (outBuff >> 8);
+ destination[destOffset + 2] = (byte) (outBuff);
+ return 3;
+ }
+ } // end decodeToBytes
+
+
+ /**
+ * Decodes data from Base64 notation.
+ *
+ * @param s the string to decode (decoded in default encoding)
+ * @return the decoded data
+ * @since 1.4
+ */
+ public static byte[] decode(String s) throws Base64DecoderException {
+ byte[] bytes = s.getBytes();
+ return decode(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Decodes data from web safe Base64 notation.
+ * Web safe encoding uses '-' instead of '+', '_' instead of '/'
+ *
+ * @param s the string to decode (decoded in default encoding)
+ * @return the decoded data
+ */
+ public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
+ byte[] bytes = s.getBytes();
+ return decodeWebSafe(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Decodes Base64 content in byte array format and returns
+ * the decoded byte array.
+ *
+ * @param source The Base64 encoded data
+ * @return decoded data
+ * @since 1.3
+ * @throws Base64DecoderException
+ */
+ public static byte[] decode(byte[] source) throws Base64DecoderException {
+ return decode(source, 0, source.length);
+ }
+
+ /**
+ * Decodes web safe Base64 content in byte array format and returns
+ * the decoded data.
+ * Web safe encoding uses '-' instead of '+', '_' instead of '/'
+ *
+ * @param source the string to decode (decoded in default encoding)
+ * @return the decoded data
+ */
+ public static byte[] decodeWebSafe(byte[] source)
+ throws Base64DecoderException {
+ return decodeWebSafe(source, 0, source.length);
+ }
+
+ /**
+ * Decodes Base64 content in byte array format and returns
+ * the decoded byte array.
+ *
+ * @param source The Base64 encoded data
+ * @param off The offset of where to begin decoding
+ * @param len The length of characters to decode
+ * @return decoded data
+ * @since 1.3
+ * @throws Base64DecoderException
+ */
+ public static byte[] decode(byte[] source, int off, int len)
+ throws Base64DecoderException {
+ return decode(source, off, len, DECODABET);
+ }
+
+ /**
+ * Decodes web safe Base64 content in byte array format and returns
+ * the decoded byte array.
+ * Web safe encoding uses '-' instead of '+', '_' instead of '/'
+ *
+ * @param source The Base64 encoded data
+ * @param off The offset of where to begin decoding
+ * @param len The length of characters to decode
+ * @return decoded data
+ */
+ public static byte[] decodeWebSafe(byte[] source, int off, int len)
+ throws Base64DecoderException {
+ return decode(source, off, len, WEBSAFE_DECODABET);
+ }
+
+ /**
+ * Decodes Base64 content using the supplied decodabet and returns
+ * the decoded byte array.
+ *
+ * @param source The Base64 encoded data
+ * @param off The offset of where to begin decoding
+ * @param len The length of characters to decode
+ * @param decodabet the decodabet for decoding Base64 content
+ * @return decoded data
+ */
+ public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
+ throws Base64DecoderException {
+ int len34 = len * 3 / 4;
+ byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
+ int outBuffPosn = 0;
+
+ byte[] b4 = new byte[4];
+ int b4Posn = 0;
+ int i = 0;
+ byte sbiCrop = 0;
+ byte sbiDecode = 0;
+ for (i = 0; i < len; i++) {
+ sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
+ sbiDecode = decodabet[sbiCrop];
+
+ if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
+ if (sbiDecode >= EQUALS_SIGN_ENC) {
+ // An equals sign (for padding) must not occur at position 0 or 1
+ // and must be the last byte[s] in the encoded value
+ if (sbiCrop == EQUALS_SIGN) {
+ int bytesLeft = len - i;
+ byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
+ if (b4Posn == 0 || b4Posn == 1) {
+ throw new Base64DecoderException(
+ "invalid padding byte '=' at byte offset " + i);
+ } else if ((b4Posn == 3 && bytesLeft > 2)
+ || (b4Posn == 4 && bytesLeft > 1)) {
+ throw new Base64DecoderException(
+ "padding byte '=' falsely signals end of encoded value "
+ + "at offset " + i);
+ } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
+ throw new Base64DecoderException(
+ "encoded value has invalid trailing byte");
+ }
+ break;
+ }
+
+ b4[b4Posn++] = sbiCrop;
+ if (b4Posn == 4) {
+ outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
+ b4Posn = 0;
+ }
+ }
+ } else {
+ throw new Base64DecoderException("Bad Base64 input character at " + i
+ + ": " + source[i + off] + "(decimal)");
+ }
+ }
+
+ // Because web safe encoding allows non padding base64 encodes, we
+ // need to pad the rest of the b4 buffer with equal signs when
+ // b4Posn != 0. There can be at most 2 equal signs at the end of
+ // four characters, so the b4 buffer must have two or three
+ // characters. This also catches the case where the input is
+ // padded with EQUALS_SIGN
+ if (b4Posn != 0) {
+ if (b4Posn == 1) {
+ throw new Base64DecoderException("single trailing character at offset "
+ + (len - 1));
+ }
+ b4[b4Posn++] = EQUALS_SIGN;
+ outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
+ }
+
+ byte[] out = new byte[outBuffPosn];
+ System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
+ return out;
+ }
+}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/util/Base64DecoderException.java b/platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64DecoderException.java
index 50724a9b05..1aef1b54b8 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/util/Base64DecoderException.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/util/Base64DecoderException.java
@@ -20,13 +20,13 @@ package com.google.android.vending.licensing.util;
* @author nelson
*/
public class Base64DecoderException extends Exception {
- public Base64DecoderException() {
- super();
- }
+ public Base64DecoderException() {
+ super();
+ }
- public Base64DecoderException(String s) {
- super(s);
- }
+ public Base64DecoderException(String s) {
+ super(s);
+ }
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 1L;
}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/util/URIQueryDecoder.java b/platform/android/java/lib/src/com/google/android/vending/licensing/util/URIQueryDecoder.java
index 4f908b472c..5155bf5ac3 100644
--- a/platform/android/java/src/com/google/android/vending/licensing/util/URIQueryDecoder.java
+++ b/platform/android/java/lib/src/com/google/android/vending/licensing/util/URIQueryDecoder.java
@@ -25,36 +25,36 @@ import java.util.Map;
import java.util.Scanner;
public class URIQueryDecoder {
- private static final String TAG = "URIQueryDecoder";
+ private static final String TAG = "URIQueryDecoder";
- /**
+ /**
* Decodes the query portion of the passed-in URI.
*
* @param encodedURI the URI containing the query to decode
* @param results a map containing all query parameters. Query parameters that do not have a
* value will map to a null string
*/
- static public void DecodeQuery(URI encodedURI, Map<String, String> results) {
- Scanner scanner = new Scanner(encodedURI.getRawQuery());
- scanner.useDelimiter("&");
- try {
- while (scanner.hasNext()) {
- String param = scanner.next();
- String[] valuePair = param.split("=");
- String name, value;
- if (valuePair.length == 1) {
- value = null;
- } else if (valuePair.length == 2) {
- value = URLDecoder.decode(valuePair[1], "UTF-8");
- } else {
- throw new IllegalArgumentException("query parameter invalid");
- }
- name = URLDecoder.decode(valuePair[0], "UTF-8");
- results.put(name, value);
- }
- } catch (UnsupportedEncodingException e) {
- // This should never happen.
- Log.e(TAG, "UTF-8 Not Recognized as a charset. Device configuration Error.");
- }
- }
+ static public void DecodeQuery(URI encodedURI, Map<String, String> results) {
+ Scanner scanner = new Scanner(encodedURI.getRawQuery());
+ scanner.useDelimiter("&");
+ try {
+ while (scanner.hasNext()) {
+ String param = scanner.next();
+ String[] valuePair = param.split("=");
+ String name, value;
+ if (valuePair.length == 1) {
+ value = null;
+ } else if (valuePair.length == 2) {
+ value = URLDecoder.decode(valuePair[1], "UTF-8");
+ } else {
+ throw new IllegalArgumentException("query parameter invalid");
+ }
+ name = URLDecoder.decode(valuePair[0], "UTF-8");
+ results.put(name, value);
+ }
+ } catch (UnsupportedEncodingException e) {
+ // This should never happen.
+ Log.e(TAG, "UTF-8 Not Recognized as a charset. Device configuration Error.");
+ }
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
index 588d9ae646..588d9ae646 100644
--- a/platform/android/java/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 6e1841fa8b..739aa285bf 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -31,6 +31,7 @@
package org.godotengine.godot;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
@@ -56,7 +57,10 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Messenger;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
import android.provider.Settings.Secure;
+import android.support.annotation.Keep;
import android.support.v4.content.ContextCompat;
import android.view.Display;
import android.view.KeyEvent;
@@ -93,13 +97,13 @@ import org.godotengine.godot.input.GodotEditText;
import org.godotengine.godot.payments.PaymentsManager;
import org.godotengine.godot.xr.XRMode;
-public class Godot extends Activity implements SensorEventListener, IDownloaderClient {
+public abstract class Godot extends Activity implements SensorEventListener, IDownloaderClient {
static final int MAX_SINGLETONS = 64;
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
static final int REQUEST_CAMERA_PERMISSION = 2;
+ static final int REQUEST_VIBRATE_PERMISSION = 3;
private IStub mDownloaderClientStub;
- private IDownloaderService mRemoteService;
private TextView mStatusText;
private TextView mProgressFraction;
private TextView mProgressPercent;
@@ -142,8 +146,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private void setButtonPausedState(boolean paused) {
mStatePaused = paused;
- int stringResourceID = paused ? com.godot.game.R.string.text_button_resume :
- com.godot.game.R.string.text_button_pause;
+ int stringResourceID = paused ? R.string.text_button_resume :
+ R.string.text_button_pause;
mPauseButton.setText(stringResourceID);
}
@@ -222,15 +226,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private Sensor mMagnetometer;
private Sensor mGyroscope;
- public FrameLayout layout;
-
public static GodotIO io;
- public static void setWindowTitle(String title) {
- //setTitle(title);
- }
-
- static SingletonBase singletons[] = new SingletonBase[MAX_SINGLETONS];
+ static SingletonBase[] singletons = new SingletonBase[MAX_SINGLETONS];
static int singleton_count = 0;
public interface ResultCallback {
@@ -266,13 +264,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
};
- public void onVideoInit() {
+ /**
+ * Used by the native code (java_godot_lib_jni.cpp) to complete initialization of the GLSurfaceView view and renderer.
+ */
+ @Keep
+ private void onVideoInit() {
boolean use_gl3 = getGLESVersionCode() >= 0x00030000;
- //mView = new GodotView(getApplication(),io,use_gl3);
- //setContentView(mView);
-
- layout = new FrameLayout(this);
+ final FrameLayout layout = new FrameLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setContentView(layout);
@@ -324,6 +323,26 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
});
}
+ /**
+ * Used by the native code (java_godot_wrapper.h) to vibrate the device.
+ * @param durationMs
+ */
+ @SuppressLint("MissingPermission")
+ @Keep
+ private void vibrate(int durationMs) {
+ if (requestPermission("VIBRATE")) {
+ Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+ if (v != null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE));
+ } else {
+ //deprecated in API 26
+ v.vibrate(durationMs);
+ }
+ }
+ }
+ }
+
public void restart() {
// HACK:
//
@@ -338,7 +357,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
//
Bundle args = new Bundle();
args.putParcelable("intent", mCurrentIntent);
- startInstrumentation(new ComponentName(Godot.this, GodotInstrumentation.class), null, args);
+ startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args);
}
public void alert(final String message, final String title) {
@@ -405,6 +424,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
/**
* Used by the native code (java_godot_wrapper.h) to check whether the activity is resumed or paused.
*/
+ @Keep
private boolean isActivityResumed() {
return activityResumed;
}
@@ -412,10 +432,20 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
/**
* Used by the native code (java_godot_wrapper.h) to access the Android surface.
*/
+ @Keep
private Surface getSurface() {
return mView.getHolder().getSurface();
}
+ /**
+ * Used by the native code (java_godot_wrapper.h) to access the input fallback mapping.
+ * @return The input fallback mapping for the current XR mode.
+ */
+ @Keep
+ private String getInputFallbackMapping() {
+ return xrMode.inputFallbackMapping;
+ }
+
String expansion_pack_path;
private void initializeGodot() {
@@ -463,8 +493,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override
public void onServiceConnected(Messenger m) {
- mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
- mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
+ IDownloaderService remoteService = DownloaderServiceMarshaller.CreateProxy(m);
+ remoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
@Override
@@ -472,7 +502,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
super.onCreate(icicle);
Window window = getWindow();
- //window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
@@ -585,20 +614,19 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
GodotDownloaderService.class);
- setContentView(com.godot.game.R.layout.downloading_expansion);
- mPB = (ProgressBar)findViewById(com.godot.game.R.id.progressBar);
- mStatusText = (TextView)findViewById(com.godot.game.R.id.statusText);
- mProgressFraction = (TextView)findViewById(com.godot.game.R.id.progressAsFraction);
- mProgressPercent = (TextView)findViewById(com.godot.game.R.id.progressAsPercentage);
- mAverageSpeed = (TextView)findViewById(com.godot.game.R.id.progressAverageSpeed);
- mTimeRemaining = (TextView)findViewById(com.godot.game.R.id.progressTimeRemaining);
- mDashboard = findViewById(com.godot.game.R.id.downloaderDashboard);
- mCellMessage = findViewById(com.godot.game.R.id.approveCellular);
- mPauseButton = (Button)findViewById(com.godot.game.R.id.pauseButton);
- mWiFiSettingsButton = (Button)findViewById(com.godot.game.R.id.wifiSettingsButton);
+ setContentView(R.layout.downloading_expansion);
+ mPB = (ProgressBar)findViewById(R.id.progressBar);
+ mStatusText = (TextView)findViewById(R.id.statusText);
+ mProgressFraction = (TextView)findViewById(R.id.progressAsFraction);
+ mProgressPercent = (TextView)findViewById(R.id.progressAsPercentage);
+ mAverageSpeed = (TextView)findViewById(R.id.progressAverageSpeed);
+ mTimeRemaining = (TextView)findViewById(R.id.progressTimeRemaining);
+ mDashboard = findViewById(R.id.downloaderDashboard);
+ mCellMessage = findViewById(R.id.approveCellular);
+ mPauseButton = (Button)findViewById(R.id.pauseButton);
+ mWiFiSettingsButton = (Button)findViewById(R.id.wifiSettingsButton);
return;
- } else {
}
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
@@ -610,8 +638,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mCurrentIntent = getIntent();
initializeGodot();
-
- //instanceSingleton( new GodotFacebook(this) );
}
@Override
@@ -625,6 +651,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
GodotLib.ondestroy(this);
super.onDestroy();
+
+ // TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
+ // native Godot components that is started in Godot#onVideoInit.
+ forceQuit();
}
@Override
@@ -639,12 +669,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return;
}
mView.onPause();
- mView.queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.focusout();
- }
- });
+
mSensorManager.unregisterListener(this);
for (int i = 0; i < singleton_count; i++) {
@@ -673,6 +698,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override
protected void onResume() {
super.onResume();
+ activityResumed = true;
if (!godot_initialized) {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
@@ -681,12 +707,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
mView.onResume();
- mView.queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.focusin();
- }
- });
+
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
@@ -707,8 +728,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
singletons[i].onMainResume();
}
-
- activityResumed = true;
}
public void UiChangeListener() {
@@ -816,8 +835,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
}
- public void forceQuit() {
-
+ private void forceQuit() {
System.exit(0);
}
@@ -864,7 +882,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
}
- //@Override public boolean dispatchTouchEvent (MotionEvent event) {
public boolean gotTouchEvent(final MotionEvent event) {
final int evcount = event.getPointerCount();
@@ -935,8 +952,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
;
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
- final Activity me = this;
- queueEvent(new Runnable() {
+ mView.queueEvent(new Runnable() {
// This method will be called on the rendering thread:
public void run() {
for (int i = 0, n = cc.length; i < n; i++) {
@@ -952,20 +968,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return true;
}
- private void queueEvent(Runnable runnable) {
- // TODO Auto-generated method stub
- }
-
public PaymentsManager getPaymentsManager() {
return mPaymentsManager;
}
- /*
- public void setPaymentsManager(PaymentsManager mPaymentsManager) {
- this.mPaymentsManager = mPaymentsManager;
- }
- */
-
public boolean requestPermission(String p_name) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already
@@ -985,6 +991,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return false;
}
}
+
+ if (p_name.equals("VIBRATE")) {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION);
+ return false;
+ }
+ }
return true;
}
@@ -1003,7 +1016,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
switch (newState) {
case IDownloaderClient.STATE_IDLE:
// STATE_IDLE means the service is listening, so it's
- // safe to start making calls via mRemoteService.
+ // safe to start making remote service calls.
paused = false;
indeterminate = true;
break;
@@ -1070,9 +1083,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override
public void onDownloadProgress(DownloadProgressInfo progress) {
- mAverageSpeed.setText(getString(com.godot.game.R.string.kilobytes_per_second,
+ mAverageSpeed.setText(getString(R.string.kilobytes_per_second,
Helpers.getSpeedString(progress.mCurrentSpeed)));
- mTimeRemaining.setText(getString(com.godot.game.R.string.time_remaining,
+ mTimeRemaining.setText(getString(R.string.time_remaining,
Helpers.getTimeRemaining(progress.mTimeRemaining)));
mPB.setMax((int)(progress.mOverallTotal >> 8));
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index e7e2a3f808..e7e2a3f808 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
index 8e10710c9f..8e10710c9f 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
diff --git a/platform/android/java/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 98174157ec..04566cf62c 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -29,26 +29,18 @@
/*************************************************************************/
package org.godotengine.godot;
-import android.app.*;
import android.content.*;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
-import android.graphics.*;
-import android.hardware.*;
import android.media.*;
import android.net.Uri;
import android.os.*;
-import android.text.*;
-import android.text.method.*;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
-import android.view.*;
-import android.view.inputmethod.InputMethodManager;
import java.io.IOException;
import java.io.InputStream;
-import java.util.HashMap;
import java.util.Locale;
import org.godotengine.godot.input.*;
//android.os.Build
diff --git a/platform/android/java/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
index 0466f380e8..0466f380e8 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotInstrumentation.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
new file mode 100644
index 0000000000..067fa6f4b9
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -0,0 +1,226 @@
+/*************************************************************************/
+/* GodotLib.java */
+/*************************************************************************/
+/* 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. */
+/*************************************************************************/
+
+package org.godotengine.godot;
+
+import android.app.Activity;
+import android.hardware.SensorEvent;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Wrapper for native library
+ */
+public class GodotLib {
+
+ public static GodotIO io;
+
+ static {
+ System.loadLibrary("godot_android");
+ }
+
+ /**
+ * Invoked on the main thread to initialize Godot native layer.
+ */
+ public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
+
+ /**
+ * Invoked on the main thread to clean up Godot native layer.
+ * @see Activity#onDestroy()
+ */
+ public static native void ondestroy(Godot p_instance);
+
+ /**
+ * Invoked on the GL thread to complete setup for the Godot native layer logic.
+ * @param p_cmdline Command line arguments used to configure Godot native layer components.
+ */
+ public static native void setup(String[] p_cmdline);
+
+ /**
+ * Invoked on the GL thread when the underlying Android surface has changed size.
+ * @param width
+ * @param height
+ * @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(GL10, int, int)
+ */
+ public static native void resize(int width, int height);
+
+ /**
+ * Invoked on the GL thread when the underlying Android surface is created or recreated.
+ * @param p_32_bits
+ * @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
+ */
+ public static native void newcontext(boolean p_32_bits);
+
+ /**
+ * Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
+ */
+ public static native void back();
+
+ /**
+ * Invoked on the GL thread to draw the current frame.
+ * @see android.opengl.GLSurfaceView.Renderer#onDrawFrame(GL10)
+ */
+ public static native void step();
+
+ /**
+ * Forward touch events from the main thread to the GL thread.
+ */
+ public static native void touch(int what, int pointer, int howmany, int[] arr);
+
+ /**
+ * Forward accelerometer sensor events from the main thread to the GL thread.
+ * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
+ */
+ public static native void accelerometer(float x, float y, float z);
+
+ /**
+ * Forward gravity sensor events from the main thread to the GL thread.
+ * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
+ */
+ public static native void gravity(float x, float y, float z);
+
+ /**
+ * Forward magnetometer sensor events from the main thread to the GL thread.
+ * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
+ */
+ public static native void magnetometer(float x, float y, float z);
+
+ /**
+ * Forward gyroscope sensor events from the main thread to the GL thread.
+ * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
+ */
+ public static native void gyroscope(float x, float y, float z);
+
+ /**
+ * Forward regular key events from the main thread to the GL thread.
+ */
+ public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
+
+ /**
+ * Forward game device's key events from the main thread to the GL thread.
+ */
+ public static native void joybutton(int p_device, int p_but, boolean p_pressed);
+
+ /**
+ * Forward joystick devices axis motion events from the main thread to the GL thread.
+ */
+ public static native void joyaxis(int p_device, int p_axis, float p_value);
+
+ /**
+ * Forward joystick devices hat motion events from the main thread to the GL thread.
+ */
+ public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
+
+ /**
+ * Fires when a joystick device is added or removed.
+ */
+ public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
+
+ /**
+ * Invoked when the Android activity resumes.
+ * @see Activity#onResume()
+ */
+ public static native void focusin();
+
+ /**
+ * Invoked when the Android activity pauses.
+ * @see Activity#onPause()
+ */
+ public static native void focusout();
+
+ /**
+ * Invoked when the audio thread is started.
+ */
+ public static native void audio();
+
+ /**
+ * Used to setup a {@link org.godotengine.godot.Godot.SingletonBase} instance.
+ * @param p_name Name of the instance.
+ * @param p_object Reference to the singleton instance.
+ */
+ public static native void singleton(String p_name, Object p_object);
+
+ /**
+ * Used to complete registration of the {@link org.godotengine.godot.Godot.SingletonBase} instance's methods.
+ * @param p_sname Name of the instance
+ * @param p_name Name of the method to register
+ * @param p_ret Return type of the registered method
+ * @param p_params Method parameters types
+ */
+ public static native void method(String p_sname, String p_name, String p_ret, String[] p_params);
+
+ /**
+ * Used to access Godot global properties.
+ * @param p_key Property key
+ * @return String value of the property
+ */
+ public static native String getGlobal(String p_key);
+
+ /**
+ * Invoke method |p_method| on the Godot object specified by |p_id|
+ * @param p_id Id of the Godot object to invoke
+ * @param p_method Name of the method to invoke
+ * @param p_params Parameters to use for method invocation
+ */
+ public static native void callobject(int p_id, String p_method, Object[] p_params);
+
+ /**
+ * Invoke method |p_method| on the Godot object specified by |p_id| during idle time.
+ * @param p_id Id of the Godot object to invoke
+ * @param p_method Name of the method to invoke
+ * @param p_params Parameters to use for method invocation
+ */
+ public static native void calldeferred(int p_id, String p_method, Object[] p_params);
+
+ /**
+ * Forward the results from a permission request.
+ * @see Activity#onRequestPermissionsResult(int, String[], int[])
+ * @param p_permission Request permission
+ * @param p_result True if the permission was granted, false otherwise
+ */
+ public static native void requestPermissionResult(String p_permission, boolean p_result);
+
+ /**
+ * Invoked on the GL thread to configure the height of the virtual keyboard.
+ */
+ public static native void setVirtualKeyboardHeight(int p_height);
+
+ /**
+ * Invoked on the GL thread when the {@link GodotRenderer} has been resumed.
+ * @see GodotRenderer#onActivityResumed()
+ */
+ public static native void onRendererResumed();
+
+ /**
+ * Invoked on the GL thread when the {@link GodotRenderer} has been paused.
+ * @see GodotRenderer#onActivityPaused()
+ */
+ public static native void onRendererPaused();
+}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java
index 1432cd3a67..1432cd3a67 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java
diff --git a/platform/android/java/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index 8e3775c2a9..56ba88656e 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -40,7 +40,14 @@ import org.godotengine.godot.utils.GLUtils;
*/
class GodotRenderer implements GLSurfaceView.Renderer {
+ private boolean activityJustResumed = false;
+
public void onDrawFrame(GL10 gl) {
+ if (activityJustResumed) {
+ GodotLib.onRendererResumed();
+ activityJustResumed = false;
+ }
+
GodotLib.step();
for (int i = 0; i < Godot.singleton_count; i++) {
Godot.singletons[i].onGLDrawFrame(gl);
@@ -58,4 +65,14 @@ class GodotRenderer implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GodotLib.newcontext(GLUtils.use_32);
}
+
+ void onActivityResumed() {
+ // We defer invoking GodotLib.onRendererResumed() until the first draw frame call.
+ // This ensures we have a valid GL context and surface when we do so.
+ activityJustResumed = true;
+ }
+
+ void onActivityPaused() {
+ GodotLib.onRendererPaused();
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
index fc3e47e69d..5511e5d782 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
@@ -68,6 +68,7 @@ public class GodotView extends GLSurfaceView {
private final Godot activity;
private final GodotInputHandler inputHandler;
+ private final GodotRenderer godotRenderer;
public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) {
super(activity);
@@ -77,6 +78,7 @@ public class GodotView extends GLSurfaceView {
this.activity = activity;
this.inputHandler = new GodotInputHandler(this);
+ this.godotRenderer = new GodotRenderer();
init(xrMode, false, 16, 0);
}
@@ -161,10 +163,38 @@ public class GodotView extends GLSurfaceView {
}
/* Set the renderer responsible for frame rendering */
- setRenderer(new GodotRenderer());
+ setRenderer(godotRenderer);
}
public void onBackPressed() {
activity.onBackPressed();
}
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ // Resume the renderer
+ godotRenderer.onActivityResumed();
+ GodotLib.focusin();
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.focusout();
+ // Pause the renderer
+ godotRenderer.onActivityPaused();
+ }
+ });
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index 45b739baa0..45b739baa0 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index a443a0ad90..2beca67922 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -96,7 +96,6 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.joybutton(device_id, button, false);
}
});
- return true;
}
} else {
final int chr = event.getUnicodeChar(0);
@@ -108,7 +107,7 @@ public class GodotInputHandler implements InputDeviceListener {
});
};
- return false;
+ return true;
}
public boolean onKeyDown(final int keyCode, KeyEvent event) {
@@ -142,7 +141,6 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.joybutton(device_id, button, true);
}
});
- return true;
}
} else {
final int chr = event.getUnicodeChar(0);
@@ -154,7 +152,7 @@ public class GodotInputHandler implements InputDeviceListener {
});
};
- return false;
+ return true;
}
public boolean onGenericMotionEvent(MotionEvent event) {
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index d6e7ad5b18..9b372c75e3 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -32,7 +32,6 @@ package org.godotengine.godot.input;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
index 4042c42e9d..4042c42e9d 100644
--- a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
index e4bafa7ff9..e4bafa7ff9 100644
--- a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
diff --git a/platform/android/java/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
index ff95bfb0c5..ff95bfb0c5 100644
--- a/platform/android/java/src/org/godotengine/godot/input/Joystick.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java
index f872e7af56..4c1050c948 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java
@@ -33,7 +33,6 @@ package org.godotengine.godot.payments;
import android.content.Context;
import android.os.AsyncTask;
import android.os.RemoteException;
-import android.util.Log;
import com.android.vending.billing.IInAppBillingService;
import java.lang.ref.WeakReference;
diff --git a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java
index 5424ebb49d..1a914967a2 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java
@@ -31,18 +31,7 @@
package org.godotengine.godot.payments;
import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentSender.SendIntentException;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import com.android.vending.billing.IInAppBillingService;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.utils.Crypt;
import org.json.JSONException;
import org.json.JSONObject;
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java
index 8a2facbcfb..8a2facbcfb 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java
index a0dbc432c1..c079c55854 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -43,7 +43,6 @@ import android.util.Log;
import com.android.vending.billing.IInAppBillingService;
import java.util.ArrayList;
import java.util.Arrays;
-import org.godotengine.godot.Godot;
import org.godotengine.godot.GodotPaymentV3;
import org.json.JSONException;
import org.json.JSONObject;
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java
index 650c5178f0..9adc85e521 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java
@@ -32,19 +32,12 @@ package org.godotengine.godot.payments;
import android.app.Activity;
import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import com.android.vending.billing.IInAppBillingService;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.utils.Crypt;
-import org.json.JSONException;
-import org.json.JSONObject;
abstract public class PurchaseTask {
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
index daca6ef5ae..daca6ef5ae 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java
index d32c80e8e0..17a2a197ad 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java
@@ -31,21 +31,10 @@
package org.godotengine.godot.payments;
import android.app.Activity;
-import android.app.PendingIntent;
import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender.SendIntentException;
import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import com.android.vending.billing.IInAppBillingService;
import java.lang.ref.WeakReference;
-import org.godotengine.godot.Godot;
-import org.godotengine.godot.GodotLib;
import org.godotengine.godot.GodotPaymentV3;
-import org.godotengine.godot.utils.Crypt;
import org.godotengine.godot.utils.HttpRequester;
import org.godotengine.godot.utils.RequestParams;
import org.json.JSONException;
diff --git a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
index 4c551d1d21..4c551d1d21 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
diff --git a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
index b61007faa3..b61007faa3 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
diff --git a/platform/android/java/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
index 6c95494f8b..6c95494f8b 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/GLUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
diff --git a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java
index e98f533c23..02ae753b3e 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java
@@ -39,12 +39,9 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.KeyStore;
-import java.util.ArrayList;
import java.util.Date;
-import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
-import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
@@ -58,7 +55,6 @@ import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
diff --git a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java
index b9fe0dd0c9..b9fe0dd0c9 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
index dd5701af7d..5896b23ac3 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
@@ -34,16 +34,18 @@ package org.godotengine.godot.xr;
* Godot available XR modes.
*/
public enum XRMode {
- REGULAR(0, "Regular", "--xr_mode_regular"), // Regular/flatscreen
- OVR(1, "Oculus Mobile VR", "--xr_mode_ovr");
+ REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen
+ OVR(1, "Oculus Mobile VR", "--xr_mode_ovr", "");
final int index;
final String label;
public final String cmdLineArg;
+ public final String inputFallbackMapping;
- XRMode(int index, String label, String cmdLineArg) {
+ XRMode(int index, String label, String cmdLineArg, String inputFallbackMapping) {
this.index = index;
this.label = label;
this.cmdLineArg = cmdLineArg;
+ this.inputFallbackMapping = inputFallbackMapping;
}
}
diff --git a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
index ff836a31ca..ff836a31ca 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
index 5f6da8c672..5f6da8c672 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
index f1e38c35d8..f1e38c35d8 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index 3836967f86..3836967f86 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index 4f1e9a696b..4f1e9a696b 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
diff --git a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
index f5718ef2b3..f5718ef2b3 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
diff --git a/misc/ide/jetbrains/settings.gradle b/platform/android/java/settings.gradle
index 1904ab94e7..f6921c70aa 100644
--- a/misc/ide/jetbrains/settings.gradle
+++ b/platform/android/java/settings.gradle
@@ -1,2 +1,5 @@
// Configure the root project.
rootProject.name = "Godot"
+
+include ':app'
+include ':lib'
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java
deleted file mode 100644
index 9a78a6d3df..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloadProgressInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class contains progress information about the active download(s).
- *
- * When you build the Activity that initiates a download and tracks the
- * progress by implementing the {@link IDownloaderClient} interface, you'll
- * receive a DownloadProgressInfo object in each call to the {@link
- * IDownloaderClient#onDownloadProgress} method. This allows you to update
- * your activity's UI with information about the download progress, such
- * as the progress so far, time remaining and current speed.
- */
-public class DownloadProgressInfo implements Parcelable {
- public long mOverallTotal;
- public long mOverallProgress;
- public long mTimeRemaining; // time remaining
- public float mCurrentSpeed; // speed in KB/S
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel p, int i) {
- p.writeLong(mOverallTotal);
- p.writeLong(mOverallProgress);
- p.writeLong(mTimeRemaining);
- p.writeFloat(mCurrentSpeed);
- }
-
- public DownloadProgressInfo(Parcel p) {
- mOverallTotal = p.readLong();
- mOverallProgress = p.readLong();
- mTimeRemaining = p.readLong();
- mCurrentSpeed = p.readFloat();
- }
-
- public DownloadProgressInfo(long overallTotal, long overallProgress,
- long timeRemaining,
- float currentSpeed) {
- this.mOverallTotal = overallTotal;
- this.mOverallProgress = overallProgress;
- this.mTimeRemaining = timeRemaining;
- this.mCurrentSpeed = currentSpeed;
- }
-
- public static final Creator<DownloadProgressInfo> CREATOR = new Creator<DownloadProgressInfo>() {
- @Override
- public DownloadProgressInfo createFromParcel(Parcel parcel) {
- return new DownloadProgressInfo(parcel);
- }
-
- @Override
- public DownloadProgressInfo[] newArray(int i) {
- return new DownloadProgressInfo[i];
- }
- };
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
deleted file mode 100644
index 146426ef83..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderClientMarshaller.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader;
-
-import com.google.android.vending.expansion.downloader.impl.DownloaderService;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This class binds the service API to your application client. It contains the IDownloaderClient proxy,
- * which is used to call functions in your client as well as the Stub, which is used to call functions
- * in the client implementation of IDownloaderClient.
- *
- * <p>The IPC is implemented using an Android Messenger and a service Binder. The connect method
- * should be called whenever the client wants to bind to the service. It opens up a service connection
- * that ends up calling the onServiceConnected client API that passes the service messenger
- * in. If the client wants to be notified by the service, it is responsible for then passing its
- * messenger to the service in a separate call.
- *
- * <p>Critical methods are {@link #startDownloadServiceIfRequired} and {@link #CreateStub}.
- *
- * <p>When your application first starts, you should first check whether your app's expansion files are
- * already on the device. If not, you should then call {@link #startDownloadServiceIfRequired}, which
- * starts your {@link impl.DownloaderService} to download the expansion files if necessary. The method
- * returns a value indicating whether download is required or not.
- *
- * <p>If a download is required, {@link #startDownloadServiceIfRequired} begins the download through
- * the specified service and you should then call {@link #CreateStub} to instantiate a member {@link
- * IStub} object that you need in order to receive calls through your {@link IDownloaderClient}
- * interface.
- */
-public class DownloaderClientMarshaller {
- public static final int MSG_ONDOWNLOADSTATE_CHANGED = 10;
- public static final int MSG_ONDOWNLOADPROGRESS = 11;
- public static final int MSG_ONSERVICECONNECTED = 12;
-
- public static final String PARAM_NEW_STATE = "newState";
- public static final String PARAM_PROGRESS = "progress";
- public static final String PARAM_MESSENGER = DownloaderService.EXTRA_MESSAGE_HANDLER;
-
- public static final int NO_DOWNLOAD_REQUIRED = DownloaderService.NO_DOWNLOAD_REQUIRED;
- public static final int LVL_CHECK_REQUIRED = DownloaderService.LVL_CHECK_REQUIRED;
- public static final int DOWNLOAD_REQUIRED = DownloaderService.DOWNLOAD_REQUIRED;
-
- private static class Proxy implements IDownloaderClient {
- private Messenger mServiceMessenger;
-
- @Override
- public void onDownloadStateChanged(int newState) {
- Bundle params = new Bundle(1);
- params.putInt(PARAM_NEW_STATE, newState);
- send(MSG_ONDOWNLOADSTATE_CHANGED, params);
- }
-
- @Override
- public void onDownloadProgress(DownloadProgressInfo progress) {
- Bundle params = new Bundle(1);
- params.putParcelable(PARAM_PROGRESS, progress);
- send(MSG_ONDOWNLOADPROGRESS, params);
- }
-
- private void send(int method, Bundle params) {
- Message m = Message.obtain(null, method);
- m.setData(params);
- try {
- mServiceMessenger.send(m);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- public Proxy(Messenger msg) {
- mServiceMessenger = msg;
- }
-
- @Override
- public void onServiceConnected(Messenger m) {
- /**
- * This is never called through the proxy.
- */
- }
- }
-
- private static class Stub implements IStub {
- private IDownloaderClient mItf = null;
- private Class<?> mDownloaderServiceClass;
- private boolean mBound;
- private Messenger mServiceMessenger;
- private Context mContext;
- /**
- * Target we publish for clients to send messages to IncomingHandler.
- */
- private final MessengerHandlerClient mMsgHandler = new MessengerHandlerClient(this);
- final Messenger mMessenger = new Messenger(mMsgHandler);
-
- private static class MessengerHandlerClient extends Handler {
- private final WeakReference<Stub> mDownloader;
- public MessengerHandlerClient(Stub downloader) {
- mDownloader = new WeakReference<>(downloader);
- }
-
- @Override
- public void handleMessage(Message msg) {
- Stub downloader = mDownloader.get();
- if (downloader != null) {
- downloader.handleMessage(msg);
- }
- }
- }
-
- private void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ONDOWNLOADPROGRESS:
- Bundle bun = msg.getData();
- if (null != mContext) {
- bun.setClassLoader(mContext.getClassLoader());
- DownloadProgressInfo dpi = (DownloadProgressInfo)msg.getData()
- .getParcelable(PARAM_PROGRESS);
- mItf.onDownloadProgress(dpi);
- }
- break;
- case MSG_ONDOWNLOADSTATE_CHANGED:
- mItf.onDownloadStateChanged(msg.getData().getInt(PARAM_NEW_STATE));
- break;
- case MSG_ONSERVICECONNECTED:
- mItf.onServiceConnected(
- (Messenger)msg.getData().getParcelable(PARAM_MESSENGER));
- break;
- }
- }
-
- public Stub(IDownloaderClient itf, Class<?> downloaderService) {
- mItf = itf;
- mDownloaderServiceClass = downloaderService;
- }
-
- /**
- * Class for interacting with the main interface of the service.
- */
- private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- // This is called when the connection with the service has been
- // established, giving us the object we can use to
- // interact with the service. We are communicating with the
- // service using a Messenger, so here we get a client-side
- // representation of that from the raw IBinder object.
- mServiceMessenger = new Messenger(service);
- mItf.onServiceConnected(
- mServiceMessenger);
- }
-
- public void onServiceDisconnected(ComponentName className) {
- // This is called when the connection with the service has been
- // unexpectedly disconnected -- that is, its process crashed.
- mServiceMessenger = null;
- }
- };
-
- @Override
- public void connect(Context c) {
- mContext = c;
- Intent bindIntent = new Intent(c, mDownloaderServiceClass);
- bindIntent.putExtra(PARAM_MESSENGER, mMessenger);
- if (!c.bindService(bindIntent, mConnection, Context.BIND_DEBUG_UNBIND)) {
- if (Constants.LOGVV) {
- Log.d(Constants.TAG, "Service Unbound");
- }
- } else {
- mBound = true;
- }
- }
-
- @Override
- public void disconnect(Context c) {
- if (mBound) {
- c.unbindService(mConnection);
- mBound = false;
- }
- mContext = null;
- }
-
- @Override
- public Messenger getMessenger() {
- return mMessenger;
- }
- }
-
- /**
- * Returns a proxy that will marshal calls to IDownloaderClient methods
- *
- * @param msg
- * @return
- */
- public static IDownloaderClient CreateProxy(Messenger msg) {
- return new Proxy(msg);
- }
-
- /**
- * Returns a stub object that, when connected, will listen for marshaled
- * {@link IDownloaderClient} methods and translate them into calls to the supplied
- * interface.
- *
- * @param itf An implementation of IDownloaderClient that will be called
- * when remote method calls are unmarshaled.
- * @param downloaderService The class for your implementation of {@link
- * impl.DownloaderService}.
- * @return The {@link IStub} that allows you to connect to the service such that
- * your {@link IDownloaderClient} receives status updates.
- */
- public static IStub CreateStub(IDownloaderClient itf, Class<?> downloaderService) {
- return new Stub(itf, downloaderService);
- }
-
- /**
- * Starts the download if necessary. This function starts a flow that does `
- * many things. 1) Checks to see if the APK version has been checked and
- * the metadata database updated 2) If the APK version does not match,
- * checks the new LVL status to see if a new download is required 3) If the
- * APK version does match, then checks to see if the download(s) have been
- * completed 4) If the downloads have been completed, returns
- * NO_DOWNLOAD_REQUIRED The idea is that this can be called during the
- * startup of an application to quickly ascertain if the application needs
- * to wait to hear about any updated APK expansion files. Note that this does
- * mean that the application MUST be run for the first time with a network
- * connection, even if Market delivers all of the files.
- *
- * @param context Your application Context.
- * @param notificationClient A PendingIntent to start the Activity in your application
- * that shows the download progress and which will also start the application when download
- * completes.
- * @param serviceClass the class of your {@link imp.DownloaderService} implementation
- * @return whether the service was started and the reason for starting the service.
- * Either {@link #NO_DOWNLOAD_REQUIRED}, {@link #LVL_CHECK_REQUIRED}, or {@link
- * #DOWNLOAD_REQUIRED}.
- * @throws NameNotFoundException
- */
- public static int startDownloadServiceIfRequired(Context context, PendingIntent notificationClient,
- Class<?> serviceClass)
- throws NameNotFoundException {
- return DownloaderService.startDownloadServiceIfRequired(context, notificationClient,
- serviceClass);
- }
-
- /**
- * This version assumes that the intent contains the pending intent as a parameter. This
- * is used for responding to alarms.
- * <p>The pending intent must be in an extra with the key {@link
- * impl.DownloaderService#EXTRA_PENDING_INTENT}.
- *
- * @param context
- * @param notificationClient
- * @param serviceClass the class of the service to start
- * @return
- * @throws NameNotFoundException
- */
- public static int startDownloadServiceIfRequired(Context context, Intent notificationClient,
- Class<?> serviceClass)
- throws NameNotFoundException {
- return DownloaderService.startDownloadServiceIfRequired(context, notificationClient,
- serviceClass);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
deleted file mode 100644
index f75debe32d..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/DownloaderServiceMarshaller.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader;
-
-import com.google.android.vending.expansion.downloader.impl.DownloaderService;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This class is used by the client activity to proxy requests to the Downloader
- * Service.
- *
- * Most importantly, you must call {@link #CreateProxy} during the {@link
- * IDownloaderClient#onServiceConnected} callback in your activity in order to instantiate
- * an {@link IDownloaderService} object that you can then use to issue commands to the {@link
- * DownloaderService} (such as to pause and resume downloads).
- */
-public class DownloaderServiceMarshaller {
-
- public static final int MSG_REQUEST_ABORT_DOWNLOAD =
- 1;
- public static final int MSG_REQUEST_PAUSE_DOWNLOAD =
- 2;
- public static final int MSG_SET_DOWNLOAD_FLAGS =
- 3;
- public static final int MSG_REQUEST_CONTINUE_DOWNLOAD =
- 4;
- public static final int MSG_REQUEST_DOWNLOAD_STATE =
- 5;
- public static final int MSG_REQUEST_CLIENT_UPDATE =
- 6;
-
- public static final String PARAMS_FLAGS = "flags";
- public static final String PARAM_MESSENGER = DownloaderService.EXTRA_MESSAGE_HANDLER;
-
- private static class Proxy implements IDownloaderService {
- private Messenger mMsg;
-
- private void send(int method, Bundle params) {
- Message m = Message.obtain(null, method);
- m.setData(params);
- try {
- mMsg.send(m);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- public Proxy(Messenger msg) {
- mMsg = msg;
- }
-
- @Override
- public void requestAbortDownload() {
- send(MSG_REQUEST_ABORT_DOWNLOAD, new Bundle());
- }
-
- @Override
- public void requestPauseDownload() {
- send(MSG_REQUEST_PAUSE_DOWNLOAD, new Bundle());
- }
-
- @Override
- public void setDownloadFlags(int flags) {
- Bundle params = new Bundle();
- params.putInt(PARAMS_FLAGS, flags);
- send(MSG_SET_DOWNLOAD_FLAGS, params);
- }
-
- @Override
- public void requestContinueDownload() {
- send(MSG_REQUEST_CONTINUE_DOWNLOAD, new Bundle());
- }
-
- @Override
- public void requestDownloadStatus() {
- send(MSG_REQUEST_DOWNLOAD_STATE, new Bundle());
- }
-
- @Override
- public void onClientUpdated(Messenger clientMessenger) {
- Bundle bundle = new Bundle(1);
- bundle.putParcelable(PARAM_MESSENGER, clientMessenger);
- send(MSG_REQUEST_CLIENT_UPDATE, bundle);
- }
- }
-
- private static class Stub implements IStub {
- private IDownloaderService mItf = null;
- private final MessengerHandlerServer mMsgHandler = new MessengerHandlerServer(this);
- final Messenger mMessenger = new Messenger(mMsgHandler);
-
- private static class MessengerHandlerServer extends Handler {
- private final WeakReference<Stub> mDownloader;
- public MessengerHandlerServer(Stub downloader) {
- mDownloader = new WeakReference<>(downloader);
- }
-
- @Override
- public void handleMessage(Message msg) {
- Stub downloader = mDownloader.get();
- if (downloader != null) {
- downloader.handleMessage(msg);
- }
- }
- }
-
- private void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REQUEST_ABORT_DOWNLOAD:
- mItf.requestAbortDownload();
- break;
- case MSG_REQUEST_CONTINUE_DOWNLOAD:
- mItf.requestContinueDownload();
- break;
- case MSG_REQUEST_PAUSE_DOWNLOAD:
- mItf.requestPauseDownload();
- break;
- case MSG_SET_DOWNLOAD_FLAGS:
- mItf.setDownloadFlags(msg.getData().getInt(PARAMS_FLAGS));
- break;
- case MSG_REQUEST_DOWNLOAD_STATE:
- mItf.requestDownloadStatus();
- break;
- case MSG_REQUEST_CLIENT_UPDATE:
- mItf.onClientUpdated((Messenger)msg.getData().getParcelable(
- PARAM_MESSENGER));
- break;
- }
- }
-
- public Stub(IDownloaderService itf) {
- mItf = itf;
- }
-
- @Override
- public Messenger getMessenger() {
- return mMessenger;
- }
-
- @Override
- public void connect(Context c) {
- }
-
- @Override
- public void disconnect(Context c) {
- }
- }
-
- /**
- * Returns a proxy that will marshall calls to IDownloaderService methods
- *
- * @param ctx
- * @return
- */
- public static IDownloaderService CreateProxy(Messenger msg) {
- return new Proxy(msg);
- }
-
- /**
- * Returns a stub object that, when connected, will listen for marshalled
- * IDownloaderService methods and translate them into calls to the supplied
- * interface.
- *
- * @param itf An implementation of IDownloaderService that will be called
- * when remote method calls are unmarshalled.
- * @return
- */
- public static IStub CreateStub(IDownloaderService itf) {
- return new Stub(itf);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
deleted file mode 100644
index cd8726533f..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.Environment;
-import android.os.StatFs;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.godot.game.R;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Random;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Some helper functions for the download manager
- */
-public class Helpers {
-
- public static Random sRandom = new Random(SystemClock.uptimeMillis());
-
- /** Regex used to parse content-disposition headers */
- private static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern
- .compile("attachment;\\s*filename\\s*=\\s*\"([^\"]*)\"");
-
- private Helpers() {
- }
-
- /*
- * Parse the Content-Disposition HTTP Header. The format of the header is defined here:
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
- * content that is going to be downloaded to the file system. We only support the attachment
- * type.
- */
- static String parseContentDisposition(String contentDisposition) {
- try {
- Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);
- if (m.find()) {
- return m.group(1);
- }
- } catch (IllegalStateException ex) {
- // This function is defined as returning null when it can't parse
- // the header
- }
- return null;
- }
-
- /**
- * @return the root of the filesystem containing the given path
- */
- public static File getFilesystemRoot(String path) {
- File cache = Environment.getDownloadCacheDirectory();
- if (path.startsWith(cache.getPath())) {
- return cache;
- }
- File external = Environment.getExternalStorageDirectory();
- if (path.startsWith(external.getPath())) {
- return external;
- }
- throw new IllegalArgumentException(
- "Cannot determine filesystem root for " + path);
- }
-
- public static boolean isExternalMediaMounted() {
- if (!Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)) {
- // No SD card found.
- if (Constants.LOGVV) {
- Log.d(Constants.TAG, "no external storage");
- }
- return false;
- }
- return true;
- }
-
- /**
- * @return the number of bytes available on the filesystem rooted at the given File
- */
- public static long getAvailableBytes(File root) {
- StatFs stat = new StatFs(root.getPath());
- // put a bit of margin (in case creating the file grows the system by a
- // few blocks)
- long availableBlocks = (long)stat.getAvailableBlocks() - 4;
- return stat.getBlockSize() * availableBlocks;
- }
-
- /**
- * Checks whether the filename looks legitimate
- */
- public static boolean isFilenameValid(String filename) {
- filename = filename.replaceFirst("/+", "/"); // normalize leading
- // slashes
- return filename.startsWith(Environment.getDownloadCacheDirectory().toString()) || filename.startsWith(Environment.getExternalStorageDirectory().toString());
- }
-
- /*
- * Delete the given file from device
- */
- /* package */ static void deleteFile(String path) {
- try {
- File file = new File(path);
- file.delete();
- } catch (Exception e) {
- Log.w(Constants.TAG, "file: '" + path + "' couldn't be deleted", e);
- }
- }
-
- /**
- * Showing progress in MB here. It would be nice to choose the unit (KB, MB, GB) based on total
- * file size, but given what we know about the expected ranges of file sizes for APK expansion
- * files, it's probably not necessary.
- *
- * @param overallProgress
- * @param overallTotal
- * @return
- */
-
- static public String getDownloadProgressString(long overallProgress, long overallTotal) {
- if (overallTotal == 0) {
- if (Constants.LOGVV) {
- Log.e(Constants.TAG, "Notification called when total is zero");
- }
- return "";
- }
- return String.format(Locale.ENGLISH, "%.2f",
- (float)overallProgress / (1024.0f * 1024.0f)) +
- "MB /" +
- String.format(Locale.ENGLISH, "%.2f", (float)overallTotal / (1024.0f * 1024.0f)) + "MB";
- }
-
- /**
- * Adds a percentile to getDownloadProgressString.
- *
- * @param overallProgress
- * @param overallTotal
- * @return
- */
- static public String getDownloadProgressStringNotification(long overallProgress,
- long overallTotal) {
- if (overallTotal == 0) {
- if (Constants.LOGVV) {
- Log.e(Constants.TAG, "Notification called when total is zero");
- }
- return "";
- }
- return getDownloadProgressString(overallProgress, overallTotal) + " (" +
- getDownloadProgressPercent(overallProgress, overallTotal) + ")";
- }
-
- public static String getDownloadProgressPercent(long overallProgress, long overallTotal) {
- if (overallTotal == 0) {
- if (Constants.LOGVV) {
- Log.e(Constants.TAG, "Notification called when total is zero");
- }
- return "";
- }
- return Long.toString(overallProgress * 100 / overallTotal) + "%";
- }
-
- public static String getSpeedString(float bytesPerMillisecond) {
- return String.format(Locale.ENGLISH, "%.2f", bytesPerMillisecond * 1000 / 1024);
- }
-
- public static String getTimeRemaining(long durationInMilliseconds) {
- SimpleDateFormat sdf;
- if (durationInMilliseconds > 1000 * 60 * 60) {
- sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
- } else {
- sdf = new SimpleDateFormat("mm:ss", Locale.getDefault());
- }
- return sdf.format(new Date(durationInMilliseconds - TimeZone.getDefault().getRawOffset()));
- }
-
- /**
- * Returns the file name (without full path) for an Expansion APK file from the given context.
- *
- * @param c the context
- * @param mainFile true for main file, false for patch file
- * @param versionCode the version of the file
- * @return String the file name of the expansion file
- */
- public static String getExpansionAPKFileName(Context c, boolean mainFile, int versionCode) {
- return (mainFile ? "main." : "patch.") + versionCode + "." + c.getPackageName() + ".obb";
- }
-
- /**
- * Returns the filename (where the file should be saved) from info about a download
- */
- static public String generateSaveFileName(Context c, String fileName) {
- String path = getSaveFilePath(c) + File.separator + fileName;
- return path;
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- static public String getSaveFilePath(Context c) {
- // This technically existed since Honeycomb, but it is critical
- // on KitKat and greater versions since it will create the
- // directory if needed
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- return c.getObbDir().toString();
- } else {
- File root = Environment.getExternalStorageDirectory();
- String path = root.toString() + Constants.EXP_PATH + c.getPackageName();
- return path;
- }
- }
-
- /**
- * Helper function to ascertain the existence of a file and return true/false appropriately
- *
- * @param c the app/activity/service context
- * @param fileName the name (sans path) of the file to query
- * @param fileSize the size that the file must match
- * @param deleteFileOnMismatch if the file sizes do not match, delete the file
- * @return true if it does exist, false otherwise
- */
- static public boolean doesFileExist(Context c, String fileName, long fileSize,
- boolean deleteFileOnMismatch) {
- // the file may have been delivered by Play --- let's make sure
- // it's the size we expect
- File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
- if (fileForNewFile.exists()) {
- if (fileForNewFile.length() == fileSize) {
- return true;
- }
- if (deleteFileOnMismatch) {
- // delete the file --- we won't be able to resume
- // because we cannot confirm the integrity of the file
- fileForNewFile.delete();
- }
- }
- return false;
- }
-
- public static final int FS_READABLE = 0;
- public static final int FS_DOES_NOT_EXIST = 1;
- public static final int FS_CANNOT_READ = 2;
-
- /**
- * Helper function to ascertain whether a file can be read.
- *
- * @param c the app/activity/service context
- * @param fileName the name (sans path) of the file to query
- * @return true if it does exist, false otherwise
- */
- static public int getFileStatus(Context c, String fileName) {
- // the file may have been delivered by Play --- let's make sure
- // it's the size we expect
- File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName));
- int returnValue;
- if (fileForNewFile.exists()) {
- if (fileForNewFile.canRead()) {
- returnValue = FS_READABLE;
- } else {
- returnValue = FS_CANNOT_READ;
- }
- } else {
- returnValue = FS_DOES_NOT_EXIST;
- }
- return returnValue;
- }
-
- /**
- * Helper function to ascertain whether the application has the correct access to the OBB
- * directory to allow an OBB file to be written.
- *
- * @param c the app/activity/service context
- * @return true if the application can write an OBB file, false otherwise
- */
- static public boolean canWriteOBBFile(Context c) {
- String path = getSaveFilePath(c);
- File fileForNewFile = new File(path);
- boolean canWrite;
- if (fileForNewFile.exists()) {
- canWrite = fileForNewFile.isDirectory() && fileForNewFile.canWrite();
- } else {
- canWrite = fileForNewFile.mkdirs();
- }
- return canWrite;
- }
-
- /**
- * Converts download states that are returned by the
- * {@link IDownloaderClient#onDownloadStateChanged} callback into usable strings. This is useful
- * if using the state strings built into the library to display user messages.
- *
- * @param state One of the STATE_* constants from {@link IDownloaderClient}.
- * @return string resource ID for the corresponding string.
- */
- static public int getDownloaderStringResourceIDFromState(int state) {
- switch (state) {
- case IDownloaderClient.STATE_IDLE:
- return R.string.state_idle;
- case IDownloaderClient.STATE_FETCHING_URL:
- return R.string.state_fetching_url;
- case IDownloaderClient.STATE_CONNECTING:
- return R.string.state_connecting;
- case IDownloaderClient.STATE_DOWNLOADING:
- return R.string.state_downloading;
- case IDownloaderClient.STATE_COMPLETED:
- return R.string.state_completed;
- case IDownloaderClient.STATE_PAUSED_NETWORK_UNAVAILABLE:
- return R.string.state_paused_network_unavailable;
- case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
- return R.string.state_paused_by_request;
- case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
- return R.string.state_paused_wifi_disabled;
- case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
- return R.string.state_paused_wifi_unavailable;
- case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED:
- return R.string.state_paused_wifi_disabled;
- case IDownloaderClient.STATE_PAUSED_NEED_WIFI:
- return R.string.state_paused_wifi_unavailable;
- case IDownloaderClient.STATE_PAUSED_ROAMING:
- return R.string.state_paused_roaming;
- case IDownloaderClient.STATE_PAUSED_NETWORK_SETUP_FAILURE:
- return R.string.state_paused_network_setup_failure;
- case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
- return R.string.state_paused_sdcard_unavailable;
- case IDownloaderClient.STATE_FAILED_UNLICENSED:
- return R.string.state_failed_unlicensed;
- case IDownloaderClient.STATE_FAILED_FETCHING_URL:
- return R.string.state_failed_fetching_url;
- case IDownloaderClient.STATE_FAILED_SDCARD_FULL:
- return R.string.state_failed_sdcard_full;
- case IDownloaderClient.STATE_FAILED_CANCELED:
- return R.string.state_failed_cancelled;
- default:
- return R.string.state_unknown;
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
deleted file mode 100644
index c5577d4c2a..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/SystemFacade.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader;
-
-import android.annotation.SuppressLint;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-/**
- * Contains useful helper functions, typically tied to the application context.
- */
-class SystemFacade {
- private Context mContext;
- private NotificationManager mNotificationManager;
-
- public SystemFacade(Context context) {
- mContext = context;
- mNotificationManager = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- }
-
- public long currentTimeMillis() {
- return System.currentTimeMillis();
- }
-
- public Integer getActiveNetworkType() {
- ConnectivityManager connectivity =
- (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (connectivity == null) {
- Log.w(Constants.TAG, "couldn't get connectivity manager");
- return null;
- }
-
- @SuppressLint("MissingPermission")
- NetworkInfo activeInfo = connectivity.getActiveNetworkInfo();
- if (activeInfo == null) {
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "network is not available");
- }
- return null;
- }
- return activeInfo.getType();
- }
-
- public boolean isNetworkRoaming() {
- ConnectivityManager connectivity =
- (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (connectivity == null) {
- Log.w(Constants.TAG, "couldn't get connectivity manager");
- return false;
- }
-
- @SuppressLint("MissingPermission")
- NetworkInfo info = connectivity.getActiveNetworkInfo();
- boolean isMobile = (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE);
- TelephonyManager tm = (TelephonyManager)mContext
- .getSystemService(Context.TELEPHONY_SERVICE);
- if (null == tm) {
- Log.w(Constants.TAG, "couldn't get telephony manager");
- return false;
- }
- boolean isRoaming = isMobile && tm.isNetworkRoaming();
- if (Constants.LOGVV && isRoaming) {
- Log.v(Constants.TAG, "network is roaming");
- }
- return isRoaming;
- }
-
- public Long getMaxBytesOverMobile() {
- return (long)Integer.MAX_VALUE;
- }
-
- public Long getRecommendedMaxBytesOverMobile() {
- return 2097152L;
- }
-
- public void sendBroadcast(Intent intent) {
- mContext.sendBroadcast(intent);
- }
-
- public boolean userOwnsPackage(int uid, String packageName) throws NameNotFoundException {
- return mContext.getPackageManager().getApplicationInfo(packageName, 0).uid == uid;
- }
-
- public void postNotification(long id, Notification notification) {
- /**
- * TODO: The system notification manager takes ints, not longs, as IDs,
- * but the download manager uses IDs take straight from the database,
- * which are longs. This will have to be dealt with at some point.
- */
- mNotificationManager.notify((int)id, notification);
- }
-
- public void cancelNotification(long id) {
- mNotificationManager.cancel((int)id);
- }
-
- public void cancelAllNotifications() {
- mNotificationManager.cancelAll();
- }
-
- public void startThread(Thread thread) {
- thread.start();
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java
deleted file mode 100755
index 6346d7703a..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/CustomIntentService.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * This service differs from IntentService in a few minor ways/ It will not
- * auto-stop itself after the intent is handled unless the target returns "true"
- * in should stop. Since the goal of this service is to handle a single kind of
- * intent, it does not queue up batches of intents of the same type.
- */
-public abstract class CustomIntentService extends Service {
- private String mName;
- private boolean mRedelivery;
- private volatile ServiceHandler mServiceHandler;
- private volatile Looper mServiceLooper;
- private static final String LOG_TAG = "CustomIntentService";
- private static final int WHAT_MESSAGE = -10;
-
- public CustomIntentService(String paramString) {
- this.mName = paramString;
- }
-
- @Override
- public IBinder onBind(Intent paramIntent) {
- return null;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- HandlerThread localHandlerThread = new HandlerThread("IntentService[" + this.mName + "]");
- localHandlerThread.start();
- this.mServiceLooper = localHandlerThread.getLooper();
- this.mServiceHandler = new ServiceHandler(this.mServiceLooper);
- }
-
- @Override
- public void onDestroy() {
- Thread localThread = this.mServiceLooper.getThread();
- if ((localThread != null) && (localThread.isAlive())) {
- localThread.interrupt();
- }
- this.mServiceLooper.quit();
- Log.d(LOG_TAG, "onDestroy");
- }
-
- protected abstract void onHandleIntent(Intent paramIntent);
-
- protected abstract boolean shouldStop();
-
- @Override
- public void onStart(Intent paramIntent, int startId) {
- if (!this.mServiceHandler.hasMessages(WHAT_MESSAGE)) {
- Message localMessage = this.mServiceHandler.obtainMessage();
- localMessage.arg1 = startId;
- localMessage.obj = paramIntent;
- localMessage.what = WHAT_MESSAGE;
- this.mServiceHandler.sendMessage(localMessage);
- }
- }
-
- @Override
- public int onStartCommand(Intent paramIntent, int flags, int startId) {
- onStart(paramIntent, startId);
- return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
- }
-
- public void setIntentRedelivery(boolean enabled) {
- this.mRedelivery = enabled;
- }
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message paramMessage) {
- CustomIntentService.this
- .onHandleIntent((Intent)paramMessage.obj);
- if (shouldStop()) {
- Log.d(LOG_TAG, "stopSelf");
- CustomIntentService.this.stopSelf(paramMessage.arg1);
- Log.d(LOG_TAG, "afterStopSelf");
- }
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java
deleted file mode 100644
index 0e72b7ae77..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadInfo.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import com.google.android.vending.expansion.downloader.Constants;
-import com.google.android.vending.expansion.downloader.Helpers;
-
-import android.util.Log;
-
-/**
- * Representation of information about an individual download from the database.
- */
-public class DownloadInfo {
- public String mUri;
- public final int mIndex;
- public final String mFileName;
- public String mETag;
- public long mTotalBytes;
- public long mCurrentBytes;
- public long mLastMod;
- public int mStatus;
- public int mControl;
- public int mNumFailed;
- public int mRetryAfter;
- public int mRedirectCount;
-
- boolean mInitialized;
-
- public int mFuzz;
-
- public DownloadInfo(int index, String fileName, String pkg) {
- mFuzz = Helpers.sRandom.nextInt(1001);
- mFileName = fileName;
- mIndex = index;
- }
-
- public void resetDownload() {
- mCurrentBytes = 0;
- mETag = "";
- mLastMod = 0;
- mStatus = 0;
- mControl = 0;
- mNumFailed = 0;
- mRetryAfter = 0;
- mRedirectCount = 0;
- }
-
- /**
- * Returns the time when a download should be restarted.
- */
- public long restartTime(long now) {
- if (mNumFailed == 0) {
- return now;
- }
- if (mRetryAfter > 0) {
- return mLastMod + mRetryAfter;
- }
- return mLastMod +
- Constants.RETRY_FIRST_DELAY *
- (1000 + mFuzz) * (1 << (mNumFailed - 1));
- }
-
- public void logVerboseInfo() {
- Log.v(Constants.TAG, "Service adding new entry");
- Log.v(Constants.TAG, "FILENAME: " + mFileName);
- Log.v(Constants.TAG, "URI : " + mUri);
- Log.v(Constants.TAG, "FILENAME: " + mFileName);
- Log.v(Constants.TAG, "CONTROL : " + mControl);
- Log.v(Constants.TAG, "STATUS : " + mStatus);
- Log.v(Constants.TAG, "FAILED_C: " + mNumFailed);
- Log.v(Constants.TAG, "RETRY_AF: " + mRetryAfter);
- Log.v(Constants.TAG, "REDIRECT: " + mRedirectCount);
- Log.v(Constants.TAG, "LAST_MOD: " + mLastMod);
- Log.v(Constants.TAG, "TOTAL : " + mTotalBytes);
- Log.v(Constants.TAG, "CURRENT : " + mCurrentBytes);
- Log.v(Constants.TAG, "ETAG : " + mETag);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
deleted file mode 100644
index 099e3f05b3..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import com.godot.game.R;
-import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
-import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
-import com.google.android.vending.expansion.downloader.Helpers;
-import com.google.android.vending.expansion.downloader.IDownloaderClient;
-
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Build;
-import android.os.Messenger;
-import android.support.v4.app.NotificationCompat;
-
-/**
- * This class handles displaying the notification associated with the download
- * queue going on in the download manager. It handles multiple status types;
- * Some require user interaction and some do not. Some of the user interactions
- * may be transient. (for example: the user is queried to continue the download
- * on 3G when it started on WiFi, but then the phone locks onto WiFi again so
- * the prompt automatically goes away)
- * <p/>
- * The application interface for the downloader also needs to understand and
- * handle these transient states.
- */
-public class DownloadNotification implements IDownloaderClient {
-
- private int mState;
- private final Context mContext;
- private final NotificationManager mNotificationManager;
- private CharSequence mCurrentTitle;
-
- private IDownloaderClient mClientProxy;
- private NotificationCompat.Builder mActiveDownloadBuilder;
- private NotificationCompat.Builder mBuilder;
- private NotificationCompat.Builder mCurrentBuilder;
- private CharSequence mLabel;
- private String mCurrentText;
- private DownloadProgressInfo mProgressInfo;
- private PendingIntent mContentIntent;
-
- static final String LOGTAG = "DownloadNotification";
- static final int NOTIFICATION_ID = LOGTAG.hashCode();
-
- public PendingIntent getClientIntent() {
- return mContentIntent;
- }
-
- public void setClientIntent(PendingIntent clientIntent) {
- this.mBuilder.setContentIntent(clientIntent);
- this.mActiveDownloadBuilder.setContentIntent(clientIntent);
- this.mContentIntent = clientIntent;
- }
-
- public void resendState() {
- if (null != mClientProxy) {
- mClientProxy.onDownloadStateChanged(mState);
- }
- }
-
- @Override
- public void onDownloadStateChanged(int newState) {
- if (null != mClientProxy) {
- mClientProxy.onDownloadStateChanged(newState);
- }
- if (newState != mState) {
- mState = newState;
- if (newState == IDownloaderClient.STATE_IDLE || null == mContentIntent) {
- return;
- }
- int stringDownloadID;
- int iconResource;
- boolean ongoingEvent;
-
- // get the new title string and paused text
- switch (newState) {
- case 0:
- iconResource = android.R.drawable.stat_sys_warning;
- stringDownloadID = R.string.state_unknown;
- ongoingEvent = false;
- break;
-
- case IDownloaderClient.STATE_DOWNLOADING:
- iconResource = android.R.drawable.stat_sys_download;
- stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
- ongoingEvent = true;
- break;
-
- case IDownloaderClient.STATE_FETCHING_URL:
- case IDownloaderClient.STATE_CONNECTING:
- iconResource = android.R.drawable.stat_sys_download_done;
- stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
- ongoingEvent = true;
- break;
-
- case IDownloaderClient.STATE_COMPLETED:
- case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
- iconResource = android.R.drawable.stat_sys_download_done;
- stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
- ongoingEvent = false;
- break;
-
- case IDownloaderClient.STATE_FAILED:
- case IDownloaderClient.STATE_FAILED_CANCELED:
- case IDownloaderClient.STATE_FAILED_FETCHING_URL:
- case IDownloaderClient.STATE_FAILED_SDCARD_FULL:
- case IDownloaderClient.STATE_FAILED_UNLICENSED:
- iconResource = android.R.drawable.stat_sys_warning;
- stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
- ongoingEvent = false;
- break;
-
- default:
- iconResource = android.R.drawable.stat_sys_warning;
- stringDownloadID = Helpers.getDownloaderStringResourceIDFromState(newState);
- ongoingEvent = true;
- break;
- }
-
- mCurrentText = mContext.getString(stringDownloadID);
- mCurrentTitle = mLabel;
- mCurrentBuilder.setTicker(mLabel + ": " + mCurrentText);
- mCurrentBuilder.setSmallIcon(iconResource);
- mCurrentBuilder.setContentTitle(mCurrentTitle);
- mCurrentBuilder.setContentText(mCurrentText);
- if (ongoingEvent) {
- mCurrentBuilder.setOngoing(true);
- } else {
- mCurrentBuilder.setOngoing(false);
- mCurrentBuilder.setAutoCancel(true);
- }
- mNotificationManager.notify(NOTIFICATION_ID, mCurrentBuilder.build());
- }
- }
-
- @Override
- public void onDownloadProgress(DownloadProgressInfo progress) {
- mProgressInfo = progress;
- if (null != mClientProxy) {
- mClientProxy.onDownloadProgress(progress);
- }
- if (progress.mOverallTotal <= 0) {
- // we just show the text
- mBuilder.setTicker(mCurrentTitle);
- mBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
- mBuilder.setContentTitle(mCurrentTitle);
- mBuilder.setContentText(mCurrentText);
- mCurrentBuilder = mBuilder;
- } else {
- mActiveDownloadBuilder.setProgress((int)progress.mOverallTotal, (int)progress.mOverallProgress, false);
- mActiveDownloadBuilder.setContentText(Helpers.getDownloadProgressString(progress.mOverallProgress, progress.mOverallTotal));
- mActiveDownloadBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
- mActiveDownloadBuilder.setTicker(mLabel + ": " + mCurrentText);
- mActiveDownloadBuilder.setContentTitle(mLabel);
- mActiveDownloadBuilder.setContentInfo(mContext.getString(R.string.time_remaining_notification,
- Helpers.getTimeRemaining(progress.mTimeRemaining)));
- mCurrentBuilder = mActiveDownloadBuilder;
- }
- mNotificationManager.notify(NOTIFICATION_ID, mCurrentBuilder.build());
- }
-
- /**
- * Called in response to onClientUpdated. Creates a new proxy and notifies
- * it of the current state.
- *
- * @param msg the client Messenger to notify
- */
- public void setMessenger(Messenger msg) {
- mClientProxy = DownloaderClientMarshaller.CreateProxy(msg);
- if (null != mProgressInfo) {
- mClientProxy.onDownloadProgress(mProgressInfo);
- }
- if (mState != -1) {
- mClientProxy.onDownloadStateChanged(mState);
- }
- }
-
- /**
- * Constructor
- *
- * @param ctx The context to use to obtain access to the Notification
- * Service
- */
- DownloadNotification(Context ctx, CharSequence applicationLabel) {
- mState = -1;
- mContext = ctx;
- mLabel = applicationLabel;
- mNotificationManager = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- mActiveDownloadBuilder = new NotificationCompat.Builder(ctx);
- mBuilder = new NotificationCompat.Builder(ctx);
-
- // Set Notification category and priorities to something that makes sense for a long
- // lived background task.
- mActiveDownloadBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
- mActiveDownloadBuilder.setCategory(NotificationCompat.CATEGORY_PROGRESS);
-
- mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
- mBuilder.setCategory(NotificationCompat.CATEGORY_PROGRESS);
-
- mCurrentBuilder = mBuilder;
- }
-
- @Override
- public void onServiceConnected(Messenger m) {
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
deleted file mode 100644
index 2fa146408b..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadThread.java
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import com.google.android.vending.expansion.downloader.Constants;
-import com.google.android.vending.expansion.downloader.Helpers;
-import com.google.android.vending.expansion.downloader.IDownloaderClient;
-
-import android.content.Context;
-import android.os.PowerManager;
-import android.os.Process;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.SyncFailedException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Locale;
-
-/**
- * Runs an actual download
- */
-public class DownloadThread {
-
- private Context mContext;
- private DownloadInfo mInfo;
- private DownloaderService mService;
- private final DownloadsDB mDB;
- private final DownloadNotification mNotification;
- private String mUserAgent;
-
- public DownloadThread(DownloadInfo info, DownloaderService service,
- DownloadNotification notification) {
- mContext = service;
- mInfo = info;
- mService = service;
- mNotification = notification;
- mDB = DownloadsDB.getDB(service);
- mUserAgent = "APKXDL (Linux; U; Android " + android.os.Build.VERSION.RELEASE + ";" + Locale.getDefault().toString() + "; " + android.os.Build.DEVICE + "/" + android.os.Build.ID + ")" +
- service.getPackageName();
- }
-
- /**
- * Returns the default user agent
- */
- private String userAgent() {
- return mUserAgent;
- }
-
- /**
- * State for the entire run() method.
- */
- private static class State {
- public String mFilename;
- public FileOutputStream mStream;
- public boolean mCountRetry = false;
- public int mRetryAfter = 0;
- public int mRedirectCount = 0;
- public String mNewUri;
- public boolean mGotData = false;
- public String mRequestUri;
-
- public State(DownloadInfo info, DownloaderService service) {
- mRedirectCount = info.mRedirectCount;
- mRequestUri = info.mUri;
- mFilename = service.generateTempSaveFileName(info.mFileName);
- }
- }
-
- /**
- * State within executeDownload()
- */
- private static class InnerState {
- public int mBytesSoFar = 0;
- public int mBytesThisSession = 0;
- public String mHeaderETag;
- public boolean mContinuingDownload = false;
- public String mHeaderContentLength;
- public String mHeaderContentDisposition;
- public String mHeaderContentLocation;
- public int mBytesNotified = 0;
- public long mTimeLastNotification = 0;
- }
-
- /**
- * Raised from methods called by run() to indicate that the current request
- * should be stopped immediately. Note the message passed to this exception
- * will be logged and therefore must be guaranteed not to contain any PII,
- * meaning it generally can't include any information about the request URI,
- * headers, or destination filename.
- */
- private class StopRequest extends Throwable {
-
- private static final long serialVersionUID = 6338592678988347973L;
- public int mFinalStatus;
-
- public StopRequest(int finalStatus, String message) {
- super(message);
- mFinalStatus = finalStatus;
- }
-
- public StopRequest(int finalStatus, String message, Throwable throwable) {
- super(message, throwable);
- mFinalStatus = finalStatus;
- }
- }
-
- /**
- * Raised from methods called by executeDownload() to indicate that the
- * download should be retried immediately.
- */
- private class RetryDownload extends Throwable {
-
- private static final long serialVersionUID = 6196036036517540229L;
- }
-
- /**
- * Executes the download in a separate thread
- */
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
- State state = new State(mInfo, mService);
- PowerManager.WakeLock wakeLock = null;
- int finalStatus = DownloaderService.STATUS_UNKNOWN_ERROR;
-
- try {
- PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "org.godot.game:wakelock");
- wakeLock.acquire(20 * 60 * 1000L /*20 minutes*/);
-
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
- Log.v(Constants.TAG, " at " + mInfo.mUri);
- }
-
- boolean finished = false;
- while (!finished) {
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "initiating download for " + mInfo.mFileName);
- Log.v(Constants.TAG, " at " + mInfo.mUri);
- }
- // Set or unset proxy, which may have changed since last GET
- // request.
- // setDefaultProxy() supports null as proxy parameter.
- URL url = new URL(state.mRequestUri);
- HttpURLConnection request = (HttpURLConnection)url.openConnection();
- request.setRequestProperty("User-Agent", userAgent());
- try {
- executeDownload(state, request);
- finished = true;
- } catch (RetryDownload exc) {
- // fall through
- } finally {
- request.disconnect();
- request = null;
- }
- }
-
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "download completed for " + mInfo.mFileName);
- Log.v(Constants.TAG, " at " + mInfo.mUri);
- }
- finalizeDestinationFile(state);
- finalStatus = DownloaderService.STATUS_SUCCESS;
- } catch (StopRequest error) {
- // remove the cause before printing, in case it contains PII
- Log.w(Constants.TAG,
- "Aborting request for download " + mInfo.mFileName + ": " + error.getMessage());
- error.printStackTrace();
- finalStatus = error.mFinalStatus;
- // fall through to finally block
- } catch (Throwable ex) { // sometimes the socket code throws unchecked
- // exceptions
- Log.w(Constants.TAG, "Exception for " + mInfo.mFileName + ": " + ex);
- finalStatus = DownloaderService.STATUS_UNKNOWN_ERROR;
- // falls through to the code that reports an error
- } finally {
- if (wakeLock != null) {
- wakeLock.release();
- wakeLock = null;
- }
- cleanupDestination(state, finalStatus);
- notifyDownloadCompleted(finalStatus, state.mCountRetry, state.mRetryAfter,
- state.mRedirectCount, state.mGotData, state.mFilename);
- }
- }
-
- /**
- * Fully execute a single download request - setup and send the request,
- * handle the response, and transfer the data to the destination file.
- */
- private void executeDownload(State state, HttpURLConnection request)
- throws StopRequest, RetryDownload {
- InnerState innerState = new InnerState();
- byte data[] = new byte[Constants.BUFFER_SIZE];
-
- checkPausedOrCanceled(state);
-
- setupDestinationFile(state, innerState);
- addRequestHeaders(innerState, request);
-
- // check just before sending the request to avoid using an invalid
- // connection at all
- checkConnectivity(state);
-
- mNotification.onDownloadStateChanged(IDownloaderClient.STATE_CONNECTING);
- int responseCode = sendRequest(state, request);
- handleExceptionalStatus(state, innerState, request, responseCode);
-
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "received response for " + mInfo.mUri);
- }
-
- processResponseHeaders(state, innerState, request);
- InputStream entityStream = openResponseEntity(state, request);
- mNotification.onDownloadStateChanged(IDownloaderClient.STATE_DOWNLOADING);
- transferData(state, innerState, data, entityStream);
- }
-
- /**
- * Check if current connectivity is valid for this request.
- */
- private void checkConnectivity(State state) throws StopRequest {
- switch (mService.getNetworkAvailabilityState(mDB)) {
- case DownloaderService.NETWORK_OK:
- return;
- case DownloaderService.NETWORK_NO_CONNECTION:
- throw new StopRequest(DownloaderService.STATUS_WAITING_FOR_NETWORK,
- "waiting for network to return");
- case DownloaderService.NETWORK_TYPE_DISALLOWED_BY_REQUESTOR:
- throw new StopRequest(
- DownloaderService.STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION,
- "waiting for wifi or for download over cellular to be authorized");
- case DownloaderService.NETWORK_CANNOT_USE_ROAMING:
- throw new StopRequest(DownloaderService.STATUS_WAITING_FOR_NETWORK,
- "roaming is not allowed");
- case DownloaderService.NETWORK_UNUSABLE_DUE_TO_SIZE:
- throw new StopRequest(DownloaderService.STATUS_QUEUED_FOR_WIFI, "waiting for wifi");
- }
- }
-
- /**
- * Transfer as much data as possible from the HTTP response to the
- * destination file.
- *
- * @param data buffer to use to read data
- * @param entityStream stream for reading the HTTP response entity
- */
- private void transferData(State state, InnerState innerState, byte[] data,
- InputStream entityStream) throws StopRequest {
- for (;;) {
- int bytesRead = readFromResponse(state, innerState, data, entityStream);
- if (bytesRead == -1) { // success, end of stream already reached
- handleEndOfStream(state, innerState);
- return;
- }
-
- state.mGotData = true;
- writeDataToDestination(state, data, bytesRead);
- innerState.mBytesSoFar += bytesRead;
- innerState.mBytesThisSession += bytesRead;
- reportProgress(state, innerState);
-
- checkPausedOrCanceled(state);
- }
- }
-
- /**
- * Called after a successful completion to take any necessary action on the
- * downloaded file.
- */
- private void finalizeDestinationFile(State state) throws StopRequest {
- syncDestination(state);
- String tempFilename = state.mFilename;
- String finalFilename = Helpers.generateSaveFileName(mService, mInfo.mFileName);
- if (!state.mFilename.equals(finalFilename)) {
- File startFile = new File(tempFilename);
- File destFile = new File(finalFilename);
- if (mInfo.mTotalBytes != -1 && mInfo.mCurrentBytes == mInfo.mTotalBytes) {
- if (!startFile.renameTo(destFile)) {
- throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
- "unable to finalize destination file");
- }
- } else {
- throw new StopRequest(DownloaderService.STATUS_FILE_DELIVERED_INCORRECTLY,
- "file delivered with incorrect size. probably due to network not browser configured");
- }
- }
- }
-
- /**
- * Called just before the thread finishes, regardless of status, to take any
- * necessary action on the downloaded file.
- */
- private void cleanupDestination(State state, int finalStatus) {
- closeDestination(state);
- if (state.mFilename != null && DownloaderService.isStatusError(finalStatus)) {
- new File(state.mFilename).delete();
- state.mFilename = null;
- }
- }
-
- /**
- * Sync the destination file to storage.
- */
- private void syncDestination(State state) {
- FileOutputStream downloadedFileStream = null;
- try {
- downloadedFileStream = new FileOutputStream(state.mFilename, true);
- downloadedFileStream.getFD().sync();
- } catch (FileNotFoundException ex) {
- Log.w(Constants.TAG, "file " + state.mFilename + " not found: " + ex);
- } catch (SyncFailedException ex) {
- Log.w(Constants.TAG, "file " + state.mFilename + " sync failed: " + ex);
- } catch (IOException ex) {
- Log.w(Constants.TAG, "IOException trying to sync " + state.mFilename + ": " + ex);
- } catch (RuntimeException ex) {
- Log.w(Constants.TAG, "exception while syncing file: ", ex);
- } finally {
- if (downloadedFileStream != null) {
- try {
- downloadedFileStream.close();
- } catch (IOException ex) {
- Log.w(Constants.TAG, "IOException while closing synced file: ", ex);
- } catch (RuntimeException ex) {
- Log.w(Constants.TAG, "exception while closing file: ", ex);
- }
- }
- }
- }
-
- /**
- * Close the destination output stream.
- */
- private void closeDestination(State state) {
- try {
- // close the file
- if (state.mStream != null) {
- state.mStream.close();
- state.mStream = null;
- }
- } catch (IOException ex) {
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "exception when closing the file after download : " + ex);
- }
- // nothing can really be done if the file can't be closed
- }
- }
-
- /**
- * Check if the download has been paused or canceled, stopping the request
- * appropriately if it has been.
- */
- private void checkPausedOrCanceled(State state) throws StopRequest {
- if (mService.getControl() == DownloaderService.CONTROL_PAUSED) {
- int status = mService.getStatus();
- switch (status) {
- case DownloaderService.STATUS_PAUSED_BY_APP:
- throw new StopRequest(mService.getStatus(),
- "download paused");
- }
- }
- }
-
- /**
- * Report download progress through the database if necessary.
- */
- private void reportProgress(State state, InnerState innerState) {
- long now = System.currentTimeMillis();
- if (innerState.mBytesSoFar - innerState.mBytesNotified > Constants.MIN_PROGRESS_STEP && now - innerState.mTimeLastNotification > Constants.MIN_PROGRESS_TIME) {
- // we store progress updates to the database here
- mInfo.mCurrentBytes = innerState.mBytesSoFar;
- mDB.updateDownloadCurrentBytes(mInfo);
-
- innerState.mBytesNotified = innerState.mBytesSoFar;
- innerState.mTimeLastNotification = now;
-
- long totalBytesSoFar = innerState.mBytesThisSession + mService.mBytesSoFar;
-
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "downloaded " + mInfo.mCurrentBytes + " out of " + mInfo.mTotalBytes);
- Log.v(Constants.TAG, " total " + totalBytesSoFar + " out of " + mService.mTotalLength);
- }
-
- mService.notifyUpdateBytes(totalBytesSoFar);
- }
- }
-
- /**
- * Write a data buffer to the destination file.
- *
- * @param data buffer containing the data to write
- * @param bytesRead how many bytes to write from the buffer
- */
- private void writeDataToDestination(State state, byte[] data, int bytesRead)
- throws StopRequest {
- for (;;) {
- try {
- if (state.mStream == null) {
- state.mStream = new FileOutputStream(state.mFilename, true);
- }
- state.mStream.write(data, 0, bytesRead);
- // we close after every write --- this may be too inefficient
- closeDestination(state);
- return;
- } catch (IOException ex) {
- if (!Helpers.isExternalMediaMounted()) {
- throw new StopRequest(DownloaderService.STATUS_DEVICE_NOT_FOUND_ERROR,
- "external media not mounted while writing destination file");
- }
-
- long availableBytes =
- Helpers.getAvailableBytes(Helpers.getFilesystemRoot(state.mFilename));
- if (availableBytes < bytesRead) {
- throw new StopRequest(DownloaderService.STATUS_INSUFFICIENT_SPACE_ERROR,
- "insufficient space while writing destination file", ex);
- }
- throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
- "while writing destination file: " + ex.toString(), ex);
- }
- }
- }
-
- /**
- * Called when we've reached the end of the HTTP response stream, to update
- * the database and check for consistency.
- */
- private void handleEndOfStream(State state, InnerState innerState) throws StopRequest {
- mInfo.mCurrentBytes = innerState.mBytesSoFar;
- // this should always be set from the market
- // if ( innerState.mHeaderContentLength == null ) {
- // mInfo.mTotalBytes = innerState.mBytesSoFar;
- // }
- mDB.updateDownload(mInfo);
-
- boolean lengthMismatched = (innerState.mHeaderContentLength != null) && (innerState.mBytesSoFar != Integer.parseInt(innerState.mHeaderContentLength));
- if (lengthMismatched) {
- if (cannotResume(innerState)) {
- throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
- "mismatched content length");
- } else {
- throw new StopRequest(getFinalStatusForHttpError(state),
- "closed socket before end of file");
- }
- }
- }
-
- private boolean cannotResume(InnerState innerState) {
- return innerState.mBytesSoFar > 0 && innerState.mHeaderETag == null;
- }
-
- /**
- * Read some data from the HTTP response stream, handling I/O errors.
- *
- * @param data buffer to use to read data
- * @param entityStream stream for reading the HTTP response entity
- * @return the number of bytes actually read or -1 if the end of the stream
- * has been reached
- */
- private int readFromResponse(State state, InnerState innerState, byte[] data,
- InputStream entityStream) throws StopRequest {
- try {
- return entityStream.read(data);
- } catch (IOException ex) {
- logNetworkState();
- mInfo.mCurrentBytes = innerState.mBytesSoFar;
- mDB.updateDownload(mInfo);
- if (cannotResume(innerState)) {
- String message = "while reading response: " + ex.toString() + ", can't resume interrupted download with no ETag";
- throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
- message, ex);
- } else {
- throw new StopRequest(getFinalStatusForHttpError(state),
- "while reading response: " + ex.toString(), ex);
- }
- }
- }
-
- /**
- * Open a stream for the HTTP response entity, handling I/O errors.
- *
- * @return an InputStream to read the response entity
- */
- private InputStream openResponseEntity(State state, HttpURLConnection response)
- throws StopRequest {
- try {
- return response.getInputStream();
- } catch (IOException ex) {
- logNetworkState();
- throw new StopRequest(getFinalStatusForHttpError(state),
- "while getting entity: " + ex.toString(), ex);
- }
- }
-
- private void logNetworkState() {
- if (Constants.LOGX) {
- Log.i(Constants.TAG,
- "Net " + (mService.getNetworkAvailabilityState(mDB) == DownloaderService.NETWORK_OK ? "Up" : "Down"));
- }
- }
-
- /**
- * Read HTTP response headers and take appropriate action, including setting
- * up the destination file and updating the database.
- */
- private void processResponseHeaders(State state, InnerState innerState, HttpURLConnection response)
- throws StopRequest {
- if (innerState.mContinuingDownload) {
- // ignore response headers on resume requests
- return;
- }
-
- readResponseHeaders(state, innerState, response);
-
- try {
- state.mFilename = mService.generateSaveFile(mInfo.mFileName, mInfo.mTotalBytes);
- } catch (DownloaderService.GenerateSaveFileError exc) {
- throw new StopRequest(exc.mStatus, exc.mMessage);
- }
- try {
- state.mStream = new FileOutputStream(state.mFilename);
- } catch (FileNotFoundException exc) {
- // make sure the directory exists
- File pathFile = new File(Helpers.getSaveFilePath(mService));
- try {
- if (pathFile.mkdirs()) {
- state.mStream = new FileOutputStream(state.mFilename);
- }
- } catch (Exception ex) {
- throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
- "while opening destination file: " + exc.toString(), exc);
- }
- }
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "writing " + mInfo.mUri + " to " + state.mFilename);
- }
-
- updateDatabaseFromHeaders(state, innerState);
- // check connectivity again now that we know the total size
- checkConnectivity(state);
- }
-
- /**
- * Update necessary database fields based on values of HTTP response headers
- * that have been read.
- */
- private void updateDatabaseFromHeaders(State state, InnerState innerState) {
- mInfo.mETag = innerState.mHeaderETag;
- mDB.updateDownload(mInfo);
- }
-
- /**
- * Read headers from the HTTP response and store them into local state.
- */
- private void readResponseHeaders(State state, InnerState innerState, HttpURLConnection response)
- throws StopRequest {
- String value = response.getHeaderField("Content-Disposition");
- if (value != null) {
- innerState.mHeaderContentDisposition = value;
- }
- value = response.getHeaderField("Content-Location");
- if (value != null) {
- innerState.mHeaderContentLocation = value;
- }
- value = response.getHeaderField("ETag");
- if (value != null) {
- innerState.mHeaderETag = value;
- }
- String headerTransferEncoding = null;
- value = response.getHeaderField("Transfer-Encoding");
- if (value != null) {
- headerTransferEncoding = value;
- }
- String headerContentType = null;
- value = response.getHeaderField("Content-Type");
- if (value != null) {
- headerContentType = value;
- if (!headerContentType.equals("application/vnd.android.obb")) {
- throw new StopRequest(DownloaderService.STATUS_FILE_DELIVERED_INCORRECTLY,
- "file delivered with incorrect Mime type");
- }
- }
-
- if (headerTransferEncoding == null) {
- long contentLength = response.getContentLength();
- if (value != null) {
- // this is always set from Market
- if (contentLength != -1 && contentLength != mInfo.mTotalBytes) {
- // we're most likely on a bad wifi connection -- we should
- // probably
- // also look at the mime type --- but the size mismatch is
- // enough
- // to tell us that something is wrong here
- Log.e(Constants.TAG, "Incorrect file size delivered.");
- } else {
- innerState.mHeaderContentLength = Long.toString(contentLength);
- }
- }
- } else {
- // Ignore content-length with transfer-encoding - 2616 4.4 3
- if (Constants.LOGVV) {
- Log.v(Constants.TAG,
- "ignoring content-length because of xfer-encoding");
- }
- }
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "Content-Disposition: " +
- innerState.mHeaderContentDisposition);
- Log.v(Constants.TAG, "Content-Length: " + innerState.mHeaderContentLength);
- Log.v(Constants.TAG, "Content-Location: " + innerState.mHeaderContentLocation);
- Log.v(Constants.TAG, "ETag: " + innerState.mHeaderETag);
- Log.v(Constants.TAG, "Transfer-Encoding: " + headerTransferEncoding);
- }
-
- boolean noSizeInfo = innerState.mHeaderContentLength == null && (headerTransferEncoding == null || !headerTransferEncoding.equalsIgnoreCase("chunked"));
- if (noSizeInfo) {
- throw new StopRequest(DownloaderService.STATUS_HTTP_DATA_ERROR,
- "can't know size of download, giving up");
- }
- }
-
- /**
- * Check the HTTP response status and handle anything unusual (e.g. not
- * 200/206).
- */
- private void handleExceptionalStatus(State state, InnerState innerState, HttpURLConnection connection, int responseCode)
- throws StopRequest, RetryDownload {
- if (responseCode == 503 && mInfo.mNumFailed < Constants.MAX_RETRIES) {
- handleServiceUnavailable(state, connection);
- }
- int expectedStatus = innerState.mContinuingDownload ? 206 : DownloaderService.STATUS_SUCCESS;
- if (responseCode != expectedStatus) {
- handleOtherStatus(state, innerState, responseCode);
- } else {
- // no longer redirected
- state.mRedirectCount = 0;
- }
- }
-
- /**
- * Handle a status that we don't know how to deal with properly.
- */
- private void handleOtherStatus(State state, InnerState innerState, int statusCode)
- throws StopRequest {
- int finalStatus;
- if (DownloaderService.isStatusError(statusCode)) {
- finalStatus = statusCode;
- } else if (statusCode >= 300 && statusCode < 400) {
- finalStatus = DownloaderService.STATUS_UNHANDLED_REDIRECT;
- } else if (innerState.mContinuingDownload && statusCode == DownloaderService.STATUS_SUCCESS) {
- finalStatus = DownloaderService.STATUS_CANNOT_RESUME;
- } else {
- finalStatus = DownloaderService.STATUS_UNHANDLED_HTTP_CODE;
- }
- throw new StopRequest(finalStatus, "http error " + statusCode);
- }
-
- /**
- * Add headers for this download to the HTTP request to allow for resume.
- */
- private void addRequestHeaders(InnerState innerState, HttpURLConnection request) {
- if (innerState.mContinuingDownload) {
- if (innerState.mHeaderETag != null) {
- request.setRequestProperty("If-Match", innerState.mHeaderETag);
- }
- request.setRequestProperty("Range", "bytes=" + innerState.mBytesSoFar + "-");
- }
- }
-
- /**
- * Handle a 503 Service Unavailable status by processing the Retry-After
- * header.
- */
- private void handleServiceUnavailable(State state, HttpURLConnection connection) throws StopRequest {
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "got HTTP response code 503");
- }
- state.mCountRetry = true;
- String retryAfterValue = connection.getHeaderField("Retry-After");
- if (retryAfterValue != null) {
- try {
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "Retry-After :" + retryAfterValue);
- }
- state.mRetryAfter = Integer.parseInt(retryAfterValue);
- if (state.mRetryAfter < 0) {
- state.mRetryAfter = 0;
- } else {
- if (state.mRetryAfter < Constants.MIN_RETRY_AFTER) {
- state.mRetryAfter = Constants.MIN_RETRY_AFTER;
- } else if (state.mRetryAfter > Constants.MAX_RETRY_AFTER) {
- state.mRetryAfter = Constants.MAX_RETRY_AFTER;
- }
- state.mRetryAfter += Helpers.sRandom.nextInt(Constants.MIN_RETRY_AFTER + 1);
- state.mRetryAfter *= 1000;
- }
- } catch (NumberFormatException ex) {
- // ignored - retryAfter stays 0 in this case.
- }
- }
- throw new StopRequest(DownloaderService.STATUS_WAITING_TO_RETRY,
- "got 503 Service Unavailable, will retry later");
- }
-
- /**
- * Send the request to the server, handling any I/O exceptions.
- */
- private int sendRequest(State state, HttpURLConnection request)
- throws StopRequest {
- try {
- return request.getResponseCode();
- } catch (IllegalArgumentException ex) {
- throw new StopRequest(DownloaderService.STATUS_HTTP_DATA_ERROR,
- "while trying to execute request: " + ex.toString(), ex);
- } catch (IOException ex) {
- logNetworkState();
- throw new StopRequest(getFinalStatusForHttpError(state),
- "while trying to execute request: " + ex.toString(), ex);
- }
- }
-
- private int getFinalStatusForHttpError(State state) {
- if (mService.getNetworkAvailabilityState(mDB) != DownloaderService.NETWORK_OK) {
- return DownloaderService.STATUS_WAITING_FOR_NETWORK;
- } else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
- state.mCountRetry = true;
- return DownloaderService.STATUS_WAITING_TO_RETRY;
- } else {
- Log.w(Constants.TAG, "reached max retries for " + mInfo.mNumFailed);
- return DownloaderService.STATUS_HTTP_DATA_ERROR;
- }
- }
-
- /**
- * Prepare the destination file to receive data. If the file already exists,
- * we'll set up appropriately for resumption.
- */
- private void setupDestinationFile(State state, InnerState innerState)
- throws StopRequest {
- if (state.mFilename != null) { // only true if we've already run a
- // thread for this download
- if (!Helpers.isFilenameValid(state.mFilename)) {
- // this should never happen
- throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
- "found invalid internal destination filename");
- }
- // We're resuming a download that got interrupted
- File f = new File(state.mFilename);
- if (f.exists()) {
- long fileLength = f.length();
- if (fileLength == 0) {
- // The download hadn't actually started, we can restart from
- // scratch
- f.delete();
- state.mFilename = null;
- } else if (mInfo.mETag == null) {
- // This should've been caught upon failure
- f.delete();
- throw new StopRequest(DownloaderService.STATUS_CANNOT_RESUME,
- "Trying to resume a download that can't be resumed");
- } else {
- // All right, we'll be able to resume this download
- try {
- state.mStream = new FileOutputStream(state.mFilename, true);
- } catch (FileNotFoundException exc) {
- throw new StopRequest(DownloaderService.STATUS_FILE_ERROR,
- "while opening destination for resuming: " + exc.toString(), exc);
- }
- innerState.mBytesSoFar = (int)fileLength;
- if (mInfo.mTotalBytes != -1) {
- innerState.mHeaderContentLength = Long.toString(mInfo.mTotalBytes);
- }
- innerState.mHeaderETag = mInfo.mETag;
- innerState.mContinuingDownload = true;
- }
- }
- }
-
- if (state.mStream != null) {
- closeDestination(state);
- }
- }
-
- /**
- * Stores information about the completed download, and notifies the
- * initiating application.
- */
- private void notifyDownloadCompleted(
- int status, boolean countRetry, int retryAfter, int redirectCount, boolean gotData,
- String filename) {
- updateDownloadDatabase(
- status, countRetry, retryAfter, redirectCount, gotData, filename);
- if (DownloaderService.isStatusCompleted(status)) {
- // TBD: send status update?
- }
- }
-
- private void updateDownloadDatabase(
- int status, boolean countRetry, int retryAfter, int redirectCount, boolean gotData,
- String filename) {
- mInfo.mStatus = status;
- mInfo.mRetryAfter = retryAfter;
- mInfo.mRedirectCount = redirectCount;
- mInfo.mLastMod = System.currentTimeMillis();
- if (!countRetry) {
- mInfo.mNumFailed = 0;
- } else if (gotData) {
- mInfo.mNumFailed = 1;
- } else {
- mInfo.mNumFailed++;
- }
- mDB.updateDownload(mInfo);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
deleted file mode 100644
index 25a561ccd4..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+++ /dev/null
@@ -1,1320 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import com.google.android.vending.expansion.downloader.Constants;
-import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
-import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller;
-import com.google.android.vending.expansion.downloader.Helpers;
-import com.google.android.vending.expansion.downloader.IDownloaderClient;
-import com.google.android.vending.expansion.downloader.IDownloaderService;
-import com.google.android.vending.expansion.downloader.IStub;
-import com.google.android.vending.licensing.AESObfuscator;
-import com.google.android.vending.licensing.APKExpansionPolicy;
-import com.google.android.vending.licensing.LicenseChecker;
-import com.google.android.vending.licensing.LicenseCheckerCallback;
-import com.google.android.vending.licensing.Policy;
-
-import android.annotation.SuppressLint;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Messenger;
-import android.os.SystemClock;
-import android.provider.Settings.Secure;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import java.io.File;
-
-/**
- * Performs the background downloads requested by applications that use the
- * Downloads provider. This service does not run as a foreground task, so
- * Android may kill it off at will, but it will try to restart itself if it can.
- * Note that Android by default will kill off any process that has an open file
- * handle on the shared (SD Card) partition if the partition is unmounted.
- */
-public abstract class DownloaderService extends CustomIntentService implements IDownloaderService {
-
- public DownloaderService() {
- super("LVLDownloadService");
- }
-
- private static final String LOG_TAG = "LVLDL";
-
- // the following NETWORK_* constants are used to indicates specific reasons
- // for disallowing a
- // download from using a network, since specific causes can require special
- // handling
-
- /**
- * The network is usable for the given download.
- */
- public static final int NETWORK_OK = 1;
-
- /**
- * There is no network connectivity.
- */
- public static final int NETWORK_NO_CONNECTION = 2;
-
- /**
- * The download exceeds the maximum size for this network.
- */
- public static final int NETWORK_UNUSABLE_DUE_TO_SIZE = 3;
-
- /**
- * The download exceeds the recommended maximum size for this network, the
- * user must confirm for this download to proceed without WiFi.
- */
- public static final int NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE = 4;
-
- /**
- * The current connection is roaming, and the download can't proceed over a
- * roaming connection.
- */
- public static final int NETWORK_CANNOT_USE_ROAMING = 5;
-
- /**
- * The app requesting the download specific that it can't use the current
- * network connection.
- */
- public static final int NETWORK_TYPE_DISALLOWED_BY_REQUESTOR = 6;
-
- /**
- * For intents used to notify the user that a download exceeds a size
- * threshold, if this extra is true, WiFi is required for this download
- * size; otherwise, it is only recommended.
- */
- public static final String EXTRA_IS_WIFI_REQUIRED = "isWifiRequired";
- public static final String EXTRA_FILE_NAME = "downloadId";
-
- /**
- * Used with DOWNLOAD_STATUS
- */
- public static final String EXTRA_STATUS_STATE = "ESS";
- public static final String EXTRA_STATUS_TOTAL_SIZE = "ETS";
- public static final String EXTRA_STATUS_CURRENT_FILE_SIZE = "CFS";
- public static final String EXTRA_STATUS_TOTAL_PROGRESS = "TFP";
- public static final String EXTRA_STATUS_CURRENT_PROGRESS = "CFP";
-
- public static final String ACTION_DOWNLOADS_CHANGED = "downloadsChanged";
-
- /**
- * Broadcast intent action sent by the download manager when a download
- * completes.
- */
- public final static String ACTION_DOWNLOAD_COMPLETE = "lvldownloader.intent.action.DOWNLOAD_COMPLETE";
-
- /**
- * Broadcast intent action sent by the download manager when download status
- * changes.
- */
- public final static String ACTION_DOWNLOAD_STATUS = "lvldownloader.intent.action.DOWNLOAD_STATUS";
-
- /*
- * Lists the states that the download manager can set on a download to
- * notify applications of the download progress. The codes follow the HTTP
- * families:<br> 1xx: informational<br> 2xx: success<br> 3xx: redirects (not
- * used by the download manager)<br> 4xx: client errors<br> 5xx: server
- * errors
- */
-
- /**
- * Returns whether the status is informational (i.e. 1xx).
- */
- public static boolean isStatusInformational(int status) {
- return (status >= 100 && status < 200);
- }
-
- /**
- * Returns whether the status is a success (i.e. 2xx).
- */
- public static boolean isStatusSuccess(int status) {
- return (status >= 200 && status < 300);
- }
-
- /**
- * Returns whether the status is an error (i.e. 4xx or 5xx).
- */
- public static boolean isStatusError(int status) {
- return (status >= 400 && status < 600);
- }
-
- /**
- * Returns whether the status is a client error (i.e. 4xx).
- */
- public static boolean isStatusClientError(int status) {
- return (status >= 400 && status < 500);
- }
-
- /**
- * Returns whether the status is a server error (i.e. 5xx).
- */
- public static boolean isStatusServerError(int status) {
- return (status >= 500 && status < 600);
- }
-
- /**
- * Returns whether the download has completed (either with success or
- * error).
- */
- public static boolean isStatusCompleted(int status) {
- return (status >= 200 && status < 300) || (status >= 400 && status < 600);
- }
-
- /**
- * This download hasn't stated yet
- */
- public static final int STATUS_PENDING = 190;
-
- /**
- * This download has started
- */
- public static final int STATUS_RUNNING = 192;
-
- /**
- * This download has been paused by the owning app.
- */
- public static final int STATUS_PAUSED_BY_APP = 193;
-
- /**
- * This download encountered some network error and is waiting before
- * retrying the request.
- */
- public static final int STATUS_WAITING_TO_RETRY = 194;
-
- /**
- * This download is waiting for network connectivity to proceed.
- */
- public static final int STATUS_WAITING_FOR_NETWORK = 195;
-
- /**
- * This download is waiting for a Wi-Fi connection to proceed or for
- * permission to download over cellular.
- */
- public static final int STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION = 196;
-
- /**
- * This download is waiting for a Wi-Fi connection to proceed.
- */
- public static final int STATUS_QUEUED_FOR_WIFI = 197;
-
- /**
- * This download has successfully completed. Warning: there might be other
- * status values that indicate success in the future. Use isSucccess() to
- * capture the entire category.
- *
- * @hide
- */
- public static final int STATUS_SUCCESS = 200;
-
- /**
- * The requested URL is no longer available
- */
- public static final int STATUS_FORBIDDEN = 403;
-
- /**
- * The file was delivered incorrectly
- */
- public static final int STATUS_FILE_DELIVERED_INCORRECTLY = 487;
-
- /**
- * The requested destination file already exists.
- */
- public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
-
- /**
- * Some possibly transient error occurred, but we can't resume the download.
- */
- public static final int STATUS_CANNOT_RESUME = 489;
-
- /**
- * This download was canceled
- *
- * @hide
- */
- public static final int STATUS_CANCELED = 490;
-
- /**
- * This download has completed with an error. Warning: there will be other
- * status values that indicate errors in the future. Use isStatusError() to
- * capture the entire category.
- */
- public static final int STATUS_UNKNOWN_ERROR = 491;
-
- /**
- * This download couldn't be completed because of a storage issue.
- * Typically, that's because the filesystem is missing or full. Use the more
- * specific {@link #STATUS_INSUFFICIENT_SPACE_ERROR} and
- * {@link #STATUS_DEVICE_NOT_FOUND_ERROR} when appropriate.
- *
- * @hide
- */
- public static final int STATUS_FILE_ERROR = 492;
-
- /**
- * This download couldn't be completed because of an HTTP redirect response
- * that the download manager couldn't handle.
- *
- * @hide
- */
- public static final int STATUS_UNHANDLED_REDIRECT = 493;
-
- /**
- * This download couldn't be completed because of an unspecified unhandled
- * HTTP code.
- *
- * @hide
- */
- public static final int STATUS_UNHANDLED_HTTP_CODE = 494;
-
- /**
- * This download couldn't be completed because of an error receiving or
- * processing data at the HTTP level.
- *
- * @hide
- */
- public static final int STATUS_HTTP_DATA_ERROR = 495;
-
- /**
- * This download couldn't be completed because of an HttpException while
- * setting up the request.
- *
- * @hide
- */
- public static final int STATUS_HTTP_EXCEPTION = 496;
-
- /**
- * This download couldn't be completed because there were too many
- * redirects.
- *
- * @hide
- */
- public static final int STATUS_TOO_MANY_REDIRECTS = 497;
-
- /**
- * This download couldn't be completed due to insufficient storage space.
- * Typically, this is because the SD card is full.
- *
- * @hide
- */
- public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
-
- /**
- * This download couldn't be completed because no external storage device
- * was found. Typically, this is because the SD card is not mounted.
- *
- * @hide
- */
- public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
-
- /**
- * This download is allowed to run.
- *
- * @hide
- */
- public static final int CONTROL_RUN = 0;
-
- /**
- * This download must pause at the first opportunity.
- *
- * @hide
- */
- public static final int CONTROL_PAUSED = 1;
-
- /**
- * This download is visible but only shows in the notifications while it's
- * in progress.
- *
- * @hide
- */
- public static final int VISIBILITY_VISIBLE = 0;
-
- /**
- * This download is visible and shows in the notifications while in progress
- * and after completion.
- *
- * @hide
- */
- public static final int VISIBILITY_VISIBLE_NOTIFY_COMPLETED = 1;
-
- /**
- * This download doesn't show in the UI or in the notifications.
- *
- * @hide
- */
- public static final int VISIBILITY_HIDDEN = 2;
-
- /**
- * Bit flag for setAllowedNetworkTypes corresponding to
- * {@link ConnectivityManager#TYPE_MOBILE}.
- */
- public static final int NETWORK_MOBILE = 1 << 0;
-
- /**
- * Bit flag for setAllowedNetworkTypes corresponding to
- * {@link ConnectivityManager#TYPE_WIFI}.
- */
- public static final int NETWORK_WIFI = 1 << 1;
-
- private final static String TEMP_EXT = ".tmp";
-
- /**
- * Service thread status
- */
- private static boolean sIsRunning;
-
- @Override
- public IBinder onBind(Intent paramIntent) {
- Log.d(Constants.TAG, "Service Bound");
- return this.mServiceMessenger.getBinder();
- }
-
- /**
- * Network state.
- */
- private boolean mIsConnected;
- private boolean mIsFailover;
- private boolean mIsCellularConnection;
- private boolean mIsRoaming;
- private boolean mIsAtLeast3G;
- private boolean mIsAtLeast4G;
- private boolean mStateChanged;
-
- /**
- * Download state
- */
- private int mControl;
- private int mStatus;
-
- public boolean isWiFi() {
- return mIsConnected && !mIsCellularConnection;
- }
-
- /**
- * Bindings to important services
- */
- private ConnectivityManager mConnectivityManager;
- private WifiManager mWifiManager;
-
- /**
- * Package we are downloading for (defaults to package of application)
- */
- private PackageInfo mPackageInfo;
-
- /**
- * Byte counts
- */
- long mBytesSoFar;
- long mTotalLength;
- int mFileCount;
-
- /**
- * Used for calculating time remaining and speed
- */
- long mBytesAtSample;
- long mMillisecondsAtSample;
- float mAverageDownloadSpeed;
-
- /**
- * Our binding to the network state broadcasts
- */
- private BroadcastReceiver mConnReceiver;
- final private IStub mServiceStub = DownloaderServiceMarshaller.CreateStub(this);
- final private Messenger mServiceMessenger = mServiceStub.getMessenger();
- private Messenger mClientMessenger;
- private DownloadNotification mNotification;
- private PendingIntent mPendingIntent;
- private PendingIntent mAlarmIntent;
-
- /**
- * Updates the network type based upon the type and subtype returned from
- * the connectivity manager. Subtype is only used for cellular signals.
- *
- * @param type
- * @param subType
- */
- private void updateNetworkType(int type, int subType) {
- switch (type) {
- case ConnectivityManager.TYPE_WIFI:
- case ConnectivityManager.TYPE_ETHERNET:
- case ConnectivityManager.TYPE_BLUETOOTH:
- mIsCellularConnection = false;
- mIsAtLeast3G = false;
- mIsAtLeast4G = false;
- break;
- case ConnectivityManager.TYPE_WIMAX:
- mIsCellularConnection = true;
- mIsAtLeast3G = true;
- mIsAtLeast4G = true;
- break;
- case ConnectivityManager.TYPE_MOBILE:
- mIsCellularConnection = true;
- switch (subType) {
- case TelephonyManager.NETWORK_TYPE_1xRTT:
- case TelephonyManager.NETWORK_TYPE_CDMA:
- case TelephonyManager.NETWORK_TYPE_EDGE:
- case TelephonyManager.NETWORK_TYPE_GPRS:
- case TelephonyManager.NETWORK_TYPE_IDEN:
- mIsAtLeast3G = false;
- mIsAtLeast4G = false;
- break;
- case TelephonyManager.NETWORK_TYPE_HSDPA:
- case TelephonyManager.NETWORK_TYPE_HSUPA:
- case TelephonyManager.NETWORK_TYPE_HSPA:
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
- case TelephonyManager.NETWORK_TYPE_UMTS:
- mIsAtLeast3G = true;
- mIsAtLeast4G = false;
- break;
- case TelephonyManager.NETWORK_TYPE_LTE: // 4G
- case TelephonyManager.NETWORK_TYPE_EHRPD: // 3G ++ interop
- // with 4G
- case TelephonyManager.NETWORK_TYPE_HSPAP: // 3G ++ but
- // marketed as
- // 4G
- mIsAtLeast3G = true;
- mIsAtLeast4G = true;
- break;
- default:
- mIsCellularConnection = false;
- mIsAtLeast3G = false;
- mIsAtLeast4G = false;
- }
- }
- }
-
- private void updateNetworkState(NetworkInfo info) {
- boolean isConnected = mIsConnected;
- boolean isFailover = mIsFailover;
- boolean isCellularConnection = mIsCellularConnection;
- boolean isRoaming = mIsRoaming;
- boolean isAtLeast3G = mIsAtLeast3G;
- if (null != info) {
- mIsRoaming = info.isRoaming();
- mIsFailover = info.isFailover();
- mIsConnected = info.isConnected();
- updateNetworkType(info.getType(), info.getSubtype());
- } else {
- mIsRoaming = false;
- mIsFailover = false;
- mIsConnected = false;
- updateNetworkType(-1, -1);
- }
- mStateChanged = (mStateChanged || isConnected != mIsConnected || isFailover != mIsFailover || isCellularConnection != mIsCellularConnection || isRoaming != mIsRoaming || isAtLeast3G != mIsAtLeast3G);
- if (Constants.LOGVV) {
- if (mStateChanged) {
- Log.v(LOG_TAG, "Network state changed: ");
- Log.v(LOG_TAG, "Starting State: " +
- (isConnected ? "Connected " : "Not Connected ") +
- (isCellularConnection ? "Cellular " : "WiFi ") +
- (isRoaming ? "Roaming " : "Local ") +
- (isAtLeast3G ? "3G+ " : "<3G "));
- Log.v(LOG_TAG, "Ending State: " +
- (mIsConnected ? "Connected " : "Not Connected ") +
- (mIsCellularConnection ? "Cellular " : "WiFi ") +
- (mIsRoaming ? "Roaming " : "Local ") +
- (mIsAtLeast3G ? "3G+ " : "<3G "));
-
- if (isServiceRunning()) {
- if (mIsRoaming) {
- mStatus = STATUS_WAITING_FOR_NETWORK;
- mControl = CONTROL_PAUSED;
- } else if (mIsCellularConnection) {
- DownloadsDB db = DownloadsDB.getDB(this);
- int flags = db.getFlags();
- if (0 == (flags & FLAGS_DOWNLOAD_OVER_CELLULAR)) {
- mStatus = STATUS_QUEUED_FOR_WIFI;
- mControl = CONTROL_PAUSED;
- }
- }
- }
- }
- }
- }
-
- /**
- * Polls the network state, setting the flags appropriately.
- */
- void pollNetworkState() {
- if (null == mConnectivityManager) {
- mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
- }
- if (null == mWifiManager) {
- mWifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- }
- if (mConnectivityManager == null) {
- Log.w(Constants.TAG,
- "couldn't get connectivity manager to poll network state");
- } else {
- @SuppressLint("MissingPermission")
- NetworkInfo activeInfo = mConnectivityManager
- .getActiveNetworkInfo();
- updateNetworkState(activeInfo);
- }
- }
-
- public static final int NO_DOWNLOAD_REQUIRED = 0;
- public static final int LVL_CHECK_REQUIRED = 1;
- public static final int DOWNLOAD_REQUIRED = 2;
-
- public static final String EXTRA_PACKAGE_NAME = "EPN";
- public static final String EXTRA_PENDING_INTENT = "EPI";
- public static final String EXTRA_MESSAGE_HANDLER = "EMH";
-
- /**
- * Returns true if the LVL check is required
- *
- * @param db a downloads DB synchronized with the latest state
- * @param pi the package info for the project
- * @return returns true if the filenames need to be returned
- */
- private static boolean isLVLCheckRequired(DownloadsDB db, PackageInfo pi) {
- // we need to update the LVL check and get a successful status to
- // proceed
- if (db.mVersionCode != pi.versionCode) {
- return true;
- }
- return false;
- }
-
- /**
- * Careful! Only use this internally.
- *
- * @return whether we think the service is running
- */
- private static synchronized boolean isServiceRunning() {
- return sIsRunning;
- }
-
- private static synchronized void setServiceRunning(boolean isRunning) {
- sIsRunning = isRunning;
- }
-
- public static int startDownloadServiceIfRequired(Context context,
- Intent intent, Class<?> serviceClass) throws NameNotFoundException {
- final PendingIntent pendingIntent = (PendingIntent)intent
- .getParcelableExtra(EXTRA_PENDING_INTENT);
- return startDownloadServiceIfRequired(context, pendingIntent,
- serviceClass);
- }
-
- public static int startDownloadServiceIfRequired(Context context,
- PendingIntent pendingIntent, Class<?> serviceClass)
- throws NameNotFoundException {
- String packageName = context.getPackageName();
- String className = serviceClass.getName();
-
- return startDownloadServiceIfRequired(context, pendingIntent,
- packageName, className);
- }
-
- /**
- * Starts the download if necessary. This function starts a flow that does `
- * many things. 1) Checks to see if the APK version has been checked and the
- * metadata database updated 2) If the APK version does not match, checks
- * the new LVL status to see if a new download is required 3) If the APK
- * version does match, then checks to see if the download(s) have been
- * completed 4) If the downloads have been completed, returns
- * NO_DOWNLOAD_REQUIRED The idea is that this can be called during the
- * startup of an application to quickly ascertain if the application needs
- * to wait to hear about any updated APK expansion files. Note that this
- * does mean that the application MUST be run for the first time with a
- * network connection, even if Market delivers all of the files.
- *
- * @param context
- * @param pendingIntent
- * @return true if the app should wait for more guidance from the
- * downloader, false if the app can continue
- * @throws NameNotFoundException
- */
- public static int startDownloadServiceIfRequired(Context context,
- PendingIntent pendingIntent, String classPackage, String className)
- throws NameNotFoundException {
- // first: do we need to do an LVL update?
- // we begin by getting our APK version from the package manager
- final PackageInfo pi = context.getPackageManager().getPackageInfo(
- context.getPackageName(), 0);
-
- int status = NO_DOWNLOAD_REQUIRED;
-
- // the database automatically reads the metadata for version code
- // and download status when the instance is created
- DownloadsDB db = DownloadsDB.getDB(context);
-
- // we need to update the LVL check and get a successful status to
- // proceed
- if (isLVLCheckRequired(db, pi)) {
- status = LVL_CHECK_REQUIRED;
- }
- // we don't have to update LVL. do we still have a download to start?
- if (db.mStatus == 0) {
- DownloadInfo[] infos = db.getDownloads();
- if (null != infos) {
- for (DownloadInfo info : infos) {
- if (!Helpers.doesFileExist(context, info.mFileName, info.mTotalBytes, true)) {
- status = DOWNLOAD_REQUIRED;
- db.updateStatus(-1);
- break;
- }
- }
- }
- } else {
- status = DOWNLOAD_REQUIRED;
- }
- switch (status) {
- case DOWNLOAD_REQUIRED:
- case LVL_CHECK_REQUIRED:
- Intent fileIntent = new Intent();
- fileIntent.setClassName(classPackage, className);
- fileIntent.putExtra(EXTRA_PENDING_INTENT, pendingIntent);
- context.startService(fileIntent);
- break;
- }
- return status;
- }
-
- @Override
- public void requestAbortDownload() {
- mControl = CONTROL_PAUSED;
- mStatus = STATUS_CANCELED;
- }
-
- @Override
- public void requestPauseDownload() {
- mControl = CONTROL_PAUSED;
- mStatus = STATUS_PAUSED_BY_APP;
- }
-
- @Override
- public void setDownloadFlags(int flags) {
- DownloadsDB.getDB(this).updateFlags(flags);
- }
-
- @Override
- public void requestContinueDownload() {
- if (mControl == CONTROL_PAUSED) {
- mControl = CONTROL_RUN;
- }
- Intent fileIntent = new Intent(this, this.getClass());
- fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
- this.startService(fileIntent);
- }
-
- public abstract String getPublicKey();
-
- public abstract byte[] getSALT();
-
- public abstract String getAlarmReceiverClassName();
-
- private class LVLRunnable implements Runnable {
- LVLRunnable(Context context, PendingIntent intent) {
- mContext = context;
- mPendingIntent = intent;
- }
-
- final Context mContext;
-
- @Override
- public void run() {
- setServiceRunning(true);
- mNotification.onDownloadStateChanged(IDownloaderClient.STATE_FETCHING_URL);
- String deviceId = Secure.ANDROID_ID;
-
- final APKExpansionPolicy aep = new APKExpansionPolicy(mContext,
- new AESObfuscator(getSALT(), mContext.getPackageName(), deviceId));
-
- // reset our policy back to the start of the world to force a
- // re-check
- aep.resetPolicy();
-
- // let's try and get the OBB file from LVL first
- // Construct the LicenseChecker with a Policy.
- final LicenseChecker checker = new LicenseChecker(mContext, aep,
- getPublicKey() // Your public licensing key.
- );
- checker.checkAccess(new LicenseCheckerCallback() {
- @Override
- public void allow(int reason) {
- try {
- int count = aep.getExpansionURLCount();
- DownloadsDB db = DownloadsDB.getDB(mContext);
- int status = 0;
- if (count != 0) {
- for (int i = 0; i < count; i++) {
- String currentFileName = aep
- .getExpansionFileName(i);
- if (null != currentFileName) {
- DownloadInfo di = new DownloadInfo(i,
- currentFileName, mContext.getPackageName());
-
- long fileSize = aep.getExpansionFileSize(i);
- if (handleFileUpdated(db, i, currentFileName,
- fileSize)) {
- status |= -1;
- di.resetDownload();
- di.mUri = aep.getExpansionURL(i);
- di.mTotalBytes = fileSize;
- di.mStatus = status;
- db.updateDownload(di);
- } else {
- // we need to read the download
- // information
- // from
- // the database
- DownloadInfo dbdi = db
- .getDownloadInfoByFileName(di.mFileName);
- if (null == dbdi) {
- // the file exists already and is
- // the
- // correct size
- // was delivered by Market or
- // through
- // another mechanism
- Log.d(LOG_TAG, "file " + di.mFileName + " found. Not downloading.");
- di.mStatus = STATUS_SUCCESS;
- di.mTotalBytes = fileSize;
- di.mCurrentBytes = fileSize;
- di.mUri = aep.getExpansionURL(i);
- db.updateDownload(di);
- } else if (dbdi.mStatus != STATUS_SUCCESS) {
- // we just update the URL
- dbdi.mUri = aep.getExpansionURL(i);
- db.updateDownload(dbdi);
- status |= -1;
- }
- }
- }
- }
- }
- // first: do we need to do an LVL update?
- // we begin by getting our APK version from the package
- // manager
- PackageInfo pi;
- try {
- pi = mContext.getPackageManager().getPackageInfo(
- mContext.getPackageName(), 0);
- db.updateMetadata(pi.versionCode, status);
- Class<?> serviceClass = DownloaderService.this.getClass();
- switch (startDownloadServiceIfRequired(mContext, mPendingIntent,
- serviceClass)) {
- case NO_DOWNLOAD_REQUIRED:
- mNotification
- .onDownloadStateChanged(IDownloaderClient.STATE_COMPLETED);
- break;
- case LVL_CHECK_REQUIRED:
- // DANGER WILL ROBINSON!
- Log.e(LOG_TAG, "In LVL checking loop!");
- mNotification
- .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_UNLICENSED);
- throw new RuntimeException(
- "Error with LVL checking and database integrity");
- case DOWNLOAD_REQUIRED:
- // do nothing. the download will notify the
- // application
- // when things are done
- break;
- }
- } catch (NameNotFoundException e1) {
- e1.printStackTrace();
- throw new RuntimeException(
- "Error with getting information from package name");
- }
- } finally {
- setServiceRunning(false);
- }
- }
-
- @Override
- public void dontAllow(int reason) {
- try {
- switch (reason) {
- case Policy.NOT_LICENSED:
- mNotification
- .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_UNLICENSED);
- break;
- case Policy.RETRY:
- mNotification
- .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_FETCHING_URL);
- break;
- }
- } finally {
- setServiceRunning(false);
- }
- }
-
- @Override
- public void applicationError(int errorCode) {
- try {
- mNotification
- .onDownloadStateChanged(IDownloaderClient.STATE_FAILED_FETCHING_URL);
- } finally {
- setServiceRunning(false);
- }
- }
- });
- }
- };
-
- /**
- * Updates the LVL information from the server.
- *
- * @param context
- */
- public void updateLVL(final Context context) {
- Context c = context.getApplicationContext();
- Handler h = new Handler(c.getMainLooper());
- h.post(new LVLRunnable(c, mPendingIntent));
- }
-
- /**
- * The APK has been updated and a filename has been sent down from the
- * Market call. If the file has the same name as the previous file, we do
- * nothing as the file is guaranteed to be the same. If the file does not
- * have the same name, we download it if it hasn't already been delivered by
- * Market.
- *
- * @param index the index of the file from market (0 = main, 1 = patch)
- * @param filename the name of the new file
- * @param fileSize the size of the new file
- * @return
- */
- public boolean handleFileUpdated(DownloadsDB db, int index,
- String filename, long fileSize) {
- DownloadInfo di = db.getDownloadInfoByFileName(filename);
- if (null != di) {
- String oldFile = di.mFileName;
- // cleanup
- if (null != oldFile) {
- if (filename.equals(oldFile)) {
- return false;
- }
-
- // remove partially downloaded file if it is there
- String deleteFile = Helpers.generateSaveFileName(this, oldFile);
- File f = new File(deleteFile);
- if (f.exists())
- f.delete();
- }
- }
- return !Helpers.doesFileExist(this, filename, fileSize, true);
- }
-
- private void scheduleAlarm(long wakeUp) {
- AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
- if (alarms == null) {
- Log.e(Constants.TAG, "couldn't get alarm manager");
- return;
- }
-
- if (Constants.LOGV) {
- Log.v(Constants.TAG, "scheduling retry in " + wakeUp + "ms");
- }
-
- String className = getAlarmReceiverClassName();
- Intent intent = new Intent(Constants.ACTION_RETRY);
- intent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
- intent.setClassName(this.getPackageName(),
- className);
- mAlarmIntent = PendingIntent.getBroadcast(this, 0, intent,
- PendingIntent.FLAG_ONE_SHOT);
- alarms.set(
- AlarmManager.RTC_WAKEUP,
- System.currentTimeMillis() + wakeUp, mAlarmIntent);
- }
-
- private void cancelAlarms() {
- if (null != mAlarmIntent) {
- AlarmManager alarms = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
- if (alarms == null) {
- Log.e(Constants.TAG, "couldn't get alarm manager");
- return;
- }
- alarms.cancel(mAlarmIntent);
- mAlarmIntent = null;
- }
- }
-
- /**
- * We use this to track network state, such as when WiFi, Cellular, etc. is
- * enabled when downloads are paused or in progress.
- */
- private class InnerBroadcastReceiver extends BroadcastReceiver {
- final Service mService;
-
- InnerBroadcastReceiver(Service service) {
- mService = service;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- pollNetworkState();
- if (mStateChanged && !isServiceRunning()) {
- Log.d(Constants.TAG, "InnerBroadcastReceiver Called");
- Intent fileIntent = new Intent(context, mService.getClass());
- fileIntent.putExtra(EXTRA_PENDING_INTENT, mPendingIntent);
- // send a new intent to the service
- context.startService(fileIntent);
- }
- }
- };
-
- /**
- * This is the main thread for the Downloader. This thread is responsible
- * for queuing up downloads and other goodness.
- */
- @Override
- protected void onHandleIntent(Intent intent) {
- setServiceRunning(true);
- try {
- // the database automatically reads the metadata for version code
- // and download status when the instance is created
- DownloadsDB db = DownloadsDB.getDB(this);
- final PendingIntent pendingIntent = (PendingIntent)intent
- .getParcelableExtra(EXTRA_PENDING_INTENT);
-
- if (null != pendingIntent) {
- mNotification.setClientIntent(pendingIntent);
- mPendingIntent = pendingIntent;
- } else if (null != mPendingIntent) {
- mNotification.setClientIntent(mPendingIntent);
- } else {
- Log.e(LOG_TAG, "Downloader started in bad state without notification intent.");
- return;
- }
-
- // when the LVL check completes, a successful response will update
- // the service
- if (isLVLCheckRequired(db, mPackageInfo)) {
- updateLVL(this);
- return;
- }
-
- // get each download
- DownloadInfo[] infos = db.getDownloads();
- mBytesSoFar = 0;
- mTotalLength = 0;
- mFileCount = infos.length;
- for (DownloadInfo info : infos) {
- // We do an (simple) integrity check on each file, just to make
- // sure
- if (info.mStatus == STATUS_SUCCESS) {
- // verify that the file matches the state
- if (!Helpers.doesFileExist(this, info.mFileName, info.mTotalBytes, true)) {
- info.mStatus = 0;
- info.mCurrentBytes = 0;
- }
- }
- // get aggregate data
- mTotalLength += info.mTotalBytes;
- mBytesSoFar += info.mCurrentBytes;
- }
-
- // loop through all downloads and fetch them
- pollNetworkState();
- if (null == mConnReceiver) {
-
- /**
- * We use this to track network state, such as when WiFi,
- * Cellular, etc. is enabled when downloads are paused or in
- * progress.
- */
- mConnReceiver = new InnerBroadcastReceiver(this);
- IntentFilter intentFilter = new IntentFilter(
- ConnectivityManager.CONNECTIVITY_ACTION);
- intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- registerReceiver(mConnReceiver, intentFilter);
- }
-
- for (DownloadInfo info : infos) {
- long startingCount = info.mCurrentBytes;
-
- if (info.mStatus != STATUS_SUCCESS) {
- DownloadThread dt = new DownloadThread(info, this, mNotification);
- cancelAlarms();
- scheduleAlarm(Constants.ACTIVE_THREAD_WATCHDOG);
- dt.run();
- cancelAlarms();
- }
- db.updateFromDb(info);
- boolean setWakeWatchdog = false;
- int notifyStatus;
- switch (info.mStatus) {
- case STATUS_FORBIDDEN:
- // the URL is out of date
- updateLVL(this);
- return;
- case STATUS_SUCCESS:
- mBytesSoFar += info.mCurrentBytes - startingCount;
- db.updateMetadata(mPackageInfo.versionCode, 0);
- continue;
- case STATUS_FILE_DELIVERED_INCORRECTLY:
- // we may be on a network that is returning us a web
- // page on redirect
- notifyStatus = IDownloaderClient.STATE_PAUSED_NETWORK_SETUP_FAILURE;
- info.mCurrentBytes = 0;
- db.updateDownload(info);
- setWakeWatchdog = true;
- break;
- case STATUS_PAUSED_BY_APP:
- notifyStatus = IDownloaderClient.STATE_PAUSED_BY_REQUEST;
- break;
- case STATUS_WAITING_FOR_NETWORK:
- case STATUS_WAITING_TO_RETRY:
- notifyStatus = IDownloaderClient.STATE_PAUSED_NETWORK_UNAVAILABLE;
- setWakeWatchdog = true;
- break;
- case STATUS_QUEUED_FOR_WIFI_OR_CELLULAR_PERMISSION:
- case STATUS_QUEUED_FOR_WIFI:
- // look for more detail here
- if (null != mWifiManager) {
- if (!mWifiManager.isWifiEnabled()) {
- notifyStatus = IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION;
- setWakeWatchdog = true;
- break;
- }
- }
- notifyStatus = IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION;
- setWakeWatchdog = true;
- break;
- case STATUS_CANCELED:
- notifyStatus = IDownloaderClient.STATE_FAILED_CANCELED;
- setWakeWatchdog = true;
- break;
-
- case STATUS_INSUFFICIENT_SPACE_ERROR:
- notifyStatus = IDownloaderClient.STATE_FAILED_SDCARD_FULL;
- setWakeWatchdog = true;
- break;
-
- case STATUS_DEVICE_NOT_FOUND_ERROR:
- notifyStatus = IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE;
- setWakeWatchdog = true;
- break;
-
- default:
- notifyStatus = IDownloaderClient.STATE_FAILED;
- break;
- }
- if (setWakeWatchdog) {
- scheduleAlarm(Constants.WATCHDOG_WAKE_TIMER);
- } else {
- cancelAlarms();
- }
- // failure or pause state
- mNotification.onDownloadStateChanged(notifyStatus);
- return;
- }
-
- // all downloads complete
- mNotification.onDownloadStateChanged(IDownloaderClient.STATE_COMPLETED);
- } finally {
- setServiceRunning(false);
- }
- }
-
- @Override
- public void onDestroy() {
- if (null != mConnReceiver) {
- unregisterReceiver(mConnReceiver);
- mConnReceiver = null;
- }
- mServiceStub.disconnect(this);
- super.onDestroy();
- }
-
- public int getNetworkAvailabilityState(DownloadsDB db) {
- if (mIsConnected) {
- if (!mIsCellularConnection)
- return NETWORK_OK;
- int flags = db.mFlags;
- if (mIsRoaming)
- return NETWORK_CANNOT_USE_ROAMING;
- if (0 != (flags & FLAGS_DOWNLOAD_OVER_CELLULAR)) {
- return NETWORK_OK;
- } else {
- return NETWORK_TYPE_DISALLOWED_BY_REQUESTOR;
- }
- }
- return NETWORK_NO_CONNECTION;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- try {
- mPackageInfo = getPackageManager().getPackageInfo(
- getPackageName(), 0);
- ApplicationInfo ai = getApplicationInfo();
- CharSequence applicationLabel = getPackageManager().getApplicationLabel(ai);
- mNotification = new DownloadNotification(this, applicationLabel);
-
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Exception thrown from methods called by generateSaveFile() for any fatal
- * error.
- */
- public static class GenerateSaveFileError extends Exception {
- private static final long serialVersionUID = 3465966015408936540L;
- int mStatus;
- String mMessage;
-
- public GenerateSaveFileError(int status, String message) {
- mStatus = status;
- mMessage = message;
- }
- }
-
- /**
- * Returns the filename (where the file should be saved) from info about a
- * download
- */
- public String generateTempSaveFileName(String fileName) {
- String path = Helpers.getSaveFilePath(this) + File.separator + fileName + TEMP_EXT;
- return path;
- }
-
- /**
- * Creates a filename (where the file should be saved) from info about a
- * download.
- */
- public String generateSaveFile(String filename, long filesize)
- throws GenerateSaveFileError {
- String path = generateTempSaveFileName(filename);
- File expPath = new File(path);
- if (!Helpers.isExternalMediaMounted()) {
- Log.d(Constants.TAG, "External media not mounted: " + path);
- throw new GenerateSaveFileError(STATUS_DEVICE_NOT_FOUND_ERROR,
- "external media is not yet mounted");
- }
- if (expPath.exists()) {
- Log.d(Constants.TAG, "File already exists: " + path);
- throw new GenerateSaveFileError(STATUS_FILE_ALREADY_EXISTS_ERROR,
- "requested destination file already exists");
- }
- if (Helpers.getAvailableBytes(Helpers.getFilesystemRoot(path)) < filesize) {
- throw new GenerateSaveFileError(STATUS_INSUFFICIENT_SPACE_ERROR,
- "insufficient space on external storage");
- }
- return path;
- }
-
- /**
- * @return a non-localized string appropriate for logging corresponding to
- * one of the NETWORK_* constants.
- */
- public String getLogMessageForNetworkError(int networkError) {
- switch (networkError) {
- case NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE:
- return "download size exceeds recommended limit for mobile network";
-
- case NETWORK_UNUSABLE_DUE_TO_SIZE:
- return "download size exceeds limit for mobile network";
-
- case NETWORK_NO_CONNECTION:
- return "no network connection available";
-
- case NETWORK_CANNOT_USE_ROAMING:
- return "download cannot use the current network connection because it is roaming";
-
- case NETWORK_TYPE_DISALLOWED_BY_REQUESTOR:
- return "download was requested to not use the current network type";
-
- default:
- return "unknown error with network connectivity";
- }
- }
-
- public int getControl() {
- return mControl;
- }
-
- public int getStatus() {
- return mStatus;
- }
-
- /**
- * Calculating a moving average for the speed so we don't get jumpy
- * calculations for time etc.
- */
- static private final float SMOOTHING_FACTOR = 0.005f;
-
- public void notifyUpdateBytes(long totalBytesSoFar) {
- long timeRemaining;
- long currentTime = SystemClock.uptimeMillis();
- if (0 != mMillisecondsAtSample) {
- // we have a sample.
- long timePassed = currentTime - mMillisecondsAtSample;
- long bytesInSample = totalBytesSoFar - mBytesAtSample;
- float currentSpeedSample = (float)bytesInSample / (float)timePassed;
- if (0 != mAverageDownloadSpeed) {
- mAverageDownloadSpeed = SMOOTHING_FACTOR * currentSpeedSample + (1 - SMOOTHING_FACTOR) * mAverageDownloadSpeed;
- } else {
- mAverageDownloadSpeed = currentSpeedSample;
- }
- timeRemaining = (long)((mTotalLength - totalBytesSoFar) / mAverageDownloadSpeed);
- } else {
- timeRemaining = -1;
- }
- mMillisecondsAtSample = currentTime;
- mBytesAtSample = totalBytesSoFar;
- mNotification.onDownloadProgress(
- new DownloadProgressInfo(mTotalLength,
- totalBytesSoFar,
- timeRemaining,
- mAverageDownloadSpeed));
- }
-
- @Override
- protected boolean shouldStop() {
- // the database automatically reads the metadata for version code
- // and download status when the instance is created
- DownloadsDB db = DownloadsDB.getDB(this);
- if (db.mStatus == 0) {
- return true;
- }
- return false;
- }
-
- @Override
- public void requestDownloadStatus() {
- mNotification.resendState();
- }
-
- @Override
- public void onClientUpdated(Messenger clientMessenger) {
- this.mClientMessenger = clientMessenger;
- mNotification.setMessenger(mClientMessenger);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java
deleted file mode 100755
index 5d8dce0bac..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadsDB.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDoneException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteStatement;
-import android.provider.BaseColumns;
-import android.util.Log;
-
-public class DownloadsDB {
- private static final String DATABASE_NAME = "DownloadsDB";
- private static final int DATABASE_VERSION = 7;
- public static final String LOG_TAG = DownloadsDB.class.getName();
- final SQLiteOpenHelper mHelper;
- SQLiteStatement mGetDownloadByIndex;
- SQLiteStatement mUpdateCurrentBytes;
- private static DownloadsDB mDownloadsDB;
- long mMetadataRowID = -1;
- int mVersionCode = -1;
- int mStatus = -1;
- int mFlags;
-
- static public synchronized DownloadsDB getDB(Context paramContext) {
- if (null == mDownloadsDB) {
- return new DownloadsDB(paramContext);
- }
- return mDownloadsDB;
- }
-
- private SQLiteStatement getDownloadByIndexStatement() {
- if (null == mGetDownloadByIndex) {
- mGetDownloadByIndex = mHelper.getReadableDatabase().compileStatement(
- "SELECT " + BaseColumns._ID + " FROM " + DownloadColumns.TABLE_NAME + " WHERE " + DownloadColumns.INDEX + " = ?");
- }
- return mGetDownloadByIndex;
- }
-
- private SQLiteStatement getUpdateCurrentBytesStatement() {
- if (null == mUpdateCurrentBytes) {
- mUpdateCurrentBytes = mHelper.getReadableDatabase().compileStatement(
- "UPDATE " + DownloadColumns.TABLE_NAME + " SET " + DownloadColumns.CURRENTBYTES + " = ?"
- +
- " WHERE " + DownloadColumns.INDEX + " = ?");
- }
- return mUpdateCurrentBytes;
- }
-
- private DownloadsDB(Context paramContext) {
- this.mHelper = new DownloadsContentDBHelper(paramContext);
- final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
- // Query for the version code, the row ID of the metadata (for future
- // updating) the status and the flags
- Cursor cur = sqldb.rawQuery("SELECT " +
- MetadataColumns.APKVERSION + "," +
- BaseColumns._ID + "," +
- MetadataColumns.DOWNLOAD_STATUS + "," +
- MetadataColumns.FLAGS +
- " FROM " + MetadataColumns.TABLE_NAME + " LIMIT 1",
- null);
- if (null != cur && cur.moveToFirst()) {
- mVersionCode = cur.getInt(0);
- mMetadataRowID = cur.getLong(1);
- mStatus = cur.getInt(2);
- mFlags = cur.getInt(3);
- cur.close();
- }
- mDownloadsDB = this;
- }
-
- protected DownloadInfo getDownloadInfoByFileName(String fileName) {
- final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
- Cursor itemcur = null;
- try {
- itemcur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
- DownloadColumns.FILENAME + " = ?",
- new String[] {
- fileName },
- null, null, null);
- if (null != itemcur && itemcur.moveToFirst()) {
- return getDownloadInfoFromCursor(itemcur);
- }
- } finally {
- if (null != itemcur)
- itemcur.close();
- }
- return null;
- }
-
- public long getIDForDownloadInfo(final DownloadInfo di) {
- return getIDByIndex(di.mIndex);
- }
-
- public long getIDByIndex(int index) {
- SQLiteStatement downloadByIndex = getDownloadByIndexStatement();
- downloadByIndex.clearBindings();
- downloadByIndex.bindLong(1, index);
- try {
- return downloadByIndex.simpleQueryForLong();
- } catch (SQLiteDoneException e) {
- return -1;
- }
- }
-
- public void updateDownloadCurrentBytes(final DownloadInfo di) {
- SQLiteStatement downloadCurrentBytes = getUpdateCurrentBytesStatement();
- downloadCurrentBytes.clearBindings();
- downloadCurrentBytes.bindLong(1, di.mCurrentBytes);
- downloadCurrentBytes.bindLong(2, di.mIndex);
- downloadCurrentBytes.execute();
- }
-
- public void close() {
- this.mHelper.close();
- }
-
- protected static class DownloadsContentDBHelper extends SQLiteOpenHelper {
- DownloadsContentDBHelper(Context paramContext) {
- super(paramContext, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- private String createTableQueryFromArray(String paramString,
- String[][] paramArrayOfString) {
- StringBuilder localStringBuilder = new StringBuilder();
- localStringBuilder.append("CREATE TABLE ");
- localStringBuilder.append(paramString);
- localStringBuilder.append(" (");
- int i = paramArrayOfString.length;
- for (int j = 0;; j++) {
- if (j >= i) {
- localStringBuilder
- .setLength(localStringBuilder.length() - 1);
- localStringBuilder.append(");");
- return localStringBuilder.toString();
- }
- String[] arrayOfString = paramArrayOfString[j];
- localStringBuilder.append(' ');
- localStringBuilder.append(arrayOfString[0]);
- localStringBuilder.append(' ');
- localStringBuilder.append(arrayOfString[1]);
- localStringBuilder.append(',');
- }
- }
-
- /**
- * These two arrays must match and have the same order. For every Schema
- * there must be a corresponding table name.
- */
- static final private String[][][] sSchemas = {
- DownloadColumns.SCHEMA, MetadataColumns.SCHEMA
- };
-
- static final private String[] sTables = {
- DownloadColumns.TABLE_NAME, MetadataColumns.TABLE_NAME
- };
-
- /**
- * Goes through all of the tables in sTables and drops each table if it
- * exists. Altered to no longer make use of reflection.
- */
- private void dropTables(SQLiteDatabase paramSQLiteDatabase) {
- for (String table : sTables) {
- try {
- paramSQLiteDatabase.execSQL("DROP TABLE IF EXISTS " + table);
- } catch (Exception localException) {
- localException.printStackTrace();
- }
- }
- }
-
- /**
- * Goes through all of the tables in sTables and creates a database with
- * the corresponding schema described in sSchemas. Altered to no longer
- * make use of reflection.
- */
- public void onCreate(SQLiteDatabase paramSQLiteDatabase) {
- int numSchemas = sSchemas.length;
- for (int i = 0; i < numSchemas; i++) {
- try {
- String[][] schema = (String[][])sSchemas[i];
- paramSQLiteDatabase.execSQL(createTableQueryFromArray(
- sTables[i], schema));
- } catch (Exception localException) {
- while (true)
- localException.printStackTrace();
- }
- }
- }
-
- public void onUpgrade(SQLiteDatabase paramSQLiteDatabase,
- int paramInt1, int paramInt2) {
- Log.w(DownloadsContentDBHelper.class.getName(),
- "Upgrading database from version " + paramInt1 + " to " + paramInt2 + ", which will destroy all old data");
- dropTables(paramSQLiteDatabase);
- onCreate(paramSQLiteDatabase);
- }
- }
-
- public static class MetadataColumns implements BaseColumns {
- public static final String APKVERSION = "APKVERSION";
- public static final String DOWNLOAD_STATUS = "DOWNLOADSTATUS";
- public static final String FLAGS = "DOWNLOADFLAGS";
-
- public static final String[][] SCHEMA = {
- { BaseColumns._ID, "INTEGER PRIMARY KEY" },
- { APKVERSION, "INTEGER" }, { DOWNLOAD_STATUS, "INTEGER" },
- { FLAGS, "INTEGER" }
- };
- public static final String TABLE_NAME = "MetadataColumns";
- public static final String _ID = "MetadataColumns._id";
- }
-
- public static class DownloadColumns implements BaseColumns {
- public static final String INDEX = "FILEIDX";
- public static final String URI = "URI";
- public static final String FILENAME = "FN";
- public static final String ETAG = "ETAG";
-
- public static final String TOTALBYTES = "TOTALBYTES";
- public static final String CURRENTBYTES = "CURRENTBYTES";
- public static final String LASTMOD = "LASTMOD";
-
- public static final String STATUS = "STATUS";
- public static final String CONTROL = "CONTROL";
- public static final String NUM_FAILED = "FAILCOUNT";
- public static final String RETRY_AFTER = "RETRYAFTER";
- public static final String REDIRECT_COUNT = "REDIRECTCOUNT";
-
- public static final String[][] SCHEMA = {
- { BaseColumns._ID, "INTEGER PRIMARY KEY" },
- { INDEX, "INTEGER UNIQUE" }, { URI, "TEXT" },
- { FILENAME, "TEXT UNIQUE" }, { ETAG, "TEXT" },
- { TOTALBYTES, "INTEGER" }, { CURRENTBYTES, "INTEGER" },
- { LASTMOD, "INTEGER" }, { STATUS, "INTEGER" },
- { CONTROL, "INTEGER" }, { NUM_FAILED, "INTEGER" },
- { RETRY_AFTER, "INTEGER" }, { REDIRECT_COUNT, "INTEGER" }
- };
- public static final String TABLE_NAME = "DownloadColumns";
- public static final String _ID = "DownloadColumns._id";
- }
-
- private static final String[] DC_PROJECTION = {
- DownloadColumns.FILENAME,
- DownloadColumns.URI, DownloadColumns.ETAG,
- DownloadColumns.TOTALBYTES, DownloadColumns.CURRENTBYTES,
- DownloadColumns.LASTMOD, DownloadColumns.STATUS,
- DownloadColumns.CONTROL, DownloadColumns.NUM_FAILED,
- DownloadColumns.RETRY_AFTER, DownloadColumns.REDIRECT_COUNT,
- DownloadColumns.INDEX
- };
-
- private static final int FILENAME_IDX = 0;
- private static final int URI_IDX = 1;
- private static final int ETAG_IDX = 2;
- private static final int TOTALBYTES_IDX = 3;
- private static final int CURRENTBYTES_IDX = 4;
- private static final int LASTMOD_IDX = 5;
- private static final int STATUS_IDX = 6;
- private static final int CONTROL_IDX = 7;
- private static final int NUM_FAILED_IDX = 8;
- private static final int RETRY_AFTER_IDX = 9;
- private static final int REDIRECT_COUNT_IDX = 10;
- private static final int INDEX_IDX = 11;
-
- /**
- * This function will add a new file to the database if it does not exist.
- *
- * @param di DownloadInfo that we wish to store
- * @return the row id of the record to be updated/inserted, or -1
- */
- public boolean updateDownload(DownloadInfo di) {
- ContentValues cv = new ContentValues();
- cv.put(DownloadColumns.INDEX, di.mIndex);
- cv.put(DownloadColumns.FILENAME, di.mFileName);
- cv.put(DownloadColumns.URI, di.mUri);
- cv.put(DownloadColumns.ETAG, di.mETag);
- cv.put(DownloadColumns.TOTALBYTES, di.mTotalBytes);
- cv.put(DownloadColumns.CURRENTBYTES, di.mCurrentBytes);
- cv.put(DownloadColumns.LASTMOD, di.mLastMod);
- cv.put(DownloadColumns.STATUS, di.mStatus);
- cv.put(DownloadColumns.CONTROL, di.mControl);
- cv.put(DownloadColumns.NUM_FAILED, di.mNumFailed);
- cv.put(DownloadColumns.RETRY_AFTER, di.mRetryAfter);
- cv.put(DownloadColumns.REDIRECT_COUNT, di.mRedirectCount);
- return updateDownload(di, cv);
- }
-
- public boolean updateDownload(DownloadInfo di, ContentValues cv) {
- long id = di == null ? -1 : getIDForDownloadInfo(di);
- try {
- final SQLiteDatabase sqldb = mHelper.getWritableDatabase();
- if (id != -1) {
- if (1 != sqldb.update(DownloadColumns.TABLE_NAME,
- cv, DownloadColumns._ID + " = " + id, null)) {
- return false;
- }
- } else {
- return -1 != sqldb.insert(DownloadColumns.TABLE_NAME,
- DownloadColumns.URI, cv);
- }
- } catch (android.database.sqlite.SQLiteException ex) {
- ex.printStackTrace();
- }
- return false;
- }
-
- public int getLastCheckedVersionCode() {
- return mVersionCode;
- }
-
- public boolean isDownloadRequired() {
- final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
- Cursor cur = sqldb.rawQuery("SELECT Count(*) FROM " + DownloadColumns.TABLE_NAME + " WHERE " + DownloadColumns.STATUS + " <> 0", null);
- try {
- if (null != cur && cur.moveToFirst()) {
- return 0 == cur.getInt(0);
- }
- } finally {
- if (null != cur)
- cur.close();
- }
- return true;
- }
-
- public int getFlags() {
- return mFlags;
- }
-
- public boolean updateFlags(int flags) {
- if (mFlags != flags) {
- ContentValues cv = new ContentValues();
- cv.put(MetadataColumns.FLAGS, flags);
- if (updateMetadata(cv)) {
- mFlags = flags;
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- };
-
- public boolean updateStatus(int status) {
- if (mStatus != status) {
- ContentValues cv = new ContentValues();
- cv.put(MetadataColumns.DOWNLOAD_STATUS, status);
- if (updateMetadata(cv)) {
- mStatus = status;
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- };
-
- public boolean updateMetadata(ContentValues cv) {
- final SQLiteDatabase sqldb = mHelper.getWritableDatabase();
- if (-1 == this.mMetadataRowID) {
- long newID = sqldb.insert(MetadataColumns.TABLE_NAME,
- MetadataColumns.APKVERSION, cv);
- if (-1 == newID)
- return false;
- mMetadataRowID = newID;
- } else {
- if (0 == sqldb.update(MetadataColumns.TABLE_NAME, cv,
- BaseColumns._ID + " = " + mMetadataRowID, null))
- return false;
- }
- return true;
- }
-
- public boolean updateMetadata(int apkVersion, int downloadStatus) {
- ContentValues cv = new ContentValues();
- cv.put(MetadataColumns.APKVERSION, apkVersion);
- cv.put(MetadataColumns.DOWNLOAD_STATUS, downloadStatus);
- if (updateMetadata(cv)) {
- mVersionCode = apkVersion;
- mStatus = downloadStatus;
- return true;
- } else {
- return false;
- }
- };
-
- public boolean updateFromDb(DownloadInfo di) {
- final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
- Cursor cur = null;
- try {
- cur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION,
- DownloadColumns.FILENAME + "= ?",
- new String[] {
- di.mFileName },
- null, null, null);
- if (null != cur && cur.moveToFirst()) {
- setDownloadInfoFromCursor(di, cur);
- return true;
- }
- return false;
- } finally {
- if (null != cur) {
- cur.close();
- }
- }
- }
-
- public void setDownloadInfoFromCursor(DownloadInfo di, Cursor cur) {
- di.mUri = cur.getString(URI_IDX);
- di.mETag = cur.getString(ETAG_IDX);
- di.mTotalBytes = cur.getLong(TOTALBYTES_IDX);
- di.mCurrentBytes = cur.getLong(CURRENTBYTES_IDX);
- di.mLastMod = cur.getLong(LASTMOD_IDX);
- di.mStatus = cur.getInt(STATUS_IDX);
- di.mControl = cur.getInt(CONTROL_IDX);
- di.mNumFailed = cur.getInt(NUM_FAILED_IDX);
- di.mRetryAfter = cur.getInt(RETRY_AFTER_IDX);
- di.mRedirectCount = cur.getInt(REDIRECT_COUNT_IDX);
- }
-
- public DownloadInfo getDownloadInfoFromCursor(Cursor cur) {
- DownloadInfo di = new DownloadInfo(cur.getInt(INDEX_IDX),
- cur.getString(FILENAME_IDX), this.getClass().getPackage().getName());
- setDownloadInfoFromCursor(di, cur);
- return di;
- }
-
- public DownloadInfo[] getDownloads() {
- final SQLiteDatabase sqldb = mHelper.getReadableDatabase();
- Cursor cur = null;
- try {
- cur = sqldb.query(DownloadColumns.TABLE_NAME, DC_PROJECTION, null,
- null, null, null, null);
- if (null != cur && cur.moveToFirst()) {
- DownloadInfo[] retInfos = new DownloadInfo[cur.getCount()];
- int idx = 0;
- do {
- DownloadInfo di = getDownloadInfoFromCursor(cur);
- retInfos[idx++] = di;
- } while (cur.moveToNext());
- return retInfos;
- }
- return null;
- } finally {
- if (null != cur) {
- cur.close();
- }
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java
deleted file mode 100644
index 02bd1f27f6..0000000000
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/HttpDateTime.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.expansion.downloader.impl;
-
-import android.text.format.Time;
-
-import java.util.Calendar;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper for parsing an HTTP date.
- */
-public final class HttpDateTime {
-
- /*
- * Regular expression for parsing HTTP-date. Wdy, DD Mon YYYY HH:MM:SS GMT
- * RFC 822, updated by RFC 1123 Weekday, DD-Mon-YY HH:MM:SS GMT RFC 850,
- * obsoleted by RFC 1036 Wdy Mon DD HH:MM:SS YYYY ANSI C's asctime() format
- * with following variations Wdy, DD-Mon-YYYY HH:MM:SS GMT Wdy, (SP)D Mon
- * YYYY HH:MM:SS GMT Wdy,DD Mon YYYY HH:MM:SS GMT Wdy, DD-Mon-YY HH:MM:SS
- * GMT Wdy, DD Mon YYYY HH:MM:SS -HHMM Wdy, DD Mon YYYY HH:MM:SS Wdy Mon
- * (SP)D HH:MM:SS YYYY Wdy Mon DD HH:MM:SS YYYY GMT HH can be H if the first
- * digit is zero. Mon can be the full name of the month.
- */
- private static final String HTTP_DATE_RFC_REGEXP =
- "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
- + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
-
- private static final String HTTP_DATE_ANSIC_REGEXP =
- "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
- + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
-
- /**
- * The compiled version of the HTTP-date regular expressions.
- */
- private static final Pattern HTTP_DATE_RFC_PATTERN =
- Pattern.compile(HTTP_DATE_RFC_REGEXP);
- private static final Pattern HTTP_DATE_ANSIC_PATTERN =
- Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
-
- private static class TimeOfDay {
- TimeOfDay(int h, int m, int s) {
- this.hour = h;
- this.minute = m;
- this.second = s;
- }
-
- int hour;
- int minute;
- int second;
- }
-
- public static long parse(String timeString)
- throws IllegalArgumentException {
-
- int date = 1;
- int month = Calendar.JANUARY;
- int year = 1970;
- TimeOfDay timeOfDay;
-
- Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
- if (rfcMatcher.find()) {
- date = getDate(rfcMatcher.group(1));
- month = getMonth(rfcMatcher.group(2));
- year = getYear(rfcMatcher.group(3));
- timeOfDay = getTime(rfcMatcher.group(4));
- } else {
- Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
- if (ansicMatcher.find()) {
- month = getMonth(ansicMatcher.group(1));
- date = getDate(ansicMatcher.group(2));
- timeOfDay = getTime(ansicMatcher.group(3));
- year = getYear(ansicMatcher.group(4));
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- // FIXME: Y2038 BUG!
- if (year >= 2038) {
- year = 2038;
- month = Calendar.JANUARY;
- date = 1;
- }
-
- Time time = new Time(Time.TIMEZONE_UTC);
- time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
- month, year);
- return time.toMillis(false /* use isDst */);
- }
-
- private static int getDate(String dateString) {
- if (dateString.length() == 2) {
- return (dateString.charAt(0) - '0') * 10 + (dateString.charAt(1) - '0');
- } else {
- return (dateString.charAt(0) - '0');
- }
- }
-
- /*
- * jan = 9 + 0 + 13 = 22 feb = 5 + 4 + 1 = 10 mar = 12 + 0 + 17 = 29 apr = 0
- * + 15 + 17 = 32 may = 12 + 0 + 24 = 36 jun = 9 + 20 + 13 = 42 jul = 9 + 20
- * + 11 = 40 aug = 0 + 20 + 6 = 26 sep = 18 + 4 + 15 = 37 oct = 14 + 2 + 19
- * = 35 nov = 13 + 14 + 21 = 48 dec = 3 + 4 + 2 = 9
- */
- private static int getMonth(String monthString) {
- int hash = Character.toLowerCase(monthString.charAt(0)) +
- Character.toLowerCase(monthString.charAt(1)) +
- Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
- switch (hash) {
- case 22:
- return Calendar.JANUARY;
- case 10:
- return Calendar.FEBRUARY;
- case 29:
- return Calendar.MARCH;
- case 32:
- return Calendar.APRIL;
- case 36:
- return Calendar.MAY;
- case 42:
- return Calendar.JUNE;
- case 40:
- return Calendar.JULY;
- case 26:
- return Calendar.AUGUST;
- case 37:
- return Calendar.SEPTEMBER;
- case 35:
- return Calendar.OCTOBER;
- case 48:
- return Calendar.NOVEMBER;
- case 9:
- return Calendar.DECEMBER;
- default:
- throw new IllegalArgumentException();
- }
- }
-
- private static int getYear(String yearString) {
- if (yearString.length() == 2) {
- int year = (yearString.charAt(0) - '0') * 10 + (yearString.charAt(1) - '0');
- if (year >= 70) {
- return year + 1900;
- } else {
- return year + 2000;
- }
- } else if (yearString.length() == 3) {
- // According to RFC 2822, three digit years should be added to 1900.
- int year = (yearString.charAt(0) - '0') * 100 + (yearString.charAt(1) - '0') * 10 + (yearString.charAt(2) - '0');
- return year + 1900;
- } else if (yearString.length() == 4) {
- return (yearString.charAt(0) - '0') * 1000 + (yearString.charAt(1) - '0') * 100 + (yearString.charAt(2) - '0') * 10 + (yearString.charAt(3) - '0');
- } else {
- return 1970;
- }
- }
-
- private static TimeOfDay getTime(String timeString) {
- // HH might be H
- int i = 0;
- int hour = timeString.charAt(i++) - '0';
- if (timeString.charAt(i) != ':')
- hour = hour * 10 + (timeString.charAt(i++) - '0');
- // Skip ':'
- i++;
-
- int minute = (timeString.charAt(i++) - '0') * 10 + (timeString.charAt(i++) - '0');
- // Skip ':'
- i++;
-
- int second = (timeString.charAt(i++) - '0') * 10 + (timeString.charAt(i++) - '0');
-
- return new TimeOfDay(hour, minute, second);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/AESObfuscator.java b/platform/android/java/src/com/google/android/vending/licensing/AESObfuscator.java
deleted file mode 100644
index feba3034c3..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/AESObfuscator.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import com.google.android.vending.licensing.util.Base64;
-import com.google.android.vending.licensing.util.Base64DecoderException;
-
-import java.io.UnsupportedEncodingException;
-import java.security.GeneralSecurityException;
-import java.security.spec.KeySpec;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * An Obfuscator that uses AES to encrypt data.
- */
-public class AESObfuscator implements Obfuscator {
- private static final String UTF8 = "UTF-8";
- private static final String KEYGEN_ALGORITHM = "PBEWITHSHAAND256BITAES-CBC-BC";
- private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
- private static final byte[] IV = { 16, 74, 71, -80, 32, 101, -47, 72, 117, -14, 0, -29, 70, 65, -12, 74 };
- private static final String header = "com.google.android.vending.licensing.AESObfuscator-1|";
-
- private Cipher mEncryptor;
- private Cipher mDecryptor;
-
- /**
- * @param salt an array of random bytes to use for each (un)obfuscation
- * @param applicationId application identifier, e.g. the package name
- * @param deviceId device identifier. Use as many sources as possible to
- * create this unique identifier.
- */
- public AESObfuscator(byte[] salt, String applicationId, String deviceId) {
- try {
- SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM);
- KeySpec keySpec =
- new PBEKeySpec((applicationId + deviceId).toCharArray(), salt, 1024, 256);
- SecretKey tmp = factory.generateSecret(keySpec);
- SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
- mEncryptor = Cipher.getInstance(CIPHER_ALGORITHM);
- mEncryptor.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(IV));
- mDecryptor = Cipher.getInstance(CIPHER_ALGORITHM);
- mDecryptor.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV));
- } catch (GeneralSecurityException e) {
- // This can't happen on a compatible Android device.
- throw new RuntimeException("Invalid environment", e);
- }
- }
-
- public String obfuscate(String original, String key) {
- if (original == null) {
- return null;
- }
- try {
- // Header is appended as an integrity check
- return Base64.encode(mEncryptor.doFinal((header + key + original).getBytes(UTF8)));
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Invalid environment", e);
- } catch (GeneralSecurityException e) {
- throw new RuntimeException("Invalid environment", e);
- }
- }
-
- public String unobfuscate(String obfuscated, String key) throws ValidationException {
- if (obfuscated == null) {
- return null;
- }
- try {
- String result = new String(mDecryptor.doFinal(Base64.decode(obfuscated)), UTF8);
- // Check for presence of header. This serves as a final integrity check, for cases
- // where the block size is correct during decryption.
- int headerIndex = result.indexOf(header + key);
- if (headerIndex != 0) {
- throw new ValidationException("Header not found (invalid data or key)"
- + ":" +
- obfuscated);
- }
- return result.substring(header.length() + key.length(), result.length());
- } catch (Base64DecoderException e) {
- throw new ValidationException(e.getMessage() + ":" + obfuscated);
- } catch (IllegalBlockSizeException e) {
- throw new ValidationException(e.getMessage() + ":" + obfuscated);
- } catch (BadPaddingException e) {
- throw new ValidationException(e.getMessage() + ":" + obfuscated);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Invalid environment", e);
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/APKExpansionPolicy.java b/platform/android/java/src/com/google/android/vending/licensing/APKExpansionPolicy.java
deleted file mode 100644
index 2c60e7e4b8..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/APKExpansionPolicy.java
+++ /dev/null
@@ -1,413 +0,0 @@
-
-package com.google.android.vending.licensing;
-
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import com.google.android.vending.licensing.util.URIQueryDecoder;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
-/**
- * Default policy. All policy decisions are based off of response data received
- * from the licensing service. Specifically, the licensing server sends the
- * following information: response validity period, error retry period,
- * error retry count and a URL for restoring app access in unlicensed cases.
- * <p>
- * These values will vary based on the the way the application is configured in
- * the Google Play publishing console, such as whether the application is
- * marked as free or is within its refund period, as well as how often an
- * application is checking with the licensing service.
- * <p>
- * Developers who need more fine grained control over their application's
- * licensing policy should implement a custom Policy.
- */
-public class APKExpansionPolicy implements Policy {
-
- private static final String TAG = "APKExpansionPolicy";
- private static final String PREFS_FILE = "com.google.android.vending.licensing.APKExpansionPolicy";
- private static final String PREF_LAST_RESPONSE = "lastResponse";
- private static final String PREF_VALIDITY_TIMESTAMP = "validityTimestamp";
- private static final String PREF_RETRY_UNTIL = "retryUntil";
- private static final String PREF_MAX_RETRIES = "maxRetries";
- private static final String PREF_RETRY_COUNT = "retryCount";
- private static final String PREF_LICENSING_URL = "licensingUrl";
- private static final String DEFAULT_VALIDITY_TIMESTAMP = "0";
- private static final String DEFAULT_RETRY_UNTIL = "0";
- private static final String DEFAULT_MAX_RETRIES = "0";
- private static final String DEFAULT_RETRY_COUNT = "0";
-
- private static final long MILLIS_PER_MINUTE = 60 * 1000;
-
- private long mValidityTimestamp;
- private long mRetryUntil;
- private long mMaxRetries;
- private long mRetryCount;
- private long mLastResponseTime = 0;
- private int mLastResponse;
- private String mLicensingUrl;
- private PreferenceObfuscator mPreferences;
- private Vector<String> mExpansionURLs = new Vector<String>();
- private Vector<String> mExpansionFileNames = new Vector<String>();
- private Vector<Long> mExpansionFileSizes = new Vector<Long>();
-
- /**
- * The design of the protocol supports n files. Currently the market can
- * only deliver two files. To accommodate this, we have these two constants,
- * but the order is the only relevant thing here.
- */
- public static final int MAIN_FILE_URL_INDEX = 0;
- public static final int PATCH_FILE_URL_INDEX = 1;
-
- /**
- * @param context The context for the current application
- * @param obfuscator An obfuscator to be used with preferences.
- */
- public APKExpansionPolicy(Context context, Obfuscator obfuscator) {
- // Import old values
- SharedPreferences sp = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);
- mPreferences = new PreferenceObfuscator(sp, obfuscator);
- mLastResponse = Integer.parseInt(
- mPreferences.getString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY)));
- mValidityTimestamp = Long.parseLong(mPreferences.getString(PREF_VALIDITY_TIMESTAMP,
- DEFAULT_VALIDITY_TIMESTAMP));
- mRetryUntil = Long.parseLong(mPreferences.getString(PREF_RETRY_UNTIL, DEFAULT_RETRY_UNTIL));
- mMaxRetries = Long.parseLong(mPreferences.getString(PREF_MAX_RETRIES, DEFAULT_MAX_RETRIES));
- mRetryCount = Long.parseLong(mPreferences.getString(PREF_RETRY_COUNT, DEFAULT_RETRY_COUNT));
- mLicensingUrl = mPreferences.getString(PREF_LICENSING_URL, null);
- }
-
- /**
- * We call this to guarantee that we fetch a fresh policy from the server.
- * This is to be used if the URL is invalid.
- */
- public void resetPolicy() {
- mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY));
- setRetryUntil(DEFAULT_RETRY_UNTIL);
- setMaxRetries(DEFAULT_MAX_RETRIES);
- setRetryCount(Long.parseLong(DEFAULT_RETRY_COUNT));
- setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
- mPreferences.commit();
- }
-
- /**
- * Process a new response from the license server.
- * <p>
- * This data will be used for computing future policy decisions. The
- * following parameters are processed:
- * <ul>
- * <li>VT: the timestamp that the client should consider the response valid
- * until
- * <li>GT: the timestamp that the client should ignore retry errors until
- * <li>GR: the number of retry errors that the client should ignore
- * <li>LU: a deep link URL that can enable access for unlicensed apps (e.g.
- * buy app on the Play Store)
- * </ul>
- *
- * @param response the result from validating the server response
- * @param rawData the raw server response data
- */
- public void processServerResponse(int response,
- com.google.android.vending.licensing.ResponseData rawData) {
-
- // Update retry counter
- if (response != Policy.RETRY) {
- setRetryCount(0);
- } else {
- setRetryCount(mRetryCount + 1);
- }
-
- // Update server policy data
- Map<String, String> extras = decodeExtras(rawData);
- if (response == Policy.LICENSED) {
- mLastResponse = response;
- // Reset the licensing URL since it is only applicable for NOT_LICENSED responses.
- setLicensingUrl(null);
- setValidityTimestamp(Long.toString(System.currentTimeMillis() + MILLIS_PER_MINUTE));
- Set<String> keys = extras.keySet();
- for (String key : keys) {
- if (key.equals("VT")) {
- setValidityTimestamp(extras.get(key));
- } else if (key.equals("GT")) {
- setRetryUntil(extras.get(key));
- } else if (key.equals("GR")) {
- setMaxRetries(extras.get(key));
- } else if (key.startsWith("FILE_URL")) {
- int index = Integer.parseInt(key.substring("FILE_URL".length())) - 1;
- setExpansionURL(index, extras.get(key));
- } else if (key.startsWith("FILE_NAME")) {
- int index = Integer.parseInt(key.substring("FILE_NAME".length())) - 1;
- setExpansionFileName(index, extras.get(key));
- } else if (key.startsWith("FILE_SIZE")) {
- int index = Integer.parseInt(key.substring("FILE_SIZE".length())) - 1;
- setExpansionFileSize(index, Long.parseLong(extras.get(key)));
- }
- }
- } else if (response == Policy.NOT_LICENSED) {
- // Clear out stale retry params
- setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
- setRetryUntil(DEFAULT_RETRY_UNTIL);
- setMaxRetries(DEFAULT_MAX_RETRIES);
- // Update the licensing URL
- setLicensingUrl(extras.get("LU"));
- }
-
- setLastResponse(response);
- mPreferences.commit();
- }
-
- /**
- * Set the last license response received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param l the response
- */
- private void setLastResponse(int l) {
- mLastResponseTime = System.currentTimeMillis();
- mLastResponse = l;
- mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(l));
- }
-
- /**
- * Set the current retry count and add to preferences. You must manually
- * call PreferenceObfuscator.commit() to commit these changes to disk.
- *
- * @param c the new retry count
- */
- private void setRetryCount(long c) {
- mRetryCount = c;
- mPreferences.putString(PREF_RETRY_COUNT, Long.toString(c));
- }
-
- public long getRetryCount() {
- return mRetryCount;
- }
-
- /**
- * Set the last validity timestamp (VT) received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param validityTimestamp the VT string received
- */
- private void setValidityTimestamp(String validityTimestamp) {
- Long lValidityTimestamp;
- try {
- lValidityTimestamp = Long.parseLong(validityTimestamp);
- } catch (NumberFormatException e) {
- // No response or not parseable, expire in one minute.
- Log.w(TAG, "License validity timestamp (VT) missing, caching for a minute");
- lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE;
- validityTimestamp = Long.toString(lValidityTimestamp);
- }
-
- mValidityTimestamp = lValidityTimestamp;
- mPreferences.putString(PREF_VALIDITY_TIMESTAMP, validityTimestamp);
- }
-
- public long getValidityTimestamp() {
- return mValidityTimestamp;
- }
-
- /**
- * Set the retry until timestamp (GT) received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param retryUntil the GT string received
- */
- private void setRetryUntil(String retryUntil) {
- Long lRetryUntil;
- try {
- lRetryUntil = Long.parseLong(retryUntil);
- } catch (NumberFormatException e) {
- // No response or not parseable, expire immediately
- Log.w(TAG, "License retry timestamp (GT) missing, grace period disabled");
- retryUntil = "0";
- lRetryUntil = 0l;
- }
-
- mRetryUntil = lRetryUntil;
- mPreferences.putString(PREF_RETRY_UNTIL, retryUntil);
- }
-
- public long getRetryUntil() {
- return mRetryUntil;
- }
-
- /**
- * Set the max retries value (GR) as received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param maxRetries the GR string received
- */
- private void setMaxRetries(String maxRetries) {
- Long lMaxRetries;
- try {
- lMaxRetries = Long.parseLong(maxRetries);
- } catch (NumberFormatException e) {
- // No response or not parseable, expire immediately
- Log.w(TAG, "Licence retry count (GR) missing, grace period disabled");
- maxRetries = "0";
- lMaxRetries = 0l;
- }
-
- mMaxRetries = lMaxRetries;
- mPreferences.putString(PREF_MAX_RETRIES, maxRetries);
- }
-
- public long getMaxRetries() {
- return mMaxRetries;
- }
-
- /**
- * Set the licensing URL that displays a Play Store UI for the user to regain app access.
- *
- * @param url the LU string received
- */
- private void setLicensingUrl(String url) {
- mLicensingUrl = url;
- mPreferences.putString(PREF_LICENSING_URL, url);
- }
-
- public String getLicensingUrl() {
- return mLicensingUrl;
- }
-
- /**
- * Gets the count of expansion URLs. Since expansionURLs are not committed
- * to preferences, this will return zero if there has been no LVL fetch
- * in the current session.
- *
- * @return the number of expansion URLs. (0,1,2)
- */
- public int getExpansionURLCount() {
- return mExpansionURLs.size();
- }
-
- /**
- * Gets the expansion URL. Since these URLs are not committed to
- * preferences, this will always return null if there has not been an LVL
- * fetch in the current session.
- *
- * @param index the index of the URL to fetch. This value will be either
- * MAIN_FILE_URL_INDEX or PATCH_FILE_URL_INDEX
- */
- public String getExpansionURL(int index) {
- if (index < mExpansionURLs.size()) {
- return mExpansionURLs.elementAt(index);
- }
- return null;
- }
-
- /**
- * Sets the expansion URL. Expansion URL's are not committed to preferences,
- * but are instead intended to be stored when the license response is
- * processed by the front-end.
- *
- * @param index the index of the expansion URL. This value will be either
- * MAIN_FILE_URL_INDEX or PATCH_FILE_URL_INDEX
- * @param URL the URL to set
- */
- public void setExpansionURL(int index, String URL) {
- if (index >= mExpansionURLs.size()) {
- mExpansionURLs.setSize(index + 1);
- }
- mExpansionURLs.set(index, URL);
- }
-
- public String getExpansionFileName(int index) {
- if (index < mExpansionFileNames.size()) {
- return mExpansionFileNames.elementAt(index);
- }
- return null;
- }
-
- public void setExpansionFileName(int index, String name) {
- if (index >= mExpansionFileNames.size()) {
- mExpansionFileNames.setSize(index + 1);
- }
- mExpansionFileNames.set(index, name);
- }
-
- public long getExpansionFileSize(int index) {
- if (index < mExpansionFileSizes.size()) {
- return mExpansionFileSizes.elementAt(index);
- }
- return -1;
- }
-
- public void setExpansionFileSize(int index, long size) {
- if (index >= mExpansionFileSizes.size()) {
- mExpansionFileSizes.setSize(index + 1);
- }
- mExpansionFileSizes.set(index, size);
- }
-
- /**
- * {@inheritDoc} This implementation allows access if either:<br>
- * <ol>
- * <li>a LICENSED response was received within the validity period
- * <li>a RETRY response was received in the last minute, and we are under
- * the RETRY count or in the RETRY period.
- * </ol>
- */
- public boolean allowAccess() {
- long ts = System.currentTimeMillis();
- if (mLastResponse == Policy.LICENSED) {
- // Check if the LICENSED response occurred within the validity
- // timeout.
- if (ts <= mValidityTimestamp) {
- // Cached LICENSED response is still valid.
- return true;
- }
- } else if (mLastResponse == Policy.RETRY &&
- ts < mLastResponseTime + MILLIS_PER_MINUTE) {
- // Only allow access if we are within the retry period or we haven't
- // used up our
- // max retries.
- return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
- }
- return false;
- }
-
- private Map<String, String> decodeExtras(
- com.google.android.vending.licensing.ResponseData rawData) {
- Map<String, String> results = new HashMap<String, String>();
- if (rawData == null) {
- return results;
- }
-
- try {
- URI rawExtras = new URI("?" + rawData.extra);
- URIQueryDecoder.DecodeQuery(rawExtras, results);
- } catch (URISyntaxException e) {
- Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
- }
- return results;
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.java b/platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.java
deleted file mode 100644
index 89edeae1b4..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/ILicenseResultListener.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
-*/
-
-/*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: aidl/ILicenseResultListener.aidl
- */
-package com.google.android.vending.licensing;
-import java.lang.String;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Binder;
-import android.os.Parcel;
-public interface ILicenseResultListener extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.google.android.vending.licensing.ILicenseResultListener {
- private static final java.lang.String DESCRIPTOR = "com.android.vending.licensing.ILicenseResultListener";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an ILicenseResultListener interface,
- * generating a proxy if needed.
- */
- public static com.google.android.vending.licensing.ILicenseResultListener asInterface(android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof com.google.android.vending.licensing.ILicenseResultListener))) {
- return ((com.google.android.vending.licensing.ILicenseResultListener)iin);
- }
- return new com.google.android.vending.licensing.ILicenseResultListener.Stub.Proxy(obj);
- }
- public android.os.IBinder asBinder() {
- return this;
- }
- public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_verifyLicense: {
- data.enforceInterface(DESCRIPTOR);
- int _arg0;
- _arg0 = data.readInt();
- java.lang.String _arg1;
- _arg1 = data.readString();
- java.lang.String _arg2;
- _arg2 = data.readString();
- this.verifyLicense(_arg0, _arg1, _arg2);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.google.android.vending.licensing.ILicenseResultListener {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote) {
- mRemote = remote;
- }
- public android.os.IBinder asBinder() {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
- public void verifyLicense(int responseCode, java.lang.String signedData, java.lang.String signature) throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(responseCode);
- _data.writeString(signedData);
- _data.writeString(signature);
- mRemote.transact(Stub.TRANSACTION_verifyLicense, _data, null, IBinder.FLAG_ONEWAY);
- } finally {
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_verifyLicense = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public void verifyLicense(int responseCode, java.lang.String signedData, java.lang.String signature) throws android.os.RemoteException;
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ILicensingService.java b/platform/android/java/src/com/google/android/vending/licensing/ILicensingService.java
deleted file mode 100644
index 8b7cc83541..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/ILicensingService.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
-*/
-
-/*
- * This file is auto-generated. DO NOT MODIFY.
- * Original file: aidl/ILicensingService.aidl
- */
-package com.google.android.vending.licensing;
-import java.lang.String;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Binder;
-import android.os.Parcel;
-public interface ILicensingService extends android.os.IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements com.google.android.vending.licensing.ILicensingService {
- private static final java.lang.String DESCRIPTOR = "com.android.vending.licensing.ILicensingService";
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an ILicensingService interface,
- * generating a proxy if needed.
- */
- public static com.google.android.vending.licensing.ILicensingService asInterface(android.os.IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof com.google.android.vending.licensing.ILicensingService))) {
- return ((com.google.android.vending.licensing.ILicensingService)iin);
- }
- return new com.google.android.vending.licensing.ILicensingService.Stub.Proxy(obj);
- }
- public android.os.IBinder asBinder() {
- return this;
- }
- public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_checkLicense: {
- data.enforceInterface(DESCRIPTOR);
- long _arg0;
- _arg0 = data.readLong();
- java.lang.String _arg1;
- _arg1 = data.readString();
- com.google.android.vending.licensing.ILicenseResultListener _arg2;
- _arg2 = com.google.android.vending.licensing.ILicenseResultListener.Stub.asInterface(data.readStrongBinder());
- this.checkLicense(_arg0, _arg1, _arg2);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements com.google.android.vending.licensing.ILicensingService {
- private android.os.IBinder mRemote;
- Proxy(android.os.IBinder remote) {
- mRemote = remote;
- }
- public android.os.IBinder asBinder() {
- return mRemote;
- }
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
- public void checkLicense(long nonce, java.lang.String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws android.os.RemoteException {
- android.os.Parcel _data = android.os.Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeLong(nonce);
- _data.writeString(packageName);
- _data.writeStrongBinder((((listener != null)) ? (listener.asBinder()) : (null)));
- mRemote.transact(Stub.TRANSACTION_checkLicense, _data, null, IBinder.FLAG_ONEWAY);
- } finally {
- _data.recycle();
- }
- }
- }
- static final int TRANSACTION_checkLicense = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
- public void checkLicense(long nonce, java.lang.String packageName, com.google.android.vending.licensing.ILicenseResultListener listener) throws android.os.RemoteException;
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/LicenseChecker.java b/platform/android/java/src/com/google/android/vending/licensing/LicenseChecker.java
deleted file mode 100644
index 38aab9f4f5..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/LicenseChecker.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.provider.Settings.Secure;
-import android.util.Log;
-
-import com.google.android.vending.licensing.ILicenseResultListener;
-import com.google.android.vending.licensing.ILicensingService;
-import com.google.android.vending.licensing.util.Base64;
-import com.google.android.vending.licensing.util.Base64DecoderException;
-
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.Set;
-
-/**
- * Client library for Google Play license verifications.
- * <p>
- * The LicenseChecker is configured via a {@link Policy} which contains the logic to determine
- * whether a user should have access to the application. For example, the Policy can define a
- * threshold for allowable number of server or client failures before the library reports the user
- * as not having access.
- * <p>
- * Must also provide the Base64-encoded RSA public key associated with your developer account. The
- * public key is obtainable from the publisher site.
- */
-public class LicenseChecker implements ServiceConnection {
- private static final String TAG = "LicenseChecker";
-
- private static final String KEY_FACTORY_ALGORITHM = "RSA";
-
- // Timeout value (in milliseconds) for calls to service.
- private static final int TIMEOUT_MS = 10 * 1000;
-
- private static final SecureRandom RANDOM = new SecureRandom();
- private static final boolean DEBUG_LICENSE_ERROR = false;
-
- private ILicensingService mService;
-
- private PublicKey mPublicKey;
- private final Context mContext;
- private final Policy mPolicy;
- /**
- * A handler for running tasks on a background thread. We don't want license processing to block
- * the UI thread.
- */
- private Handler mHandler;
- private final String mPackageName;
- private final String mVersionCode;
- private final Set<LicenseValidator> mChecksInProgress = new HashSet<LicenseValidator>();
- private final Queue<LicenseValidator> mPendingChecks = new LinkedList<LicenseValidator>();
-
- /**
- * @param context a Context
- * @param policy implementation of Policy
- * @param encodedPublicKey Base64-encoded RSA public key
- * @throws IllegalArgumentException if encodedPublicKey is invalid
- */
- public LicenseChecker(Context context, Policy policy, String encodedPublicKey) {
- mContext = context;
- mPolicy = policy;
- mPublicKey = generatePublicKey(encodedPublicKey);
- mPackageName = mContext.getPackageName();
- mVersionCode = getVersionCode(context, mPackageName);
- HandlerThread handlerThread = new HandlerThread("background thread");
- handlerThread.start();
- mHandler = new Handler(handlerThread.getLooper());
- }
-
- /**
- * Generates a PublicKey instance from a string containing the Base64-encoded public key.
- *
- * @param encodedPublicKey Base64-encoded public key
- * @throws IllegalArgumentException if encodedPublicKey is invalid
- */
- private static PublicKey generatePublicKey(String encodedPublicKey) {
- try {
- byte[] decodedKey = Base64.decode(encodedPublicKey);
- KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
-
- return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
- } catch (NoSuchAlgorithmException e) {
- // This won't happen in an Android-compatible environment.
- throw new RuntimeException(e);
- } catch (Base64DecoderException e) {
- Log.e(TAG, "Could not decode from Base64.");
- throw new IllegalArgumentException(e);
- } catch (InvalidKeySpecException e) {
- Log.e(TAG, "Invalid key specification.");
- throw new IllegalArgumentException(e);
- }
- }
-
- /**
- * Checks if the user should have access to the app. Binds the service if necessary.
- * <p>
- * NOTE: This call uses a trivially obfuscated string (base64-encoded). For best security, we
- * recommend obfuscating the string that is passed into bindService using another method of your
- * own devising.
- * <p>
- * source string: "com.android.vending.licensing.ILicensingService"
- * <p>
- *
- * @param callback
- */
- public synchronized void checkAccess(LicenseCheckerCallback callback) {
- // If we have a valid recent LICENSED response, we can skip asking
- // Market.
- if (mPolicy.allowAccess()) {
- Log.i(TAG, "Using cached license response");
- callback.allow(Policy.LICENSED);
- } else {
- LicenseValidator validator = new LicenseValidator(mPolicy, new NullDeviceLimiter(),
- callback, generateNonce(), mPackageName, mVersionCode);
-
- if (mService == null) {
- Log.i(TAG, "Binding to licensing service.");
- try {
- boolean bindResult = mContext
- .bindService(
- new Intent(
- new String(
- // Base64 encoded -
- // com.android.vending.licensing.ILicensingService
- // Consider encoding this in another way in your
- // code to improve security
- Base64.decode(
- "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")))
- // As of Android 5.0, implicit
- // Service Intents are no longer
- // allowed because it's not
- // possible for the user to
- // participate in disambiguating
- // them. This does mean we break
- // compatibility with Android
- // Cupcake devices with this
- // release, since setPackage was
- // added in Donut.
- .setPackage(
- new String(
- // Base64
- // encoded -
- // com.android.vending
- Base64.decode(
- "Y29tLmFuZHJvaWQudmVuZGluZw=="))),
- this, // ServiceConnection.
- Context.BIND_AUTO_CREATE);
- if (bindResult) {
- mPendingChecks.offer(validator);
- } else {
- Log.e(TAG, "Could not bind to service.");
- handleServiceConnectionError(validator);
- }
- } catch (SecurityException e) {
- callback.applicationError(LicenseCheckerCallback.ERROR_MISSING_PERMISSION);
- } catch (Base64DecoderException e) {
- e.printStackTrace();
- }
- } else {
- mPendingChecks.offer(validator);
- runChecks();
- }
- }
- }
-
- /**
- * Triggers the last deep link licensing URL returned from the server, which redirects users to a
- * page which enables them to gain access to the app. If no such URL is returned by the server, it
- * will go to the details page of the app in the Play Store.
- */
- public void followLastLicensingUrl(Context context) {
- String licensingUrl = mPolicy.getLicensingUrl();
- if (licensingUrl == null) {
- licensingUrl = "https://play.google.com/store/apps/details?id=" + context.getPackageName();
- }
- Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(licensingUrl));
- context.startActivity(marketIntent);
- }
-
- private void runChecks() {
- LicenseValidator validator;
- while ((validator = mPendingChecks.poll()) != null) {
- try {
- Log.i(TAG, "Calling checkLicense on service for " + validator.getPackageName());
- mService.checkLicense(
- validator.getNonce(), validator.getPackageName(),
- new ResultListener(validator));
- mChecksInProgress.add(validator);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in checkLicense call.", e);
- handleServiceConnectionError(validator);
- }
- }
- }
-
- private synchronized void finishCheck(LicenseValidator validator) {
- mChecksInProgress.remove(validator);
- if (mChecksInProgress.isEmpty()) {
- cleanupService();
- }
- }
-
- private class ResultListener extends ILicenseResultListener.Stub {
- private final LicenseValidator mValidator;
- private Runnable mOnTimeout;
-
- public ResultListener(LicenseValidator validator) {
- mValidator = validator;
- mOnTimeout = new Runnable() {
- public void run() {
- Log.i(TAG, "Check timed out.");
- handleServiceConnectionError(mValidator);
- finishCheck(mValidator);
- }
- };
- startTimeout();
- }
-
- private static final int ERROR_CONTACTING_SERVER = 0x101;
- private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
- private static final int ERROR_NON_MATCHING_UID = 0x103;
-
- // Runs in IPC thread pool. Post it to the Handler, so we can guarantee
- // either this or the timeout runs.
- public void verifyLicense(final int responseCode, final String signedData,
- final String signature) {
- mHandler.post(new Runnable() {
- public void run() {
- Log.i(TAG, "Received response.");
- // Make sure it hasn't already timed out.
- if (mChecksInProgress.contains(mValidator)) {
- clearTimeout();
- mValidator.verify(mPublicKey, responseCode, signedData, signature);
- finishCheck(mValidator);
- }
- if (DEBUG_LICENSE_ERROR) {
- boolean logResponse;
- String stringError = null;
- switch (responseCode) {
- case ERROR_CONTACTING_SERVER:
- logResponse = true;
- stringError = "ERROR_CONTACTING_SERVER";
- break;
- case ERROR_INVALID_PACKAGE_NAME:
- logResponse = true;
- stringError = "ERROR_INVALID_PACKAGE_NAME";
- break;
- case ERROR_NON_MATCHING_UID:
- logResponse = true;
- stringError = "ERROR_NON_MATCHING_UID";
- break;
- default:
- logResponse = false;
- }
-
- if (logResponse) {
- String android_id = Secure.ANDROID_ID;
- Date date = new Date();
- Log.d(TAG, "Server Failure: " + stringError);
- Log.d(TAG, "Android ID: " + android_id);
- Log.d(TAG, "Time: " + date.toGMTString());
- }
- }
- }
- });
- }
-
- private void startTimeout() {
- Log.i(TAG, "Start monitoring timeout.");
- mHandler.postDelayed(mOnTimeout, TIMEOUT_MS);
- }
-
- private void clearTimeout() {
- Log.i(TAG, "Clearing timeout.");
- mHandler.removeCallbacks(mOnTimeout);
- }
- }
-
- public synchronized void onServiceConnected(ComponentName name, IBinder service) {
- mService = ILicensingService.Stub.asInterface(service);
- runChecks();
- }
-
- public synchronized void onServiceDisconnected(ComponentName name) {
- // Called when the connection with the service has been
- // unexpectedly disconnected. That is, Market crashed.
- // If there are any checks in progress, the timeouts will handle them.
- Log.w(TAG, "Service unexpectedly disconnected.");
- mService = null;
- }
-
- /**
- * Generates policy response for service connection errors, as a result of disconnections or
- * timeouts.
- */
- private synchronized void handleServiceConnectionError(LicenseValidator validator) {
- mPolicy.processServerResponse(Policy.RETRY, null);
-
- if (mPolicy.allowAccess()) {
- validator.getCallback().allow(Policy.RETRY);
- } else {
- validator.getCallback().dontAllow(Policy.RETRY);
- }
- }
-
- /** Unbinds service if necessary and removes reference to it. */
- private void cleanupService() {
- if (mService != null) {
- try {
- mContext.unbindService(this);
- } catch (IllegalArgumentException e) {
- // Somehow we've already been unbound. This is a non-fatal
- // error.
- Log.e(TAG, "Unable to unbind from licensing service (already unbound)");
- }
- mService = null;
- }
- }
-
- /**
- * Inform the library that the context is about to be destroyed, so that any open connections
- * can be cleaned up.
- * <p>
- * Failure to call this method can result in a crash under certain circumstances, such as during
- * screen rotation if an Activity requests the license check or when the user exits the
- * application.
- */
- public synchronized void onDestroy() {
- cleanupService();
- mHandler.getLooper().quit();
- }
-
- /** Generates a nonce (number used once). */
- private int generateNonce() {
- return RANDOM.nextInt();
- }
-
- /**
- * Get version code for the application package name.
- *
- * @param context
- * @param packageName application package name
- * @return the version code or empty string if package not found
- */
- private static String getVersionCode(Context context, String packageName) {
- try {
- return String.valueOf(
- context.getPackageManager().getPackageInfo(packageName, 0).versionCode);
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Package not found. could not get version code.");
- return "";
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/LicenseValidator.java b/platform/android/java/src/com/google/android/vending/licensing/LicenseValidator.java
deleted file mode 100644
index 77f7dc7295..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/LicenseValidator.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import com.google.android.vending.licensing.util.Base64;
-import com.google.android.vending.licensing.util.Base64DecoderException;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-
-/**
- * Contains data related to a licensing request and methods to verify
- * and process the response.
- */
-class LicenseValidator {
- private static final String TAG = "LicenseValidator";
-
- // Server response codes.
- private static final int LICENSED = 0x0;
- private static final int NOT_LICENSED = 0x1;
- private static final int LICENSED_OLD_KEY = 0x2;
- private static final int ERROR_NOT_MARKET_MANAGED = 0x3;
- private static final int ERROR_SERVER_FAILURE = 0x4;
- private static final int ERROR_OVER_QUOTA = 0x5;
-
- private static final int ERROR_CONTACTING_SERVER = 0x101;
- private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
- private static final int ERROR_NON_MATCHING_UID = 0x103;
-
- private final Policy mPolicy;
- private final LicenseCheckerCallback mCallback;
- private final int mNonce;
- private final String mPackageName;
- private final String mVersionCode;
- private final DeviceLimiter mDeviceLimiter;
-
- LicenseValidator(Policy policy, DeviceLimiter deviceLimiter, LicenseCheckerCallback callback,
- int nonce, String packageName, String versionCode) {
- mPolicy = policy;
- mDeviceLimiter = deviceLimiter;
- mCallback = callback;
- mNonce = nonce;
- mPackageName = packageName;
- mVersionCode = versionCode;
- }
-
- public LicenseCheckerCallback getCallback() {
- return mCallback;
- }
-
- public int getNonce() {
- return mNonce;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
-
- /**
- * Verifies the response from server and calls appropriate callback method.
- *
- * @param publicKey public key associated with the developer account
- * @param responseCode server response code
- * @param signedData signed data from server
- * @param signature server signature
- */
- public void verify(PublicKey publicKey, int responseCode, String signedData, String signature) {
- String userId = null;
- // Skip signature check for unsuccessful requests
- ResponseData data = null;
- if (responseCode == LICENSED || responseCode == NOT_LICENSED ||
- responseCode == LICENSED_OLD_KEY) {
- // Verify signature.
- try {
- if (TextUtils.isEmpty(signedData)) {
- Log.e(TAG, "Signature verification failed: signedData is empty. "
- +
- "(Device not signed-in to any Google accounts?)");
- handleInvalidResponse();
- return;
- }
-
- Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
- sig.initVerify(publicKey);
- sig.update(signedData.getBytes());
-
- if (!sig.verify(Base64.decode(signature))) {
- Log.e(TAG, "Signature verification failed.");
- handleInvalidResponse();
- return;
- }
- } catch (NoSuchAlgorithmException e) {
- // This can't happen on an Android compatible device.
- throw new RuntimeException(e);
- } catch (InvalidKeyException e) {
- handleApplicationError(LicenseCheckerCallback.ERROR_INVALID_PUBLIC_KEY);
- return;
- } catch (SignatureException e) {
- throw new RuntimeException(e);
- } catch (Base64DecoderException e) {
- Log.e(TAG, "Could not Base64-decode signature.");
- handleInvalidResponse();
- return;
- }
-
- // Parse and validate response.
- try {
- data = ResponseData.parse(signedData);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not parse response.");
- handleInvalidResponse();
- return;
- }
-
- if (data.responseCode != responseCode) {
- Log.e(TAG, "Response codes don't match.");
- handleInvalidResponse();
- return;
- }
-
- if (data.nonce != mNonce) {
- Log.e(TAG, "Nonce doesn't match.");
- handleInvalidResponse();
- return;
- }
-
- if (!data.packageName.equals(mPackageName)) {
- Log.e(TAG, "Package name doesn't match.");
- handleInvalidResponse();
- return;
- }
-
- if (!data.versionCode.equals(mVersionCode)) {
- Log.e(TAG, "Version codes don't match.");
- handleInvalidResponse();
- return;
- }
-
- // Application-specific user identifier.
- userId = data.userId;
- if (TextUtils.isEmpty(userId)) {
- Log.e(TAG, "User identifier is empty.");
- handleInvalidResponse();
- return;
- }
- }
-
- switch (responseCode) {
- case LICENSED:
- case LICENSED_OLD_KEY:
- int limiterResponse = mDeviceLimiter.isDeviceAllowed(userId);
- handleResponse(limiterResponse, data);
- break;
- case NOT_LICENSED:
- handleResponse(Policy.NOT_LICENSED, data);
- break;
- case ERROR_CONTACTING_SERVER:
- Log.w(TAG, "Error contacting licensing server.");
- handleResponse(Policy.RETRY, data);
- break;
- case ERROR_SERVER_FAILURE:
- Log.w(TAG, "An error has occurred on the licensing server.");
- handleResponse(Policy.RETRY, data);
- break;
- case ERROR_OVER_QUOTA:
- Log.w(TAG, "Licensing server is refusing to talk to this device, over quota.");
- handleResponse(Policy.RETRY, data);
- break;
- case ERROR_INVALID_PACKAGE_NAME:
- handleApplicationError(LicenseCheckerCallback.ERROR_INVALID_PACKAGE_NAME);
- break;
- case ERROR_NON_MATCHING_UID:
- handleApplicationError(LicenseCheckerCallback.ERROR_NON_MATCHING_UID);
- break;
- case ERROR_NOT_MARKET_MANAGED:
- handleApplicationError(LicenseCheckerCallback.ERROR_NOT_MARKET_MANAGED);
- break;
- default:
- Log.e(TAG, "Unknown response code for license check.");
- handleInvalidResponse();
- }
- }
-
- /**
- * Confers with policy and calls appropriate callback method.
- *
- * @param response
- * @param rawData
- */
- private void handleResponse(int response, ResponseData rawData) {
- // Update policy data and increment retry counter (if needed)
- mPolicy.processServerResponse(response, rawData);
-
- // Given everything we know, including cached data, ask the policy if we should grant
- // access.
- if (mPolicy.allowAccess()) {
- mCallback.allow(response);
- } else {
- mCallback.dontAllow(response);
- }
- }
-
- private void handleApplicationError(int code) {
- mCallback.applicationError(code);
- }
-
- private void handleInvalidResponse() {
- mCallback.dontAllow(Policy.NOT_LICENSED);
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java b/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
deleted file mode 100644
index 099bb1c48b..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/PreferenceObfuscator.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import android.content.SharedPreferences;
-import android.util.Log;
-
-/**
- * An wrapper for SharedPreferences that transparently performs data obfuscation.
- */
-public class PreferenceObfuscator {
-
- private static final String TAG = "PreferenceObfuscator";
-
- private final SharedPreferences mPreferences;
- private final Obfuscator mObfuscator;
- private SharedPreferences.Editor mEditor;
-
- /**
- * Constructor.
- *
- * @param sp A SharedPreferences instance provided by the system.
- * @param o The Obfuscator to use when reading or writing data.
- */
- public PreferenceObfuscator(SharedPreferences sp, Obfuscator o) {
- mPreferences = sp;
- mObfuscator = o;
- mEditor = null;
- }
-
- public void putString(String key, String value) {
- if (mEditor == null) {
- mEditor = mPreferences.edit();
- mEditor.apply();
- }
- String obfuscatedValue = mObfuscator.obfuscate(value, key);
- mEditor.putString(key, obfuscatedValue);
- }
-
- public String getString(String key, String defValue) {
- String result;
- String value = mPreferences.getString(key, null);
- if (value != null) {
- try {
- result = mObfuscator.unobfuscate(value, key);
- } catch (ValidationException e) {
- // Unable to unobfuscate, data corrupt or tampered
- Log.w(TAG, "Validation error while reading preference: " + key);
- result = defValue;
- }
- } else {
- // Preference not found
- result = defValue;
- }
- return result;
- }
-
- public void commit() {
- if (mEditor != null) {
- mEditor.commit();
- mEditor = null;
- }
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ResponseData.java b/platform/android/java/src/com/google/android/vending/licensing/ResponseData.java
deleted file mode 100644
index 1c802f8e45..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/ResponseData.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import android.text.TextUtils;
-
-import java.util.regex.Pattern;
-
-/**
- * ResponseData from licensing server.
- */
-public class ResponseData {
-
- public int responseCode;
- public int nonce;
- public String packageName;
- public String versionCode;
- public String userId;
- public long timestamp;
- /** Response-specific data. */
- public String extra;
-
- /**
- * Parses response string into ResponseData.
- *
- * @param responseData response data string
- * @throws IllegalArgumentException upon parsing error
- * @return ResponseData object
- */
- public static ResponseData parse(String responseData) {
- // Must parse out main response data and response-specific data.
- int index = responseData.indexOf(':');
- String mainData, extraData;
- if (-1 == index) {
- mainData = responseData;
- extraData = "";
- } else {
- mainData = responseData.substring(0, index);
- extraData = index >= responseData.length() ? "" : responseData.substring(index + 1);
- }
-
- String[] fields = TextUtils.split(mainData, Pattern.quote("|"));
- if (fields.length < 6) {
- throw new IllegalArgumentException("Wrong number of fields.");
- }
-
- ResponseData data = new ResponseData();
- data.extra = extraData;
- data.responseCode = Integer.parseInt(fields[0]);
- data.nonce = Integer.parseInt(fields[1]);
- data.packageName = fields[2];
- data.versionCode = fields[3];
- // Application-specific user identifier.
- data.userId = fields[4];
- data.timestamp = Long.parseLong(fields[5]);
-
- return data;
- }
-
- @Override
- public String toString() {
- return TextUtils.join("|", new Object[] {
- responseCode, nonce, packageName, versionCode,
- userId, timestamp });
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/ServerManagedPolicy.java b/platform/android/java/src/com/google/android/vending/licensing/ServerManagedPolicy.java
deleted file mode 100644
index b9a50c1104..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/ServerManagedPolicy.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-package com.google.android.vending.licensing;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import com.google.android.vending.licensing.util.URIQueryDecoder;
-
-/**
- * Default policy. All policy decisions are based off of response data received
- * from the licensing service. Specifically, the licensing server sends the
- * following information: response validity period, error retry period,
- * error retry count and a URL for restoring app access in unlicensed cases.
- * <p>
- * These values will vary based on the the way the application is configured in
- * the Google Play publishing console, such as whether the application is
- * marked as free or is within its refund period, as well as how often an
- * application is checking with the licensing service.
- * <p>
- * Developers who need more fine grained control over their application's
- * licensing policy should implement a custom Policy.
- */
-public class ServerManagedPolicy implements Policy {
-
- private static final String TAG = "ServerManagedPolicy";
- private static final String PREFS_FILE = "com.google.android.vending.licensing.ServerManagedPolicy";
- private static final String PREF_LAST_RESPONSE = "lastResponse";
- private static final String PREF_VALIDITY_TIMESTAMP = "validityTimestamp";
- private static final String PREF_RETRY_UNTIL = "retryUntil";
- private static final String PREF_MAX_RETRIES = "maxRetries";
- private static final String PREF_RETRY_COUNT = "retryCount";
- private static final String PREF_LICENSING_URL = "licensingUrl";
- private static final String DEFAULT_VALIDITY_TIMESTAMP = "0";
- private static final String DEFAULT_RETRY_UNTIL = "0";
- private static final String DEFAULT_MAX_RETRIES = "0";
- private static final String DEFAULT_RETRY_COUNT = "0";
-
- private static final long MILLIS_PER_MINUTE = 60 * 1000;
-
- private long mValidityTimestamp;
- private long mRetryUntil;
- private long mMaxRetries;
- private long mRetryCount;
- private long mLastResponseTime = 0;
- private int mLastResponse;
- private String mLicensingUrl;
- private PreferenceObfuscator mPreferences;
-
- /**
- * @param context The context for the current application
- * @param obfuscator An obfuscator to be used with preferences.
- */
- public ServerManagedPolicy(Context context, Obfuscator obfuscator) {
- // Import old values
- SharedPreferences sp = context.getSharedPreferences(PREFS_FILE, Context.MODE_PRIVATE);
- mPreferences = new PreferenceObfuscator(sp, obfuscator);
- mLastResponse = Integer.parseInt(
- mPreferences.getString(PREF_LAST_RESPONSE, Integer.toString(Policy.RETRY)));
- mValidityTimestamp = Long.parseLong(mPreferences.getString(PREF_VALIDITY_TIMESTAMP,
- DEFAULT_VALIDITY_TIMESTAMP));
- mRetryUntil = Long.parseLong(mPreferences.getString(PREF_RETRY_UNTIL, DEFAULT_RETRY_UNTIL));
- mMaxRetries = Long.parseLong(mPreferences.getString(PREF_MAX_RETRIES, DEFAULT_MAX_RETRIES));
- mRetryCount = Long.parseLong(mPreferences.getString(PREF_RETRY_COUNT, DEFAULT_RETRY_COUNT));
- mLicensingUrl = mPreferences.getString(PREF_LICENSING_URL, null);
- }
-
- /**
- * Process a new response from the license server.
- * <p>
- * This data will be used for computing future policy decisions. The
- * following parameters are processed:
- * <ul>
- * <li>VT: the timestamp that the client should consider the response valid
- * until
- * <li>GT: the timestamp that the client should ignore retry errors until
- * <li>GR: the number of retry errors that the client should ignore
- * <li>LU: a deep link URL that can enable access for unlicensed apps (e.g.
- * buy app on the Play Store)
- * </ul>
- *
- * @param response the result from validating the server response
- * @param rawData the raw server response data
- */
- public void processServerResponse(int response, ResponseData rawData) {
-
- // Update retry counter
- if (response != Policy.RETRY) {
- setRetryCount(0);
- } else {
- setRetryCount(mRetryCount + 1);
- }
-
- // Update server policy data
- Map<String, String> extras = decodeExtras(rawData);
- if (response == Policy.LICENSED) {
- mLastResponse = response;
- // Reset the licensing URL since it is only applicable for NOT_LICENSED responses.
- setLicensingUrl(null);
- setValidityTimestamp(extras.get("VT"));
- setRetryUntil(extras.get("GT"));
- setMaxRetries(extras.get("GR"));
- } else if (response == Policy.NOT_LICENSED) {
- // Clear out stale retry params
- setValidityTimestamp(DEFAULT_VALIDITY_TIMESTAMP);
- setRetryUntil(DEFAULT_RETRY_UNTIL);
- setMaxRetries(DEFAULT_MAX_RETRIES);
- // Update the licensing URL
- setLicensingUrl(extras.get("LU"));
- }
-
- setLastResponse(response);
- mPreferences.commit();
- }
-
- /**
- * Set the last license response received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param l the response
- */
- private void setLastResponse(int l) {
- mLastResponseTime = System.currentTimeMillis();
- mLastResponse = l;
- mPreferences.putString(PREF_LAST_RESPONSE, Integer.toString(l));
- }
-
- /**
- * Set the current retry count and add to preferences. You must manually
- * call PreferenceObfuscator.commit() to commit these changes to disk.
- *
- * @param c the new retry count
- */
- private void setRetryCount(long c) {
- mRetryCount = c;
- mPreferences.putString(PREF_RETRY_COUNT, Long.toString(c));
- }
-
- public long getRetryCount() {
- return mRetryCount;
- }
-
- /**
- * Set the last validity timestamp (VT) received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param validityTimestamp the VT string received
- */
- private void setValidityTimestamp(String validityTimestamp) {
- Long lValidityTimestamp;
- try {
- lValidityTimestamp = Long.parseLong(validityTimestamp);
- } catch (NumberFormatException e) {
- // No response or not parsable, expire in one minute.
- Log.w(TAG, "License validity timestamp (VT) missing, caching for a minute");
- lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE;
- validityTimestamp = Long.toString(lValidityTimestamp);
- }
-
- mValidityTimestamp = lValidityTimestamp;
- mPreferences.putString(PREF_VALIDITY_TIMESTAMP, validityTimestamp);
- }
-
- public long getValidityTimestamp() {
- return mValidityTimestamp;
- }
-
- /**
- * Set the retry until timestamp (GT) received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param retryUntil the GT string received
- */
- private void setRetryUntil(String retryUntil) {
- Long lRetryUntil;
- try {
- lRetryUntil = Long.parseLong(retryUntil);
- } catch (NumberFormatException e) {
- // No response or not parsable, expire immediately
- Log.w(TAG, "License retry timestamp (GT) missing, grace period disabled");
- retryUntil = "0";
- lRetryUntil = 0l;
- }
-
- mRetryUntil = lRetryUntil;
- mPreferences.putString(PREF_RETRY_UNTIL, retryUntil);
- }
-
- public long getRetryUntil() {
- return mRetryUntil;
- }
-
- /**
- * Set the max retries value (GR) as received from the server and add to
- * preferences. You must manually call PreferenceObfuscator.commit() to
- * commit these changes to disk.
- *
- * @param maxRetries the GR string received
- */
- private void setMaxRetries(String maxRetries) {
- Long lMaxRetries;
- try {
- lMaxRetries = Long.parseLong(maxRetries);
- } catch (NumberFormatException e) {
- // No response or not parsable, expire immediately
- Log.w(TAG, "Licence retry count (GR) missing, grace period disabled");
- maxRetries = "0";
- lMaxRetries = 0l;
- }
-
- mMaxRetries = lMaxRetries;
- mPreferences.putString(PREF_MAX_RETRIES, maxRetries);
- }
-
- public long getMaxRetries() {
- return mMaxRetries;
- }
-
- /**
- * Set the license URL value (LU) as received from the server and add to preferences. You must
- * manually call PreferenceObfuscator.commit() to commit these changes to disk.
- *
- * @param url the LU string received
- */
- private void setLicensingUrl(String url) {
- mLicensingUrl = url;
- mPreferences.putString(PREF_LICENSING_URL, url);
- }
-
- public String getLicensingUrl() {
- return mLicensingUrl;
- }
-
- /**
- * {@inheritDoc}
- *
- * This implementation allows access if either:<br>
- * <ol>
- * <li>a LICENSED response was received within the validity period
- * <li>a RETRY response was received in the last minute, and we are under
- * the RETRY count or in the RETRY period.
- * </ol>
- */
- public boolean allowAccess() {
- long ts = System.currentTimeMillis();
- if (mLastResponse == Policy.LICENSED) {
- // Check if the LICENSED response occurred within the validity timeout.
- if (ts <= mValidityTimestamp) {
- // Cached LICENSED response is still valid.
- return true;
- }
- } else if (mLastResponse == Policy.RETRY &&
- ts < mLastResponseTime + MILLIS_PER_MINUTE) {
- // Only allow access if we are within the retry period or we haven't used up our
- // max retries.
- return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
- }
- return false;
- }
-
- private Map<String, String> decodeExtras(
- com.google.android.vending.licensing.ResponseData rawData) {
- Map<String, String> results = new HashMap<String, String>();
- if (rawData == null) {
- return results;
- }
-
- try {
- URI rawExtras = new URI("?" + rawData.extra);
- URIQueryDecoder.DecodeQuery(rawExtras, results);
- } catch (URISyntaxException e) {
- Log.w(TAG, "Invalid syntax error while decoding extras data from server.");
- }
- return results;
- }
-}
diff --git a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java b/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
deleted file mode 100644
index bd711aadf5..0000000000
--- a/platform/android/java/src/com/google/android/vending/licensing/util/Base64.java
+++ /dev/null
@@ -1,556 +0,0 @@
-// Portions copyright 2002, Google, Inc.
-//
-// 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.
-
-package com.google.android.vending.licensing.util;
-
-// This code was converted from code at http://iharder.sourceforge.net/base64/
-// Lots of extraneous features were removed.
-/* The original code said:
- * <p>
- * I am placing this code in the Public Domain. Do with it as you will.
- * This software comes with no guarantees or warranties but with
- * plenty of well-wishing instead!
- * Please visit
- * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
- * periodically to check for updates or to contribute improvements.
- * </p>
- *
- * @author Robert Harder
- * @author rharder@usa.net
- * @version 1.3
- */
-
-import com.godot.game.BuildConfig;
-
-/**
- * Base64 converter class. This code is not a full-blown MIME encoder;
- * it simply converts binary data to base64 data and back.
- *
- * <p>Note {@link CharBase64} is a GWT-compatible implementation of this
- * class.
- */
-public class Base64 {
- /** Specify encoding (value is {@code true}). */
- public final static boolean ENCODE = true;
-
- /** Specify decoding (value is {@code false}). */
- public final static boolean DECODE = false;
-
- /** The equals sign (=) as a byte. */
- private final static byte EQUALS_SIGN = (byte)'=';
-
- /** The new line character (\n) as a byte. */
- private final static byte NEW_LINE = (byte)'\n';
-
- /**
- * The 64 valid Base64 values.
- */
- private final static byte[] ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F',
- (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K',
- (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P',
- (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
- (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
- (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e',
- (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j',
- (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o',
- (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t',
- (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y',
- (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3',
- (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8',
- (byte)'9', (byte)'+', (byte)'/' };
-
- /**
- * The 64 valid web safe Base64 values.
- */
- private final static byte[] WEBSAFE_ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F',
- (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K',
- (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P',
- (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
- (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
- (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e',
- (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j',
- (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o',
- (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t',
- (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y',
- (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3',
- (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8',
- (byte)'9', (byte)'-', (byte)'_' };
-
- /**
- * Translates a Base64 value to either its 6-bit reconstruction value
- * or a negative number indicating some other meaning.
- **/
- private final static byte[] DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- 62, // Plus sign at decimal 43
- -9, -9, -9, // Decimal 44 - 46
- 63, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
- };
-
- /** The web safe decodabet */
- private final static byte[] WEBSAFE_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
- 62, // Dash '-' sign at decimal 45
- -9, -9, // Decimal 46-47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, // Decimal 91-94
- 63, // Underscore '_' at decimal 95
- -9, // Decimal 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- /* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
- -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
- };
-
- // Indicates white space in encoding
- private final static byte WHITE_SPACE_ENC = -5;
- // Indicates equals sign in encoding
- private final static byte EQUALS_SIGN_ENC = -1;
-
- /** Defeats instantiation. */
- private Base64() {
- }
-
- /* ******** E N C O D I N G M E T H O D S ******** */
-
- /**
- * Encodes up to three bytes of the array <var>source</var>
- * and writes the resulting four Base64 bytes to <var>destination</var>.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * <var>srcOffset</var> and <var>destOffset</var>.
- * This method does not check to make sure your arrays
- * are large enough to accommodate <var>srcOffset</var> + 3 for
- * the <var>source</var> array or <var>destOffset</var> + 4 for
- * the <var>destination</var> array.
- * The actual number of significant bytes in your array is
- * given by <var>numSigBytes</var>.
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param numSigBytes the number of significant bytes in your array
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param alphabet is the encoding alphabet
- * @return the <var>destination</var> array
- * @since 1.3
- */
- private static byte[] encode3to4(byte[] source, int srcOffset,
- int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
- // 1 2 3
- // 01234567890123456789012345678901 Bit position
- // --------000000001111111122222222 Array position from threeBytes
- // --------| || || || | Six bit groups to index alphabet
- // >>18 >>12 >> 6 >> 0 Right shift necessary
- // 0x3f 0x3f 0x3f Additional AND
-
- // Create buffer with zero-padding if there are only one or two
- // significant bytes passed in the array.
- // We have to shift left 24 in order to flush out the 1's that appear
- // when Java treats a value as negative that is cast from a byte to an int.
- int inBuff =
- (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
-
- switch (numSigBytes) {
- case 3:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = alphabet[(inBuff)&0x3f];
- return destination;
- case 2:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
- case 1:
- destination[destOffset] = alphabet[(inBuff >>> 18)];
- destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = EQUALS_SIGN;
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
- default:
- return destination;
- } // end switch
- } // end encode3to4
-
- /**
- * Encodes a byte array into Base64 notation.
- * Equivalent to calling
- * {@code encodeBytes(source, 0, source.length)}
- *
- * @param source The data to convert
- * @since 1.4
- */
- public static String encode(byte[] source) {
- return encode(source, 0, source.length, ALPHABET, true);
- }
-
- /**
- * Encodes a byte array into web safe Base64 notation.
- *
- * @param source The data to convert
- * @param doPadding is {@code true} to pad result with '=' chars
- * if it does not fall on 3 byte boundaries
- */
- public static String encodeWebSafe(byte[] source, boolean doPadding) {
- return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
- }
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param alphabet is the encoding alphabet
- * @param doPadding is {@code true} to pad result with '=' chars
- * if it does not fall on 3 byte boundaries
- * @since 1.4
- */
- public static String encode(byte[] source, int off, int len, byte[] alphabet,
- boolean doPadding) {
- byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
- int outLen = outBuff.length;
-
- // If doPadding is false, set length to truncate '='
- // padding characters
- while (doPadding == false && outLen > 0) {
- if (outBuff[outLen - 1] != '=') {
- break;
- }
- outLen -= 1;
- }
-
- return new String(outBuff, 0, outLen);
- }
-
- /**
- * Encodes a byte array into Base64 notation.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param alphabet is the encoding alphabet
- * @param maxLineLength maximum length of one line.
- * @return the BASE64-encoded byte array
- */
- public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
- int maxLineLength) {
- int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
- int len43 = lenDiv3 * 4;
- byte[] outBuff = new byte[len43 // Main 4:3
- + (len43 / maxLineLength)]; // New lines
-
- int d = 0;
- int e = 0;
- int len2 = len - 2;
- int lineLength = 0;
- for (; d < len2; d += 3, e += 4) {
-
- // The following block of code is the same as
- // encode3to4( source, d + off, 3, outBuff, e, alphabet );
- // but inlined for faster encoding (~20% improvement)
- int inBuff =
- ((source[d + off] << 24) >>> 8) | ((source[d + 1 + off] << 24) >>> 16) | ((source[d + 2 + off] << 24) >>> 24);
- outBuff[e] = alphabet[(inBuff >>> 18)];
- outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
- outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
- outBuff[e + 3] = alphabet[(inBuff)&0x3f];
-
- lineLength += 4;
- if (lineLength == maxLineLength) {
- outBuff[e + 4] = NEW_LINE;
- e++;
- lineLength = 0;
- } // end if: end of line
- } // end for: each piece of array
-
- if (d < len) {
- encode3to4(source, d + off, len - d, outBuff, e, alphabet);
-
- lineLength += 4;
- if (lineLength == maxLineLength) {
- // Add a last newline
- outBuff[e + 4] = NEW_LINE;
- e++;
- }
- e += 4;
- }
-
- if (BuildConfig.DEBUG && e != outBuff.length)
- throw new RuntimeException();
- return outBuff;
- }
-
- /* ******** D E C O D I N G M E T H O D S ******** */
-
- /**
- * Decodes four bytes from array <var>source</var>
- * and writes the resulting bytes (up to three of them)
- * to <var>destination</var>.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * <var>srcOffset</var> and <var>destOffset</var>.
- * This method does not check to make sure your arrays
- * are large enough to accommodate <var>srcOffset</var> + 4 for
- * the <var>source</var> array or <var>destOffset</var> + 3 for
- * the <var>destination</var> array.
- * This method returns the actual number of bytes that
- * were converted from the Base64 encoding.
- *
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param decodabet the decodabet for decoding Base64 content
- * @return the number of decoded bytes converted
- * @since 1.3
- */
- private static int decode4to3(byte[] source, int srcOffset,
- byte[] destination, int destOffset, byte[] decodabet) {
- // Example: Dk==
- if (source[srcOffset + 2] == EQUALS_SIGN) {
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
-
- destination[destOffset] = (byte)(outBuff >>> 16);
- return 1;
- } else if (source[srcOffset + 3] == EQUALS_SIGN) {
- // Example: DkL=
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) | ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
-
- destination[destOffset] = (byte)(outBuff >>> 16);
- destination[destOffset + 1] = (byte)(outBuff >>> 8);
- return 2;
- } else {
- // Example: DkLE
- int outBuff =
- ((decodabet[source[srcOffset]] << 24) >>> 6) | ((decodabet[source[srcOffset + 1]] << 24) >>> 12) | ((decodabet[source[srcOffset + 2]] << 24) >>> 18) | ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
-
- destination[destOffset] = (byte)(outBuff >> 16);
- destination[destOffset + 1] = (byte)(outBuff >> 8);
- destination[destOffset + 2] = (byte)(outBuff);
- return 3;
- }
- } // end decodeToBytes
-
- /**
- * Decodes data from Base64 notation.
- *
- * @param s the string to decode (decoded in default encoding)
- * @return the decoded data
- * @since 1.4
- */
- public static byte[] decode(String s) throws Base64DecoderException {
- byte[] bytes = s.getBytes();
- return decode(bytes, 0, bytes.length);
- }
-
- /**
- * Decodes data from web safe Base64 notation.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param s the string to decode (decoded in default encoding)
- * @return the decoded data
- */
- public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
- byte[] bytes = s.getBytes();
- return decodeWebSafe(bytes, 0, bytes.length);
- }
-
- /**
- * Decodes Base64 content in byte array format and returns
- * the decoded byte array.
- *
- * @param source The Base64 encoded data
- * @return decoded data
- * @since 1.3
- * @throws Base64DecoderException
- */
- public static byte[] decode(byte[] source) throws Base64DecoderException {
- return decode(source, 0, source.length);
- }
-
- /**
- * Decodes web safe Base64 content in byte array format and returns
- * the decoded data.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param source the string to decode (decoded in default encoding)
- * @return the decoded data
- */
- public static byte[] decodeWebSafe(byte[] source)
- throws Base64DecoderException {
- return decodeWebSafe(source, 0, source.length);
- }
-
- /**
- * Decodes Base64 content in byte array format and returns
- * the decoded byte array.
- *
- * @param source The Base64 encoded data
- * @param off The offset of where to begin decoding
- * @param len The length of characters to decode
- * @return decoded data
- * @since 1.3
- * @throws Base64DecoderException
- */
- public static byte[] decode(byte[] source, int off, int len)
- throws Base64DecoderException {
- return decode(source, off, len, DECODABET);
- }
-
- /**
- * Decodes web safe Base64 content in byte array format and returns
- * the decoded byte array.
- * Web safe encoding uses '-' instead of '+', '_' instead of '/'
- *
- * @param source The Base64 encoded data
- * @param off The offset of where to begin decoding
- * @param len The length of characters to decode
- * @return decoded data
- */
- public static byte[] decodeWebSafe(byte[] source, int off, int len)
- throws Base64DecoderException {
- return decode(source, off, len, WEBSAFE_DECODABET);
- }
-
- /**
- * Decodes Base64 content using the supplied decodabet and returns
- * the decoded byte array.
- *
- * @param source The Base64 encoded data
- * @param off The offset of where to begin decoding
- * @param len The length of characters to decode
- * @param decodabet the decodabet for decoding Base64 content
- * @return decoded data
- */
- public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
- throws Base64DecoderException {
- int len34 = len * 3 / 4;
- byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
- int outBuffPosn = 0;
-
- byte[] b4 = new byte[4];
- int b4Posn = 0;
- int i = 0;
- byte sbiCrop = 0;
- byte sbiDecode = 0;
- for (i = 0; i < len; i++) {
- sbiCrop = (byte)(source[i + off] & 0x7f); // Only the low seven bits
- sbiDecode = decodabet[sbiCrop];
-
- if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
- if (sbiDecode >= EQUALS_SIGN_ENC) {
- // An equals sign (for padding) must not occur at position 0 or 1
- // and must be the last byte[s] in the encoded value
- if (sbiCrop == EQUALS_SIGN) {
- int bytesLeft = len - i;
- byte lastByte = (byte)(source[len - 1 + off] & 0x7f);
- if (b4Posn == 0 || b4Posn == 1) {
- throw new Base64DecoderException(
- "invalid padding byte '=' at byte offset " + i);
- } else if ((b4Posn == 3 && bytesLeft > 2) || (b4Posn == 4 && bytesLeft > 1)) {
- throw new Base64DecoderException(
- "padding byte '=' falsely signals end of encoded value "
- + "at offset " + i);
- } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
- throw new Base64DecoderException(
- "encoded value has invalid trailing byte");
- }
- break;
- }
-
- b4[b4Posn++] = sbiCrop;
- if (b4Posn == 4) {
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
- b4Posn = 0;
- }
- }
- } else {
- throw new Base64DecoderException("Bad Base64 input character at " + i + ": " + source[i + off] + "(decimal)");
- }
- }
-
- // Because web safe encoding allows non padding base64 encodes, we
- // need to pad the rest of the b4 buffer with equal signs when
- // b4Posn != 0. There can be at most 2 equal signs at the end of
- // four characters, so the b4 buffer must have two or three
- // characters. This also catches the case where the input is
- // padded with EQUALS_SIGN
- if (b4Posn != 0) {
- if (b4Posn == 1) {
- throw new Base64DecoderException("single trailing character at offset " + (len - 1));
- }
- b4[b4Posn++] = EQUALS_SIGN;
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
- }
-
- byte[] out = new byte[outBuffPosn];
- System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
- return out;
- }
-}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
deleted file mode 100644
index 81c98bcc79..0000000000
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*************************************************************************/
-/* GodotLib.java */
-/*************************************************************************/
-/* 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. */
-/*************************************************************************/
-
-package org.godotengine.godot;
-
-// Wrapper for native library
-
-public class GodotLib {
-
- public static GodotIO io;
-
- static {
- System.loadLibrary("godot_android");
- }
-
- /**
- * @param width the current view width
- * @param height the current view height
- */
-
- public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
- public static native void ondestroy(Godot p_instance);
- public static native void setup(String[] p_cmdline);
- public static native void resize(int width, int height);
- public static native void newcontext(boolean p_32_bits);
- public static native void back();
- public static native void step();
- public static native void touch(int what, int pointer, int howmany, int[] arr);
- public static native void accelerometer(float x, float y, float z);
- public static native void gravity(float x, float y, float z);
- public static native void magnetometer(float x, float y, float z);
- public static native void gyroscope(float x, float y, float z);
- public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
- public static native void joybutton(int p_device, int p_but, boolean p_pressed);
- public static native void joyaxis(int p_device, int p_axis, float p_value);
- public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
- public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
- public static native void focusin();
- public static native void focusout();
- public static native void audio();
- public static native void singleton(String p_name, Object p_object);
- public static native void method(String p_sname, String p_name, String p_ret, String[] p_params);
- public static native String getGlobal(String p_key);
- public static native void callobject(int p_id, String p_method, Object[] p_params);
- public static native void calldeferred(int p_id, String p_method, Object[] p_params);
- public static native void requestPermissionResult(String p_permission, boolean p_result);
-
- public static native void setVirtualKeyboardHeight(int p_height);
-}
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 77f077456e..30676783db 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -644,7 +644,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
godot_java->on_video_init(env);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jobject obj, jobject activity) {
// lets cleanup
if (godot_io_java) {
delete godot_io_java;
@@ -686,20 +686,11 @@ static void _initialize_java_modules() {
print_line("Loading Android module: " + m);
jstring strClassName = env->NewStringUTF(m.utf8().get_data());
jclass singletonClass = (jclass)env->CallObjectMethod(cls, findClass, strClassName);
-
- if (!singletonClass) {
-
- ERR_EXPLAIN("Couldn't find singleton for class: " + m);
- ERR_CONTINUE(!singletonClass);
- }
+ ERR_CONTINUE_MSG(!singletonClass, "Couldn't find singleton for class: " + m + ".");
jmethodID initialize = env->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lorg/godotengine/godot/Godot$SingletonBase;");
+ ERR_CONTINUE_MSG(!initialize, "Couldn't find proper initialize function 'public static Godot.SingletonBase Class::initialize(Activity p_activity)' initializer for singleton class: " + m + ".");
- if (!initialize) {
-
- ERR_EXPLAIN("Couldn't find proper initialize function 'public static Godot.SingletonBase Class::initialize(Activity p_activity)' initializer for singleton class: " + m);
- ERR_CONTINUE(!initialize);
- }
jobject obj = env->CallStaticObjectMethod(singletonClass, initialize, godot_java->get_activity());
env->NewGlobalRef(obj);
}
@@ -1396,3 +1387,21 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResu
AudioDriver::get_singleton()->capture_start();
}
}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz) {
+ if (step == 0)
+ return;
+
+ if (os_android->get_main_loop()) {
+ os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_RESUMED);
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIEnv *env, jclass clazz) {
+ if (step == 0)
+ return;
+
+ if (os_android->get_main_loop()) {
+ os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_PAUSED);
+ }
+}
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index f99935bf7c..11bda94f8d 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -38,7 +38,7 @@
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jobject obj, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits);
@@ -64,6 +64,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jobject p_obj, jstring p_permission, jboolean p_result);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIEnv *env, jclass clazz);
}
#endif /* !JAVA_GODOT_LIB_JNI_H */
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 339b14974c..8194ee6ecf 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -62,6 +62,8 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
+ _vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V");
+ _get_input_fallback_mapping = p_env->GetMethodID(cls, "getInputFallbackMapping", "()Ljava/lang/String;");
}
GodotJavaWrapper::~GodotJavaWrapper() {
@@ -165,6 +167,16 @@ String GodotJavaWrapper::get_clipboard() {
}
}
+String GodotJavaWrapper::get_input_fallback_mapping() {
+ if (_get_input_fallback_mapping) {
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping);
+ return jstring_to_string(fallback_mapping, env);
+ } else {
+ return String();
+ }
+}
+
bool GodotJavaWrapper::has_set_clipboard() {
return _set_clipboard != 0;
}
@@ -211,3 +223,10 @@ bool GodotJavaWrapper::is_activity_resumed() {
return false;
}
}
+
+void GodotJavaWrapper::vibrate(int p_duration_ms) {
+ if (_vibrate) {
+ JNIEnv *env = ThreadAndroid::get_env();
+ env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms);
+ }
+}
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index 82c2a5d122..b1bd9b7f48 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -57,6 +57,8 @@ private:
jmethodID _init_input_devices = 0;
jmethodID _get_surface = 0;
jmethodID _is_activity_resumed = 0;
+ jmethodID _vibrate = 0;
+ jmethodID _get_input_fallback_mapping = 0;
public:
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
@@ -82,6 +84,8 @@ public:
void init_input_devices();
jobject get_surface();
bool is_activity_resumed();
+ void vibrate(int p_duration_ms);
+ String get_input_fallback_mapping();
};
#endif /* !JAVA_GODOT_WRAPPER_H */
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index ebc319e57d..49ab0ea84a 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -71,8 +71,7 @@ const char *OS_Android::get_video_driver_name(int p_driver) const {
case VIDEO_DRIVER_GLES2:
return "GLES2";
}
- ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Invalid video driver index: " + itos(p_driver) + ".");
}
int OS_Android::get_audio_driver_count() const {
@@ -174,7 +173,7 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
AudioDriverManager::initialize(p_audio_driver);
input = memnew(InputDefault);
- input->set_fallback_mapping("Default Android Gamepad");
+ input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
///@TODO implement a subclass for Android and instantiate that instead
camera_server = memnew(CameraServer);
@@ -223,10 +222,7 @@ bool OS_Android::request_permission(const String &p_name) {
Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
return OK;
}
@@ -704,6 +700,10 @@ String OS_Android::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
+void OS_Android::vibrate_handheld(int p_duration_ms) {
+ godot_java->vibrate(p_duration_ms);
+}
+
bool OS_Android::_check_internal_feature_support(const String &p_feature) {
if (p_feature == "mobile") {
//TODO support etc2 only if GLES3 driver is selected
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index e74d4cfd43..a17941f7c0 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -198,6 +198,7 @@ public:
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device) const;
void joy_connection_changed(int p_device, bool p_connected, String p_name);
+ void vibrate_handheld(int p_duration_ms);
virtual bool _check_internal_feature_support(const String &p_feature);
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index 1e1c00ab39..0b6e1f4b4a 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -31,10 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "core/os/thread.h"
#include <jni.h>
#include <pthread.h>
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 64405bfa5b..3f1230faa8 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -37,6 +37,7 @@
#include "os_iphone.h"
#import "GameController/GameController.h"
+#import <AudioToolbox/AudioServices.h>
#define kFilteringFactor 0.1
#define kRenderingFrequency 60
@@ -61,6 +62,10 @@ void _set_keep_screen_on(bool p_enabled) {
[[UIApplication sharedApplication] setIdleTimerDisabled:(BOOL)p_enabled];
};
+void _vibrate() {
+ AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
+};
+
@implementation AppDelegate
@synthesize window;
diff --git a/platform/iphone/camera_ios.mm b/platform/iphone/camera_ios.mm
index 029ce6debf..ff84df66ff 100644
--- a/platform/iphone/camera_ios.mm
+++ b/platform/iphone/camera_ios.mm
@@ -158,7 +158,7 @@
} else if (dataCbCr == NULL) {
print_line("Couldn't access CbCr pixel buffer data");
} else {
- UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
+ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
Ref<Image> img[2];
{
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 85a45d62f8..99fbe989df 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -287,7 +287,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display
- for (unsigned int i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
+ for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), ""));
}
@@ -489,7 +489,7 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
DirAccess *da = DirAccess::open(p_iconset_dir);
ERR_FAIL_COND_V(!da, ERR_CANT_OPEN);
- for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
+ for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
IconInfo info = icon_infos[i];
String icon_path = p_preset->get(info.preset_key);
if (icon_path.length() == 0) {
@@ -539,7 +539,7 @@ Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPre
DirAccess *da = DirAccess::open(p_dest_dir);
ERR_FAIL_COND_V(!da, ERR_CANT_OPEN);
- for (unsigned int i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
+ for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
LoadingScreenInfo info = loading_screen_infos[i];
String loading_screen_file = p_preset->get(info.preset_key);
if (loading_screen_file.size() > 0) {
@@ -626,7 +626,7 @@ private:
static String _hex_pad(uint32_t num) {
Vector<char> ret;
ret.resize(sizeof(num) * 2);
- for (unsigned int i = 0; i < sizeof(num) * 2; ++i) {
+ for (uint64_t i = 0; i < sizeof(num) * 2; ++i) {
uint8_t four_bits = (num >> (sizeof(num) * 8 - (i + 1) * 4)) & 0xF;
ret.write[i] = _hex_char(four_bits);
}
@@ -768,7 +768,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
DirAccess *da = DirAccess::create_for_path(asset);
if (!da) {
memdelete(filesystem_da);
- ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't create directory: " + asset + ".");
}
bool file_exists = da->file_exists(asset);
bool dir_exists = da->dir_exists(asset);
@@ -847,8 +847,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
EditorProgress ep("export", "Exporting for iOS", 5, true);
String team_id = p_preset->get("application/app_store_team_id");
- ERR_EXPLAIN("App Store Team ID not specified - cannot configure the project.");
- ERR_FAIL_COND_V(team_id.length() == 0, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project.");
if (p_debug)
src_pkg_name = p_preset->get("custom_package/debug");
@@ -1170,7 +1169,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
valid = false;
}
- for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
+ for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
IconInfo info = icon_infos[i];
String icon_path = p_preset->get(info.preset_key);
if (icon_path.length() == 0) {
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index f5fce66059..353078c51c 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -64,8 +64,7 @@ const char *OSIPhone::get_video_driver_name(int p_driver) const {
case VIDEO_DRIVER_GLES2:
return "GLES2";
}
- ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Invalid video driver index: " + itos(p_driver) + ".");
};
OSIPhone *OSIPhone::get_singleton() {
@@ -471,6 +470,7 @@ extern void _show_keyboard(String p_existing);
extern void _hide_keyboard();
extern Error _shell_open(String p_uri);
extern void _set_keep_screen_on(bool p_enabled);
+extern void _vibrate();
void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
_show_keyboard(p_existing_text);
@@ -586,6 +586,11 @@ void OSIPhone::native_video_stop() {
_stop_video();
}
+void OSIPhone::vibrate_handheld(int p_duration_ms) {
+ // iOS does not support duration for vibration
+ _vibrate();
+}
+
bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
return p_feature == "mobile";
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index c16c29a858..804ba0b1af 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -195,6 +195,7 @@ public:
virtual void native_video_unpause();
virtual void native_video_focus_out();
virtual void native_video_stop();
+ virtual void vibrate_handheld(int p_duration_ms = 500);
virtual bool _check_internal_feature_support(const String &p_feature);
OSIPhone(int width, int height, String p_data_dir);
diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h
index fc18661f62..68e3bc64fc 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/iphone/view_controller.h
@@ -39,6 +39,10 @@
- (void)didReceiveMemoryWarning;
+- (void)viewDidLoad;
+
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures;
+
- (BOOL)prefersStatusBarHidden;
@end
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index 0358abf9e2..e52ad92bf2 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -83,6 +83,18 @@ int add_cmdline(int p_argc, char **p_args) {
printf("*********** did receive memory warning!\n");
};
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ if (@available(iOS 11.0, *)) {
+ [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
+ }
+}
+
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
+ return UIRectEdgeAll;
+}
+
- (BOOL)shouldAutorotate {
switch (OS::get_singleton()->get_screen_orientation()) {
case OS::SCREEN_SENSOR:
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 163826f828..b359699d3a 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -63,7 +63,7 @@ void AudioDriverJavaScript::mix_to_js() {
void AudioDriverJavaScript::process_capture(float sample) {
int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16);
- input_buffer_write(sample32);
+ capture_buffer_write(sample32);
}
Error AudioDriverJavaScript::init() {
@@ -198,7 +198,7 @@ void AudioDriverJavaScript::finish() {
Error AudioDriverJavaScript::capture_start() {
- input_buffer_init(buffer_length);
+ capture_buffer_init(buffer_length);
/* clang-format off */
EM_ASM({
@@ -245,8 +245,6 @@ Error AudioDriverJavaScript::capture_stop() {
});
/* clang-format on */
- input_buffer.clear();
-
return OK;
}
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 10680ad1f5..a0d6ac9214 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -128,7 +128,6 @@ def configure(env):
## Link flags
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
- env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\''])
# Allow increasing memory buffer size during runtime. This is efficient
# when using WebAssembly (in comparison to asm.js) and works well for
@@ -142,3 +141,6 @@ def configure(env):
# TODO: Reevaluate usage of this setting now that engine.js manages engine runtime.
env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1'])
+
+ #adding flag due to issue with emscripten 1.38.41 callMain method https://github.com/emscripten-core/emscripten/blob/incoming/ChangeLog.md#v13841-08072019
+ env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain"]'])
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index c68b420c61..69dd038709 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -362,12 +362,21 @@ int EditorExportPlatformJavaScript::get_device_count() const {
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
- String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_export.html");
+ String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export");
+ String path = basepath + ".html";
Error err = export_project(p_preset, true, path, p_debug_flags);
- if (err) {
+ if (err != OK) {
+ // Export generates several files, clean them up on failure.
+ DirAccess::remove_file_or_error(basepath + ".html");
+ DirAccess::remove_file_or_error(basepath + ".js");
+ DirAccess::remove_file_or_error(basepath + ".pck");
+ DirAccess::remove_file_or_error(basepath + ".png");
+ DirAccess::remove_file_or_error(basepath + ".wasm");
return err;
}
OS::get_singleton()->shell_open(String("file://") + path);
+ // FIXME: Find out how to clean up export files after running the successfully
+ // exported game. Might not be trivial.
return OK;
}
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index b4bab9a999..e6e933811f 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -68,21 +68,18 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
- ERR_EXPLAIN("Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform");
- ERR_FAIL();
+ ERR_FAIL_MSG("Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");
}
Ref<StreamPeer> HTTPClient::get_connection() const {
- ERR_EXPLAIN("Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform");
- ERR_FAIL_V(REF());
+ ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");
}
Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers) {
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
- ERR_EXPLAIN("HTTP methods TRACE and CONNECT are not supported for the HTML5 platform");
- ERR_FAIL_COND_V(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform.");
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(host.empty(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
@@ -201,8 +198,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
void HTTPClient::set_blocking_mode(bool p_enable) {
- ERR_EXPLAIN("HTTPClient blocking mode is not supported for the HTML5 platform");
- ERR_FAIL_COND(p_enable);
+ ERR_FAIL_COND_MSG(p_enable, "HTTPClient blocking mode is not supported for the HTML5 platform.");
}
bool HTTPClient::is_blocking_mode_enabled() const {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 5363cd4af7..0179bf813d 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -192,9 +192,8 @@ void OS_JavaScript::set_window_fullscreen(bool p_enabled) {
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(NULL, false, &strategy);
- ERR_EXPLAIN("Enabling fullscreen is only possible from an input callback for the HTML5 platform");
- ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED);
- ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS);
+ ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
+ ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
// Not fullscreen yet, so prevent "windowed" canvas dimensions from
// being overwritten.
entering_fullscreen = true;
@@ -582,8 +581,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s
void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
- ERR_EXPLAIN("MOUSE_MODE_CONFINED is not supported for the HTML5 platform");
- ERR_FAIL_COND(p_mode == MOUSE_MODE_CONFINED);
+ ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform.");
if (p_mode == get_mouse_mode())
return;
@@ -602,9 +600,8 @@ void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
} else if (p_mode == MOUSE_MODE_CAPTURED) {
EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false);
- ERR_EXPLAIN("MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback");
- ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED);
- ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS);
+ ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
+ ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
// set_css_cursor must be called before set_cursor_shape to make the cursor visible
set_css_cursor(godot2dom_cursor(cursor_shape));
set_cursor_shape(cursor_shape);
@@ -810,8 +807,7 @@ const char *OS_JavaScript::get_video_driver_name(int p_driver) const {
case VIDEO_DRIVER_GLES2:
return "GLES2";
}
- ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V_MSG(NULL, "Invalid video driver index: " + itos(p_driver) + ".");
}
// Audio
@@ -846,8 +842,7 @@ void OS_JavaScript::set_clipboard(const String &p_text) {
return 0;
}, p_text.utf8().get_data());
/* clang-format on */
- ERR_EXPLAIN("Clipboard API is not supported.");
- ERR_FAIL_COND(err);
+ ERR_FAIL_COND_MSG(err, "Clipboard API is not supported.");
}
String OS_JavaScript::get_clipboard() const {
@@ -1117,20 +1112,17 @@ void OS_JavaScript::finalize() {
Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
- ERR_EXPLAIN("OS::execute() is not available on the HTML5 platform");
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::execute() is not available on the HTML5 platform.");
}
Error OS_JavaScript::kill(const ProcessID &p_pid) {
- ERR_EXPLAIN("OS::kill() is not available on the HTML5 platform");
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::kill() is not available on the HTML5 platform.");
}
int OS_JavaScript::get_process_id() const {
- ERR_EXPLAIN("OS::get_process_id() is not available on the HTML5 platform");
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");
}
extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index e1aa038c61..c5951a570e 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -41,9 +41,6 @@
#include "core/os/dir_access.h"
#include "drivers/unix/dir_access_unix.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class DirAccessOSX : public DirAccessUnix {
protected:
virtual String fix_unicode_name(const char *p_name) const;
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 8cabc45250..94090bcdc1 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "export.h"
+
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "core/io/zip_io.h"
+#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@@ -238,19 +240,23 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
{ "is32", "s8mk", false, 16 } //16x16 24-bit RLE + 8-bit uncompressed mask
};
- for (unsigned int i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
+ for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
copy->convert(Image::FORMAT_RGBA8);
copy->resize(icon_infos[i].size, icon_infos[i].size);
if (icon_infos[i].is_png) {
- //encode png icon
+ // Encode PNG icon.
it->create_from_image(copy);
String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
ResourceSaver::save(path, it);
FileAccess *f = FileAccess::open(path, FileAccess::READ);
- ERR_FAIL_COND(!f);
+ if (!f) {
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(path);
+ ERR_FAIL();
+ }
int ofs = data.size();
uint32_t len = f->get_len();
@@ -261,6 +267,10 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
len = BSWAP32(len);
copymem(&data.write[ofs], icon_infos[i].name, 4);
encode_uint32(len, &data.write[ofs + 4]);
+
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(path);
+
} else {
PoolVector<uint8_t> src_data = copy->get_data();
@@ -561,7 +571,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
}
}
- //bleh?
}
if (data.size() > 0) {
@@ -687,7 +696,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Clean up temporary .app dir
OS::get_singleton()->move_to_trash(tmp_app_path_name);
- } else {
+
+ } else { // pck
String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck");
@@ -747,6 +757,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
zipCloseFileInZip(dst_pkg_zip);
}
}
+
+ // Clean up generated file.
+ DirAccess::remove_file_or_error(pack_path);
}
}
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index a83d5084ed..f1f37e24d2 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -51,9 +51,6 @@
#include <CoreVideo/CoreVideo.h>
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_OSX : public OS_Unix {
public:
@@ -160,6 +157,26 @@ public:
int video_driver_index;
virtual int get_current_video_driver() const;
+ struct GlobalMenuItem {
+ String label;
+ Variant signal;
+ Variant meta;
+
+ GlobalMenuItem() {
+ //NOP
+ }
+
+ GlobalMenuItem(const String &p_label, const Variant &p_signal, const Variant &p_meta) {
+ label = p_label;
+ signal = p_signal;
+ meta = p_meta;
+ }
+ };
+
+ Map<String, Vector<GlobalMenuItem> > global_menus;
+
+ void _update_global_menu();
+
protected:
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -171,6 +188,11 @@ protected:
public:
static OS_OSX *singleton;
+ void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
+ void global_menu_add_separator(const String &p_menu);
+ void global_menu_remove_item(const String &p_menu, int p_idx);
+ void global_menu_clear(const String &p_menu);
+
void wm_minimized(bool p_minimized);
virtual String get_name() const;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 726882438b..f48d4a307d 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -204,11 +204,53 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
}
}
+- (void)globalMenuCallback:(id)sender {
+
+ if (![sender representedObject])
+ return;
+
+ OS_OSX::GlobalMenuItem *item = (OS_OSX::GlobalMenuItem *)[[sender representedObject] pointerValue];
+
+ if (!item)
+ return;
+
+ OS_OSX::singleton->main_loop->global_menu_action(item->signal, item->meta);
+}
+
+- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
+
+ NSMenu *menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
+
+ Vector<OS_OSX::GlobalMenuItem> &E = OS_OSX::singleton->global_menus["_dock"];
+ for (int i = 0; i < E.size(); i++) {
+ if (E[i].label == String()) {
+ [menu addItem:[NSMenuItem separatorItem]];
+ } else {
+ NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:E[i].label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""];
+ [menu_item setRepresentedObject:[NSValue valueWithPointer:&(E[i])]];
+ }
+ }
+
+ return menu;
+}
+
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
- // Note: called before main loop init!
+ // Note: may be called called before main loop init!
char *utfs = strdup([filename UTF8String]);
OS_OSX::singleton->open_with_filename.parse_utf8(utfs);
free(utfs);
+
+#ifdef TOOLS_ENABLED
+ // Open new instance
+ if (OS_OSX::singleton->get_main_loop()) {
+ List<String> args;
+ args.push_back(OS_OSX::singleton->open_with_filename);
+ String exec = OS::get_singleton()->get_executable_path();
+
+ OS::ProcessID pid = 0;
+ OS::get_singleton()->execute(exec, args, false, &pid);
+ }
+#endif
return YES;
}
@@ -1266,6 +1308,56 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) {
@end
+void OS_OSX::_update_global_menu() {
+
+ NSMenu *main_menu = [NSApp mainMenu];
+
+ for (int i = 1; i < [main_menu numberOfItems]; i++) {
+ [main_menu removeItemAtIndex:i];
+ }
+ for (Map<String, Vector<GlobalMenuItem> >::Element *E = global_menus.front(); E; E = E->next()) {
+ if (E->key() != "_dock") {
+ NSMenu *menu = [[[NSMenu alloc] initWithTitle:[NSString stringWithUTF8String:E->key().utf8().get_data()]] autorelease];
+ for (int i = 0; i < E->get().size(); i++) {
+ if (E->get()[i].label == String()) {
+ [menu addItem:[NSMenuItem separatorItem]];
+ } else {
+ NSMenuItem *menu_item = [menu addItemWithTitle:[NSString stringWithUTF8String:E->get()[i].label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:@""];
+ [menu_item setRepresentedObject:[NSValue valueWithPointer:&(E->get()[i])]];
+ }
+ }
+ NSMenuItem *menu_item = [main_menu addItemWithTitle:[NSString stringWithUTF8String:E->key().utf8().get_data()] action:nil keyEquivalent:@""];
+ [main_menu setSubmenu:menu forItem:menu_item];
+ }
+ }
+}
+
+void OS_OSX::global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta) {
+
+ global_menus[p_menu].push_back(GlobalMenuItem(p_label, p_signal, p_meta));
+ _update_global_menu();
+}
+
+void OS_OSX::global_menu_add_separator(const String &p_menu) {
+
+ global_menus[p_menu].push_back(GlobalMenuItem());
+ _update_global_menu();
+}
+
+void OS_OSX::global_menu_remove_item(const String &p_menu, int p_idx) {
+
+ ERR_FAIL_INDEX(p_idx, global_menus[p_menu].size());
+
+ global_menus[p_menu].remove(p_idx);
+ _update_global_menu();
+}
+
+void OS_OSX::global_menu_clear(const String &p_menu) {
+
+ global_menus[p_menu].clear();
+ _update_global_menu();
+}
+
Point2 OS_OSX::get_ime_selection() const {
return im_selection;
@@ -1599,6 +1691,7 @@ void OS_OSX::finalize() {
memdelete(joypad_osx);
memdelete(input);
+ cursors_cache.clear();
visual_server->finish();
memdelete(visual_server);
//memdelete(rasterizer);
@@ -1718,10 +1811,7 @@ Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle,
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror());
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
return OK;
}
@@ -1961,15 +2051,10 @@ void OS_OSX::set_native_icon(const String &p_filename) {
memdelete(f);
NSData *icon_data = [[[NSData alloc] initWithBytes:&data.write[0] length:len] autorelease];
- if (!icon_data) {
- ERR_EXPLAIN("Error reading icon data");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!icon_data, "Error reading icon data.");
+
NSImage *icon = [[[NSImage alloc] initWithData:icon_data] autorelease];
- if (!icon) {
- ERR_EXPLAIN("Error loading icon");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!icon, "Error loading icon.");
[NSApp setApplicationIconImage:icon];
}
@@ -2410,7 +2495,7 @@ Size2 OS_OSX::get_min_window_size() const {
void OS_OSX::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -2426,7 +2511,7 @@ void OS_OSX::set_min_window_size(const Size2 p_size) {
void OS_OSX::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 185dce8128..b6028c20e3 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -35,6 +35,7 @@ def get_opts():
BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False),
BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False),
BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False),
+ BoolVariable('use_tsan', 'Use LLVM/GCC compiler thread sanitizer (TSAN))', False),
EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
BoolVariable('execinfo', 'Use libexecinfo on systems where glibc is not available', False),
@@ -99,7 +100,7 @@ def configure(env):
env.extra_suffix = ".llvm" + env.extra_suffix
- if env['use_ubsan'] or env['use_asan'] or env['use_lsan']:
+ if env['use_ubsan'] or env['use_asan'] or env['use_lsan'] or env['use_tsan']:
env.extra_suffix += "s"
if env['use_ubsan']:
@@ -114,6 +115,10 @@ def configure(env):
env.Append(CCFLAGS=['-fsanitize=leak'])
env.Append(LINKFLAGS=['-fsanitize=leak'])
+ if env['use_tsan']:
+ env.Append(CCFLAGS=['-fsanitize=thread'])
+ env.Append(LINKFLAGS=['-fsanitize=thread'])
+
if env['use_lto']:
env.Append(CCFLAGS=['-flto'])
if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
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..b8119288ff 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -47,9 +47,6 @@
#include "servers/visual_server.h"
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_Server : public OS_Unix {
@@ -74,6 +71,7 @@ class OS_Server : public OS_Unix {
#endif
CrashHandler crash_handler;
+ CameraServer *camera_server;
int video_driver_index;
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index abb7b391d3..bb18c2da8a 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -30,10 +30,11 @@
#include "export.h"
#include "core/bind/core_bind.h"
+#include "core/crypto/crypto_core.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/dir_access.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/version.h"
@@ -133,8 +134,6 @@ class AppxPackager {
String progress_task;
FileAccess *package;
- String tmp_blockmap_file_path;
- String tmp_content_types_file_path;
Set<String> mime_types;
@@ -146,8 +145,8 @@ class AppxPackager {
String hash_block(const uint8_t *p_block_data, size_t p_block_len);
- void make_block_map();
- void make_content_types();
+ void make_block_map(const String &p_path);
+ void make_content_types(const String &p_path);
_FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) {
for (int i = 0; i < 2; i++) {
@@ -208,9 +207,9 @@ String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len)
return String(base64);
}
-void AppxPackager::make_block_map() {
+void AppxPackager::make_block_map(const String &p_path) {
- FileAccess *tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">");
@@ -253,9 +252,9 @@ String AppxPackager::content_type(String p_extension) {
return "application/octet-stream";
}
-void AppxPackager::make_content_types() {
+void AppxPackager::make_content_types(const String &p_path) {
- FileAccess *tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
@@ -458,8 +457,6 @@ void AppxPackager::init(FileAccess *p_fa) {
package = p_fa;
central_dir_offset = 0;
end_of_central_dir_offset = 0;
- tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml");
- tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml");
}
Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) {
@@ -503,7 +500,7 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
size_t block_size = (p_len - step) > BLOCK_SIZE ? (size_t)BLOCK_SIZE : (p_len - step);
- for (uint32_t i = 0; i < block_size; i++) {
+ for (uint64_t i = 0; i < block_size; i++) {
strm_in.write[i] = p_buffer[step + i];
}
@@ -519,20 +516,22 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
int total_out_before = strm.total_out;
- deflate(&strm, Z_FULL_FLUSH);
+ int err = deflate(&strm, Z_FULL_FLUSH);
+ ERR_FAIL_COND_V(err >= 0, ERR_BUG); // Negative means bug
+
bh.compressed_size = strm.total_out - total_out_before;
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + bh.compressed_size);
- for (uint32_t i = 0; i < bh.compressed_size; i++)
+ for (uint64_t i = 0; i < bh.compressed_size; i++)
file_buffer.write[start + i] = strm_out[i];
} else {
bh.compressed_size = block_size;
//package->store_buffer(strm_in.ptr(), block_size);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + block_size);
- for (uint32_t i = 0; i < bh.compressed_size; i++)
+ for (uint64_t i = 0; i < bh.compressed_size; i++)
file_buffer.write[start + i] = strm_in[i];
}
@@ -555,7 +554,7 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before));
- for (uint32_t i = 0; i < (strm.total_out - total_out_before); i++)
+ for (uint64_t i = 0; i < (strm.total_out - total_out_before); i++)
file_buffer.write[start + i] = strm_out[i];
deflateEnd(&strm);
@@ -589,7 +588,9 @@ void AppxPackager::finish() {
// Create and add block map file
EditorNode::progress_task_step("export", "Creating block map...", 4);
- make_block_map();
+ const String &tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml");
+ make_block_map(tmp_blockmap_file_path);
+
FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ);
Vector<uint8_t> blockmap_buffer;
blockmap_buffer.resize(blockmap_file->get_len());
@@ -602,8 +603,11 @@ void AppxPackager::finish() {
memdelete(blockmap_file);
// Add content types
+
EditorNode::progress_task_step("export", "Setting content types...", 5);
- make_content_types();
+
+ const String &tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml");
+ make_content_types(tmp_content_types_file_path);
FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ);
Vector<uint8_t> types_buffer;
@@ -616,6 +620,10 @@ void AppxPackager::finish() {
types_file->close();
memdelete(types_file);
+ // Cleanup generated files.
+ DirAccess::remove_file_or_error(tmp_blockmap_file_path);
+ DirAccess::remove_file_or_error(tmp_content_types_file_path);
+
// Pre-process central directory before signing
for (int i = 0; i < file_metadata.size(); i++) {
store_central_dir_header(file_metadata[i]);
@@ -899,8 +907,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
String err_string = "Couldn't save temp logo file.";
EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
+ ERR_FAIL_V_MSG(data, err_string);
}
FileAccess *f = FileAccess::open(tmp_path, FileAccess::READ, &err);
@@ -908,10 +915,10 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
if (err != OK) {
String err_string = "Couldn't open temp logo file.";
-
+ // Cleanup generated file.
+ DirAccess::remove_file_or_error(tmp_path);
EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
+ ERR_FAIL_V_MSG(data, err_string);
}
data.resize(f->get_len());
@@ -919,31 +926,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
f->close();
memdelete(f);
-
- // Delete temp file
- DirAccess *dir = DirAccess::open(tmp_path.get_base_dir(), &err);
-
- if (err != OK) {
-
- String err_string = "Couldn't open temp path to remove temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
- }
-
- err = dir->remove(tmp_path);
-
- memdelete(dir);
-
- if (err != OK) {
-
- String err_string = "Couldn't remove temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
- }
+ DirAccess::remove_file_or_error(tmp_path);
return data;
}
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 9d9be44ce5..60f2290355 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -835,11 +835,7 @@ Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle,
String full_path = "game/" + p_path;
p_library_handle = (void *)LoadPackagedLibrary(full_path.c_str(), 0);
-
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + full_path + ". Error: " + format_error_message(GetLastError()));
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + full_path + ", error: " + format_error_message(GetLastError()) + ".");
return OK;
}
@@ -854,8 +850,7 @@ Error OS_UWP::get_dynamic_library_symbol_handle(void *p_library_handle, const St
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
if (!p_symbol_handle) {
if (!p_optional) {
- ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
- ERR_FAIL_V(ERR_CANT_RESOLVE);
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
} else {
return ERR_CANT_RESOLVE;
}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index b7a7248f19..370cab6a9b 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -50,9 +50,6 @@
#include <stdio.h>
#include <windows.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_UWP : public OS {
public:
diff --git a/platform/windows/camera_win.cpp b/platform/windows/camera_win.cpp
index b97796fe89..10787d0d0a 100644
--- a/platform/windows/camera_win.cpp
+++ b/platform/windows/camera_win.cpp
@@ -30,9 +30,12 @@
#include "camera_win.h"
-///@TODO sorry guys, I got about 80% through implementing this using DirectShow only to find out Microsoft deprecated half the API and its replacement is as confusing as they could make it
-// Joey suggested looking into libuvc which offers a more direct route to webcams over USB and this is very promissing but it wouldn't compile on windows for me...
-// I've gutted the classes I implemented DirectShow in just to have a skeleton for someone to work on, mail me for more details or if you want a copy....
+///@TODO sorry guys, I got about 80% through implementing this using DirectShow only
+// to find out Microsoft deprecated half the API and its replacement is as confusing
+// as they could make it. Joey suggested looking into libuvc which offers a more direct
+// route to webcams over USB and this is very promising but it wouldn't compile on
+// windows for me...I've gutted the classes I implemented DirectShow in just to have
+// a skeleton for someone to work on, mail me for more details or if you want a copy....
//////////////////////////////////////////////////////////////////////////
// CameraFeedWindows - Subclass for our camera feed on windows
@@ -69,7 +72,8 @@ bool CameraFeedWindows::activate_feed() {
return true;
};
-///@TODO we should probably have a callback method here that is being called by the camera API which provides frames and call back into the CameraServer to update our texture
+///@TODO we should probably have a callback method here that is being called by the
+// camera API which provides frames and call back into the CameraServer to update our texture
void CameraFeedWindows::deactivate_feed(){
///@TODO this should deactivate our camera and stop the process of capturing frames
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 745f3ce379..be325381bb 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -719,7 +719,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
pressrc = 0;
}
}
- } else if (mouse_mode != MOUSE_MODE_CAPTURED) {
+ } else {
// for reasons unknown to mankind, wheel comes in screen coordinates
POINT coords;
coords.x = mb->get_position().x;
@@ -1435,16 +1435,13 @@ void OS_Windows::set_clipboard(const String &p_text) {
String text = p_text.replace("\n", "\r\n");
if (!OpenClipboard(hWnd)) {
- ERR_EXPLAIN("Unable to open clipboard.");
- ERR_FAIL();
- };
+ ERR_FAIL_MSG("Unable to open clipboard.");
+ }
EmptyClipboard();
HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(CharType));
- if (mem == NULL) {
- ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
- ERR_FAIL();
- };
+ ERR_FAIL_COND_MSG(mem == NULL, "Unable to allocate memory for clipboard contents.");
+
LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem);
memcpy(lptstrCopy, text.c_str(), (text.length() + 1) * sizeof(CharType));
GlobalUnlock(mem);
@@ -1454,10 +1451,8 @@ void OS_Windows::set_clipboard(const String &p_text) {
// set the CF_TEXT version (not needed?)
CharString utf8 = text.utf8();
mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1);
- if (mem == NULL) {
- ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
- ERR_FAIL();
- };
+ ERR_FAIL_COND_MSG(mem == NULL, "Unable to allocate memory for clipboard contents.");
+
LPTSTR ptr = (LPTSTR)GlobalLock(mem);
memcpy(ptr, utf8.get_data(), utf8.length());
ptr[utf8.length()] = 0;
@@ -1472,8 +1467,7 @@ String OS_Windows::get_clipboard() const {
String ret;
if (!OpenClipboard(hWnd)) {
- ERR_EXPLAIN("Unable to open clipboard.");
- ERR_FAIL_V("");
+ ERR_FAIL_V_MSG("", "Unable to open clipboard.");
};
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
@@ -1537,6 +1531,7 @@ void OS_Windows::finalize() {
memdelete(camera_server);
touch_state.clear();
+ cursors_cache.clear();
visual_server->finish();
memdelete(visual_server);
#ifdef OPENGL_ENABLED
@@ -1812,7 +1807,7 @@ Size2 OS_Windows::get_min_window_size() const {
void OS_Windows::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -1821,7 +1816,7 @@ void OS_Windows::set_min_window_size(const Size2 p_size) {
void OS_Windows::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
@@ -2134,15 +2129,12 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
}
p_library_handle = (void *)LoadLibraryExW(path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
+ ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + format_error_message(GetLastError()) + ".");
if (cookie) {
remove_dll_directory(cookie);
}
- if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + format_error_message(GetLastError()));
- ERR_FAIL_V(ERR_CANT_OPEN);
- }
return OK;
}
@@ -2157,8 +2149,7 @@ Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, cons
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
if (!p_symbol_handle) {
if (!p_optional) {
- ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
- ERR_FAIL_V(ERR_CANT_RESOLVE);
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
} else {
return ERR_CANT_RESOLVE;
}
@@ -2251,9 +2242,17 @@ uint64_t OS_Windows::get_unix_time() const {
FILETIME fep;
SystemTimeToFileTime(&ep, &fep);
- // FIXME: dereferencing type-punned pointer will break strict-aliasing rules (GCC warning)
+ // Type punning through unions (rather than pointer cast) as per:
// https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime#remarks
- return (*(uint64_t *)&ft - *(uint64_t *)&fep) / 10000000;
+ ULARGE_INTEGER ft_punning;
+ ft_punning.LowPart = ft.dwLowDateTime;
+ ft_punning.HighPart = ft.dwHighDateTime;
+
+ ULARGE_INTEGER fep_punning;
+ fep_punning.LowPart = fep.dwLowDateTime;
+ fep_punning.HighPart = fep.dwHighDateTime;
+
+ return (ft_punning.QuadPart - fep_punning.QuadPart) / 10000000;
};
uint64_t OS_Windows::get_system_time_secs() const {
@@ -2677,10 +2676,7 @@ void OS_Windows::set_native_icon(const String &p_filename) {
pos += sizeof(WORD);
f->seek(pos);
- if (icon_dir->idType != 1) {
- ERR_EXPLAIN("Invalid icon file format!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(icon_dir->idType != 1, "Invalid icon file format!");
icon_dir->idCount = f->get_32();
pos += sizeof(WORD);
@@ -2713,10 +2709,7 @@ void OS_Windows::set_native_icon(const String &p_filename) {
}
}
- if (big_icon_index == -1) {
- ERR_EXPLAIN("No valid icons found!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(big_icon_index == -1, "No valid icons found!");
if (small_icon_index == -1) {
WARN_PRINTS("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!");
@@ -2732,10 +2725,7 @@ void OS_Windows::set_native_icon(const String &p_filename) {
f->seek(pos);
f->get_buffer((uint8_t *)&data_big.write[0], bytecount_big);
HICON icon_big = CreateIconFromResource((PBYTE)&data_big.write[0], bytecount_big, TRUE, 0x00030000);
- if (!icon_big) {
- ERR_EXPLAIN("Could not create " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon, error: " + format_error_message(GetLastError()));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!icon_big, "Could not create " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon, error: " + format_error_message(GetLastError()) + ".");
// Read the small icon
DWORD bytecount_small = icon_dir->idEntries[small_icon_index].dwBytesInRes;
@@ -2745,10 +2735,7 @@ void OS_Windows::set_native_icon(const String &p_filename) {
f->seek(pos);
f->get_buffer((uint8_t *)&data_small.write[0], bytecount_small);
HICON icon_small = CreateIconFromResource((PBYTE)&data_small.write[0], bytecount_small, TRUE, 0x00030000);
- if (!icon_small) {
- ERR_EXPLAIN("Could not create 16x16 @" + itos(small_icon_cc) + " icon, error: " + format_error_message(GetLastError()));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!icon_small, "Could not create 16x16 @" + itos(small_icon_cc) + " icon, error: " + format_error_message(GetLastError()) + ".");
// Online tradition says to be sure last error is cleared and set the small icon first
int err = 0;
@@ -2756,17 +2743,11 @@ void OS_Windows::set_native_icon(const String &p_filename) {
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon_small);
err = GetLastError();
- if (err) {
- ERR_EXPLAIN("Error setting ICON_SMALL: " + format_error_message(err));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(err, "Error setting ICON_SMALL: " + format_error_message(err) + ".");
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon_big);
err = GetLastError();
- if (err) {
- ERR_EXPLAIN("Error setting ICON_BIG: " + format_error_message(err));
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(err, "Error setting ICON_BIG: " + format_error_message(err) + ".");
memdelete(f);
memdelete(icon_dir);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index ce55328173..915d025e3b 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -56,10 +56,6 @@
#include <windows.h>
#include <windowsx.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index 46420df48b..095ce2154b 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -31,9 +31,6 @@
#ifndef CONTEXT_GL_X11_H
#define CONTEXT_GL_X11_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#ifdef X11_ENABLED
#if defined(OPENGL_ENABLED)
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index f3a486df02..b8ff97279d 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -64,6 +64,7 @@ def get_opts():
BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False),
BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False),
BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False),
+ BoolVariable('use_tsan', 'Use LLVM/GCC compiler thread sanitizer (TSAN))', False),
BoolVariable('pulseaudio', 'Detect and use PulseAudio', True),
BoolVariable('udev', 'Use udev for gamepad connection callbacks', False),
EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
@@ -140,7 +141,7 @@ def configure(env):
print("Using LLD with GCC is not supported yet, try compiling with 'use_llvm=yes'.")
sys.exit(255)
- if env['use_ubsan'] or env['use_asan'] or env['use_lsan']:
+ if env['use_ubsan'] or env['use_asan'] or env['use_lsan'] or env['use_tsan']:
env.extra_suffix += "s"
if env['use_ubsan']:
@@ -155,6 +156,10 @@ def configure(env):
env.Append(CCFLAGS=['-fsanitize=leak'])
env.Append(LINKFLAGS=['-fsanitize=leak'])
+ if env['use_tsan']:
+ env.Append(CCFLAGS=['-fsanitize=thread'])
+ env.Append(LINKFLAGS=['-fsanitize=thread'])
+
if env['use_lto']:
if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
env.Append(CCFLAGS=['-flto'])
diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp
index 8767aac517..6e66173463 100644
--- a/platform/x11/export/export.cpp
+++ b/platform/x11/export/export.cpp
@@ -85,8 +85,7 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
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);
+ ERR_FAIL_V_MSG(ERR_INVALID_DATA, "32-bit executables cannot have embedded data >= 4 GiB.");
}
// Get info about the section header table
diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp
index e6328ee14d..4242952374 100644
--- a/platform/x11/joypad_linux.cpp
+++ b/platform/x11/joypad_linux.cpp
@@ -513,6 +513,8 @@ void JoypadLinux::process_joypads() {
break;
default:
+ if (ev.code >= MAX_ABS)
+ return;
if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
InputDefault::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
joy->curr_axis[joy->abs_map[ev.code]] = value;
diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h
index 853fe7954a..4e25d6a6ed 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/x11/key_mapping_x11.h
@@ -31,9 +31,6 @@
#ifndef KEY_MAPPING_X11_H
#define KEY_MAPPING_X11_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#include <X11/XF86keysym.h>
#include <X11/Xlib.h>
#define XK_MISCELLANY
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 9b35648046..687981f32b 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -378,6 +378,13 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
}
+ // make PID known to X11
+ {
+ const long pid = this->get_process_id();
+ Atom net_wm_pid = XInternAtom(x11_display, "_NET_WM_PID", False);
+ XChangeProperty(x11_display, x11_window, net_wm_pid, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1);
+ }
+
// disable resizable window
if (!current_videomode.resizable && !current_videomode.fullscreen) {
XSizeHints *xsh;
@@ -788,6 +795,7 @@ void OS_X11::finalize() {
memdelete(camera_server);
+ cursors_cache.clear();
visual_server->finish();
memdelete(visual_server);
//memdelete(rasterizer);
@@ -1265,7 +1273,7 @@ Size2 OS_X11::get_min_window_size() const {
void OS_X11::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -1294,7 +1302,7 @@ void OS_X11::set_min_window_size(const Size2 p_size) {
void OS_X11::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
@@ -1517,9 +1525,12 @@ void OS_X11::set_window_maximized(bool p_enabled) {
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- if (is_window_maximize_allowed()) {
- while (p_enabled && !is_window_maximized()) {
- // Wait for effective resizing (so the GLX context is too).
+ if (p_enabled && is_window_maximize_allowed()) {
+ // Wait for effective resizing (so the GLX context is too).
+ // Give up after 0.5s, it's not going to happen on this WM.
+ // https://github.com/godotengine/godot/issues/19978
+ for (int attempt = 0; !is_window_maximized() && attempt < 50; attempt++) {
+ usleep(10000);
}
}
@@ -1555,7 +1566,7 @@ bool OS_X11::is_window_maximize_allowed() {
bool found_wm_act_max_horz = false;
bool found_wm_act_max_vert = false;
- for (unsigned int i = 0; i < len; i++) {
+ for (uint64_t i = 0; i < len; i++) {
if (atoms[i] == wm_act_max_horz)
found_wm_act_max_horz = true;
if (atoms[i] == wm_act_max_vert)
@@ -1601,7 +1612,7 @@ bool OS_X11::is_window_maximized() const {
bool found_wm_max_horz = false;
bool found_wm_max_vert = false;
- for (unsigned int i = 0; i < len; i++) {
+ for (uint64_t i = 0; i < len; i++) {
if (atoms[i] == wm_max_horz)
found_wm_max_horz = true;
if (atoms[i] == wm_max_vert)
@@ -1753,7 +1764,10 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
// XLookupString returns keysyms usable as nice scancodes/
char str[256 + 1];
- XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL);
+ XKeyEvent xkeyevent_no_mod = *xkeyevent;
+ xkeyevent_no_mod.state &= ~ShiftMask;
+ xkeyevent_no_mod.state &= ~ControlMask;
+ XLookupString(&xkeyevent_no_mod, str, 256, &keysym_keycode, NULL);
// Meanwhile, XLookupString returns keysyms useful for unicode.
@@ -3014,7 +3028,7 @@ void OS_X11::alert(const String &p_alert, const String &p_title) {
String program;
for (int i = 0; i < path_elems.size(); i++) {
- for (unsigned int k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
+ for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
String tested_path = path_elems[i].plus_file(message_programs[k]);
if (FileAccess::exists(tested_path)) {
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index a4c22cf08a..e6c2effacf 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -77,9 +77,6 @@ typedef struct _xrr_monitor_info {
} xrr_monitor_info;
#undef CursorShape
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class OS_X11 : public OS_Unix {
diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp
index 758bd84114..c33c77e16b 100644
--- a/platform/x11/power_x11.cpp
+++ b/platform/x11/power_x11.cpp
@@ -268,9 +268,7 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
check_proc_acpi_battery(node.utf8().get_data(), &have_battery, &charging /*, seconds, percent*/);
node = dirp->get_next();
}
- memdelete(dirp);
}
-
dirp->change_dir(proc_acpi_ac_adapter_path);
err = dirp->list_dir_begin();
if (err != OK) {
@@ -281,7 +279,6 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
check_proc_acpi_ac_adapter(node.utf8().get_data(), &have_ac);
node = dirp->get_next();
}
- memdelete(dirp);
}
if (!have_battery) {
@@ -294,6 +291,7 @@ bool PowerX11::GetPowerInfo_Linux_proc_acpi() {
this->power_state = OS::POWERSTATE_ON_BATTERY;
}
+ memdelete(dirp);
return true; /* definitive answer. */
}
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index c7f622dee3..0b20b781f0 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "animated_sprite.h"
+
#include "core/os/os.h"
#include "scene/scene_string_names.h"
@@ -356,12 +357,11 @@ void AnimatedSprite::_validate_property(PropertyInfo &property) const {
}
if (property.name == "frame") {
-
- property.hint = PROPERTY_HINT_SPRITE_FRAME;
-
+ property.hint = PROPERTY_HINT_RANGE;
if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) {
property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1";
}
+ property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
}
@@ -642,9 +642,8 @@ void AnimatedSprite::_reset_timeout() {
void AnimatedSprite::set_animation(const StringName &p_animation) {
- ERR_EXPLAIN(vformat("There is no animation with name '%s'.", p_animation));
- ERR_FAIL_COND(frames == NULL);
- ERR_FAIL_COND(frames->get_animation_names().find(p_animation) == -1);
+ ERR_FAIL_COND_MSG(frames == NULL, vformat("There is no animation with name '%s'.", p_animation));
+ ERR_FAIL_COND_MSG(frames->get_animation_names().find(p_animation) == -1, vformat("There is no animation with name '%s'.", p_animation));
if (animation == p_animation)
return;
@@ -709,7 +708,7 @@ void AnimatedSprite::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index b701e84a9c..a636eea285 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -321,10 +321,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_
void Area2D::_clear_monitoring() {
- if (locked) {
- ERR_EXPLAIN("This function can't be used during the in/out signal.");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
{
Map<ObjectID, BodyState> bmcopy = body_map;
@@ -401,10 +398,7 @@ void Area2D::set_monitoring(bool p_enable) {
if (p_enable == monitoring)
return;
- if (locked) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
monitoring = p_enable;
@@ -427,10 +421,7 @@ bool Area2D::is_monitoring() const {
void Area2D::set_monitorable(bool p_enable) {
- if (locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries())) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(locked || (is_inside_tree() && Physics2DServer::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
if (p_enable == monitorable)
return;
@@ -672,8 +663,8 @@ void Area2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 6011941142..3e8902314c 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -106,7 +106,7 @@ Transform2D Camera2D::get_camera_transform() {
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
- if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !h_offset_changed) {
camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_LEFT]));
camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_RIGHT]));
} else {
@@ -116,9 +116,11 @@ Transform2D Camera2D::get_camera_transform() {
} else {
camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs;
}
+
+ h_offset_changed = false;
}
- if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint()) {
+ if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !v_offset_changed) {
camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_TOP]));
camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_BOTTOM]));
@@ -130,6 +132,8 @@ Transform2D Camera2D::get_camera_transform() {
} else {
camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
}
+
+ v_offset_changed = false;
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
@@ -554,6 +558,7 @@ bool Camera2D::is_v_drag_enabled() const {
void Camera2D::set_v_offset(float p_offset) {
v_ofs = p_offset;
+ v_offset_changed = true;
_update_scroll();
}
@@ -565,6 +570,7 @@ float Camera2D::get_v_offset() const {
void Camera2D::set_h_offset(float p_offset) {
h_ofs = p_offset;
+ h_offset_changed = true;
_update_scroll();
}
float Camera2D::get_h_offset() const {
@@ -750,8 +756,8 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing");
ADD_GROUP("Offset", "offset_");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset");
ADD_GROUP("Drag Margin", "drag_margin_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT);
@@ -799,9 +805,12 @@ Camera2D::Camera2D() {
limit_drawing_enabled = false;
margin_drawing_enabled = false;
- h_drag_enabled = true;
- v_drag_enabled = true;
+ h_drag_enabled = false;
+ v_drag_enabled = false;
h_ofs = 0;
v_ofs = 0;
+ h_offset_changed = false;
+ v_offset_changed = false;
+
set_notify_transform(true);
}
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 7f16ecff41..bb3c76b30c 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -77,6 +77,9 @@ protected:
float h_ofs;
float v_ofs;
+ bool h_offset_changed;
+ bool v_offset_changed;
+
Point2 camera_screen_center;
void _update_process_mode();
void _update_scroll();
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 7368efd21a..b38fbfe981 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -602,9 +602,7 @@ void CanvasItem::_notification(int p_what) {
}
global_invalid = true;
} break;
- case NOTIFICATION_DRAW: {
-
- } break;
+ case NOTIFICATION_DRAW:
case NOTIFICATION_TRANSFORM_CHANGED: {
} break;
@@ -641,6 +639,9 @@ void CanvasItem::update() {
void CanvasItem::set_modulate(const Color &p_modulate) {
+ if (modulate == p_modulate)
+ return;
+
modulate = p_modulate;
VisualServer::get_singleton()->canvas_item_set_modulate(canvas_item, modulate);
}
@@ -679,6 +680,9 @@ CanvasItem *CanvasItem::get_parent_item() const {
void CanvasItem::set_self_modulate(const Color &p_self_modulate) {
+ if (self_modulate == p_self_modulate)
+ return;
+
self_modulate = p_self_modulate;
VisualServer::get_singleton()->canvas_item_set_self_modulate(canvas_item, self_modulate);
}
@@ -689,6 +693,9 @@ Color CanvasItem::get_self_modulate() const {
void CanvasItem::set_light_mask(int p_light_mask) {
+ if (light_mask == p_light_mask)
+ return;
+
light_mask = p_light_mask;
VS::get_singleton()->canvas_item_set_light_mask(canvas_item, p_light_mask);
}
@@ -707,20 +714,14 @@ void CanvasItem::item_rect_changed(bool p_size_changed) {
void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased);
}
void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -729,20 +730,14 @@ void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_co
void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -751,20 +746,14 @@ void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_c
void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
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, float p_width, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
if (p_filled) {
if (p_width != 1.0) {
@@ -819,20 +808,14 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
}
void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
@@ -841,29 +824,20 @@ void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos
void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map);
}
void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv);
}
void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_style_box.is_null());
@@ -871,10 +845,7 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
}
void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -883,10 +854,7 @@ void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Col
}
void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Transform2D xform(p_rot, p_offset);
xform.scale_basis(p_scale);
@@ -895,20 +863,14 @@ void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const S
void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
}
void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -918,10 +880,7 @@ void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color
void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
colors.push_back(p_color);
@@ -949,10 +908,7 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
p_font->draw(canvas_item, p_pos, p_text, p_modulate, p_clip_w);
@@ -960,10 +916,7 @@ void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const
float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, const Color &p_modulate) {
- if (!drawing) {
- ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
- ERR_FAIL_V(0);
- }
+ ERR_FAIL_COND_V_MSG(!drawing, 0, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND_V(p_char.length() != 1, 0);
ERR_FAIL_COND_V(p_font.is_null(), 0);
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 202c7c9cf2..228b67990c 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -376,11 +376,12 @@ void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
void CollisionObject2D::_update_pickable() {
if (!is_inside_tree())
return;
- bool pickable = this->pickable && is_inside_tree() && is_visible_in_tree();
+
+ bool is_pickable = pickable && is_visible_in_tree();
if (area)
- Physics2DServer::get_singleton()->area_set_pickable(rid, pickable);
+ Physics2DServer::get_singleton()->area_set_pickable(rid, is_pickable);
else
- Physics2DServer::get_singleton()->body_set_pickable(rid, pickable);
+ Physics2DServer::get_singleton()->body_set_pickable(rid, is_pickable);
}
String CollisionObject2D::get_configuration_warning() const {
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 591933d972..f9f273d494 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 {
@@ -611,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) {
@@ -654,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) {
@@ -696,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;
@@ -947,9 +962,13 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
if (redraw) {
VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1);
} else {
VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
}
#ifndef NO_THREADS
update_mutex->unlock();
@@ -980,9 +999,6 @@ void CPUParticles2D::_notification(int p_what) {
_set_redraw(false);
}
- if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
- }
-
if (p_what == NOTIFICATION_DRAW) {
if (!redraw)
return; // don't add to render list
@@ -1153,6 +1169,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)); \
@@ -1187,6 +1204,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);
@@ -1199,6 +1217,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);
@@ -1225,6 +1244,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", "");
@@ -1404,6 +1424,7 @@ 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);
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 8613a185b4..da668664b9 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -35,10 +35,6 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CPUParticles2D : public Node2D {
private:
GDCLASS(CPUParticles2D, Node2D);
@@ -96,6 +92,7 @@ private:
float hue_rot_rand;
float anim_offset_rand;
float time;
+ float lifetime;
Color base_color;
uint32_t seed;
@@ -139,6 +136,7 @@ private:
float pre_process_time;
float explosiveness_ratio;
float randomness_ratio;
+ float lifetime_randomness;
float speed_scale;
bool local_coords;
int fixed_fps;
@@ -200,6 +198,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);
@@ -211,6 +210,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;
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 9fe5fb98b6..6436b3878f 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -155,7 +155,7 @@ void LineBuilder::build() {
texture_mode == Line2D::LINE_TEXTURE_STRETCH;
if (distance_required) {
total_distance = calculate_total_distance(points);
- //Ajust totalDistance.
+ //Adjust totalDistance.
// The line's outer length will be a little higher due to begin and end caps
if (begin_cap_mode == Line2D::LINE_CAP_BOX || begin_cap_mode == Line2D::LINE_CAP_ROUND) {
if (retrieve_curve)
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index f644db462b..5cf28d6c89 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
left_poly = p;
portal_left = apex_point;
portal_right = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
skip = true;
}
@@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
right_poly = p;
portal_right = apex_point;
portal_left = apex_point;
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point)))
+ if (!path.size() || path[path.size() - 1] != apex_point)
path.push_back(apex_point);
}
}
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index e389d5f98f..678db85ff0 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -271,7 +271,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
struct Polygon p;
- for (int i = 0; i < tp.GetNumPoints(); i++) {
+ for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
Map<Vector2, int>::Element *E = points.find(tp[i]);
if (!E) {
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 9a6b63b9a3..0823e09110 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -69,6 +69,9 @@ Size2 ParallaxLayer::get_motion_offset() const {
void ParallaxLayer::_update_mirroring() {
+ if (!is_inside_tree())
+ return;
+
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb) {
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index f2f53d4354..55c8c7f229 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -110,7 +110,7 @@ void Path2D::_notification(int p_what) {
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width);
+ draw_line(prev_p, p, color, line_width, true);
prev_p = p;
}
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 39b3375f09..28f7243c44 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -157,10 +157,7 @@ void PhysicsBody2D::add_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
- }
- ERR_FAIL_COND(!physics_body);
+ ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type.");
Physics2DServer::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid());
}
@@ -168,10 +165,7 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
- if (!physics_body) {
- ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type");
- }
- ERR_FAIL_COND(!physics_body);
+ ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type.");
Physics2DServer::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid());
}
@@ -203,8 +197,7 @@ void StaticBody2D::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -217,8 +210,7 @@ void StaticBody2D::set_friction(real_t p_friction) {
real_t StaticBody2D::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -233,8 +225,7 @@ void StaticBody2D::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -247,8 +238,7 @@ void StaticBody2D::set_bounce(real_t p_bounce) {
real_t StaticBody2D::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
@@ -604,7 +594,7 @@ real_t RigidBody2D::get_mass() const {
void RigidBody2D::set_inertia(real_t p_inertia) {
- ERR_FAIL_COND(p_inertia <= 0);
+ ERR_FAIL_COND(p_inertia < 0);
Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_INERTIA, p_inertia);
}
@@ -630,8 +620,7 @@ void RigidBody2D::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -643,8 +632,7 @@ void RigidBody2D::set_friction(real_t p_friction) {
}
real_t RigidBody2D::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -659,8 +647,7 @@ void RigidBody2D::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -672,8 +659,7 @@ void RigidBody2D::set_bounce(real_t p_bounce) {
}
real_t RigidBody2D::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
@@ -905,10 +891,7 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
- if (contact_monitor->locked) {
- ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead");
- }
- ERR_FAIL_COND(contact_monitor->locked);
+ ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
@@ -1074,10 +1057,10 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_GROUP("Applied Forces", "applied_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque");
@@ -1226,7 +1209,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
return colliding;
}
-//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45.
+//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
@@ -1283,7 +1266,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
//all is a wall
on_wall = true;
} else {
- if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor
+ if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
on_floor_body = collision.collider_rid;
@@ -1298,7 +1281,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
}
}
- } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1463,6 +1446,14 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) {
void KinematicBody2D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
last_valid_transform = get_global_transform();
+
+ // Reset move_and_slide() data.
+ on_floor = false;
+ on_floor_body = RID();
+ on_ceiling = false;
+ on_wall = false;
+ colliders.clear();
+ floor_velocity = Vector2();
}
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
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/sprite.cpp b/scene/2d/sprite.cpp
index 6626fccf1c..d7a8005187 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -259,6 +259,7 @@ void Sprite::set_frame(int p_frame) {
frame = p_frame;
_change_notify("frame");
+ _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -267,6 +268,17 @@ int Sprite::get_frame() const {
return frame;
}
+void Sprite::set_frame_coords(const Vector2 &p_coord) {
+ ERR_FAIL_INDEX(int(p_coord.x), vframes);
+ ERR_FAIL_INDEX(int(p_coord.y), hframes);
+
+ set_frame(int(p_coord.y) * hframes + int(p_coord.x));
+}
+
+Vector2 Sprite::get_frame_coords() const {
+ return Vector2(frame % hframes, frame / hframes);
+}
+
void Sprite::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
@@ -371,10 +383,9 @@ Rect2 Sprite::get_rect() const {
void Sprite::_validate_property(PropertyInfo &property) const {
if (property.name == "frame") {
-
- property.hint = PROPERTY_HINT_SPRITE_FRAME;
-
+ property.hint = PROPERTY_HINT_RANGE;
property.hint_string = "0," + itos(vframes * hframes - 1) + ",1";
+ property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
}
@@ -421,6 +432,9 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite::set_frame_coords);
+ ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite::get_frame_coords);
+
ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite::set_vframes);
ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite::get_vframes);
@@ -442,7 +456,8 @@ void Sprite::_bind_methods() {
ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index e38db3a299..5e6717a3f5 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -110,6 +110,9 @@ public:
void set_frame(int p_frame);
int get_frame() const;
+ void set_frame_coords(const Vector2 &p_coord);
+ Vector2 get_frame_coords() const;
+
void set_vframes(int p_amount);
int get_vframes() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c79cd80e2e..15423f8c5e 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1203,6 +1203,8 @@ void TileMap::clear() {
void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
+ ERR_FAIL_COND(format > FORMAT_2);
+
int c = p_data.size();
PoolVector<int>::Read r = p_data.read();
@@ -1245,8 +1247,6 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y));
}
-
- format = FORMAT_2;
}
PoolVector<int> TileMap::_get_tile_data() const {
@@ -1255,7 +1255,7 @@ PoolVector<int> TileMap::_get_tile_data() const {
data.resize(tile_map.size() * 3);
PoolVector<int>::Write w = data.write();
- format = FORMAT_2;
+ // Save in highest format
int idx = 0;
for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
@@ -1560,7 +1560,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == "format") {
if (p_value.get_type() == Variant::INT) {
- format = (DataFormat)(p_value.operator int64_t());
+ format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading
return true;
}
} else if (p_name == "tile_data") {
@@ -1576,7 +1576,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "format") {
- r_ret = format;
+ r_ret = FORMAT_2; // When saving, always save highest format
return true;
} else if (p_name == "tile_data") {
r_ret = _get_tile_data();
@@ -1909,6 +1909,8 @@ void TileMap::_bind_methods() {
ADD_GROUP("Occluder", "occluder_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
+ ADD_PROPERTY_DEFAULT("format", FORMAT_1);
+
ADD_SIGNAL(MethodInfo("settings_changed"));
BIND_CONSTANT(INVALID_CELL);
@@ -1942,6 +1944,7 @@ TileMap::TileMap() {
quadrant_order_dirty = false;
quadrant_size = 16;
cell_size = Size2(64, 64);
+ custom_transform = Transform2D(64, 0, 0, 64, 0, 0);
collision_layer = 1;
collision_mask = 1;
friction = 1;
@@ -1957,7 +1960,7 @@ TileMap::TileMap() {
centered_textures = false;
occluder_light_mask = 1;
clip_uv = false;
- format = FORMAT_1; //Always initialize with the lowest format
+ format = FORMAT_1; // Assume lowest possible format if none is present
fp_adjust = 0.00001;
tile_origin = TILE_ORIGIN_TOP_LEFT;
diff --git a/scene/3d/SCsub b/scene/3d/SCsub
index 200cf4316f..31a443bad1 100644
--- a/scene/3d/SCsub
+++ b/scene/3d/SCsub
@@ -3,10 +3,10 @@
Import('env')
if env['disable_3d']:
- env.scene_sources.append("3d/spatial.cpp")
- env.scene_sources.append("3d/skeleton.cpp")
- env.scene_sources.append("3d/particles.cpp")
- env.scene_sources.append("3d/visual_instance.cpp")
- env.scene_sources.append("3d/world_environment.cpp")
+ env.add_source_files(env.scene_sources, "spatial.cpp")
+ env.add_source_files(env.scene_sources, "skeleton.cpp")
+ env.add_source_files(env.scene_sources, "particles.cpp")
+ env.add_source_files(env.scene_sources, "visual_instance.cpp")
+ env.add_source_files(env.scene_sources, "world_environment.cpp")
else:
env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 4247266e3d..77682abcb3 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -218,10 +218,7 @@ void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_bo
void Area::_clear_monitoring() {
- if (locked) {
- ERR_EXPLAIN("This function can't be used during the in/out signal.");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
{
Map<ObjectID, BodyState> bmcopy = body_map;
@@ -291,10 +288,7 @@ void Area::_notification(int p_what) {
void Area::set_monitoring(bool p_enable) {
- if (locked) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitoring\",true/false)");
- }
- ERR_FAIL_COND(locked);
+ ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
if (p_enable == monitoring)
return;
@@ -441,10 +435,7 @@ Array Area::get_overlapping_bodies() const {
void Area::set_monitorable(bool p_enable) {
- if (locked || (is_inside_tree() && PhysicsServer::get_singleton()->is_flushing_queries())) {
- ERR_EXPLAIN("Function blocked during in/out signal. Use set_deferred(\"monitorable\",true/false)");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(locked || (is_inside_tree() && PhysicsServer::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
if (p_enable == monitorable)
return;
@@ -718,8 +709,8 @@ void Area::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
index 263a2d8de6..4c0449b68e 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/arvr_nodes.cpp
@@ -78,10 +78,7 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const {
return Camera::project_local_ray_normal(p_pos);
}
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- };
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_camera_rect_size();
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
@@ -106,10 +103,7 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const {
return Camera::unproject_position(p_pos);
}
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector2());
- };
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector2(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_visible_rect().size;
@@ -138,10 +132,7 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con
return Camera::project_position(p_point, p_z_depth);
}
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- };
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_visible_rect().size;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 22959d99ee..05ae281cc1 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -35,6 +35,99 @@
#include "scene/3d/listener.h"
#include "scene/main/viewport.h"
+// Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004)
+// Speaker-Placement Correction Amplitude Panning (SPCAP)
+class Spcap {
+private:
+ struct Speaker {
+ Vector3 direction;
+ real_t effective_number_of_speakers; // precalculated
+ mutable real_t squared_gain; // temporary
+ };
+
+ PoolVector<Speaker> speakers;
+
+public:
+ Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) {
+ this->speakers.resize(speaker_count);
+ PoolVector<Speaker>::Write w = this->speakers.write();
+ for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) {
+ w[speaker_num].direction = speaker_directions[speaker_num];
+ w[speaker_num].squared_gain = 0.0;
+ w[speaker_num].effective_number_of_speakers = 0.0;
+ for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) {
+ w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction));
+ }
+ }
+ }
+
+ unsigned int get_speaker_count() const {
+ return (unsigned int)this->speakers.size();
+ }
+
+ Vector3 get_speaker_direction(unsigned int index) const {
+ return this->speakers.read()[index].direction;
+ }
+
+ void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const {
+ PoolVector<Speaker>::Read r = this->speakers.read();
+ real_t sum_squared_gains = 0.0;
+ for (unsigned int speaker_num = 0; speaker_num < (unsigned int)this->speakers.size(); speaker_num++) {
+ real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers;
+ r[speaker_num].squared_gain = initial_gain * initial_gain;
+ sum_squared_gains += r[speaker_num].squared_gain;
+ }
+
+ for (unsigned int speaker_num = 0; speaker_num < MIN(volume_count, (unsigned int)this->speakers.size()); speaker_num++) {
+ volumes[speaker_num] = sqrtf(r[speaker_num].squared_gain / sum_squared_gains);
+ }
+ }
+};
+
+//TODO: hardcoded main speaker directions for 2, 3.1, 5.1 and 7.1 setups - these are simplified and could also be made configurable
+static const Vector3 speaker_directions[7] = {
+ Vector3(-1.0, 0.0, -1.0).normalized(), // front-left
+ Vector3(1.0, 0.0, -1.0).normalized(), // front-right
+ Vector3(0.0, 0.0, -1.0).normalized(), // center
+ Vector3(-1.0, 0.0, 1.0).normalized(), // rear-left
+ Vector3(1.0, 0.0, 1.0).normalized(), // rear-right
+ Vector3(-1.0, 0.0, 0.0).normalized(), // side-left
+ Vector3(1.0, 0.0, 0.0).normalized(), // side-right
+};
+
+void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, AudioStreamPlayer3D::Output &output) {
+ unsigned int speaker_count; // only main speakers (no LFE)
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+ default: //fallthrough
+ case AudioServer::SPEAKER_MODE_STEREO: speaker_count = 2; break;
+ case AudioServer::SPEAKER_SURROUND_31: speaker_count = 3; break;
+ case AudioServer::SPEAKER_SURROUND_51: speaker_count = 5; break;
+ case AudioServer::SPEAKER_SURROUND_71: speaker_count = 7; break;
+ }
+
+ Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes
+ real_t volumes[7];
+ spcap.calculate(source_dir, tightness, speaker_count, volumes);
+
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+ case AudioServer::SPEAKER_SURROUND_71:
+ output.vol[3].l = volumes[5]; // side-left
+ output.vol[3].r = volumes[6]; // side-right
+ //fallthrough
+ case AudioServer::SPEAKER_SURROUND_51:
+ output.vol[2].l = volumes[3]; // rear-left
+ output.vol[2].r = volumes[4]; // rear-right
+ //fallthrough
+ case AudioServer::SPEAKER_SURROUND_31:
+ output.vol[1].r = 1.0; // LFE - always full power
+ output.vol[1].l = volumes[2]; // center
+ //fallthrough
+ case AudioServer::SPEAKER_MODE_STEREO:
+ output.vol[0].r = volumes[1]; // front-right
+ output.vol[0].l = volumes[0]; // front-left
+ }
+}
+
void AudioStreamPlayer3D::_mix_audio() {
if (!stream_playback.is_valid() || !active ||
@@ -381,59 +474,11 @@ void AudioStreamPlayer3D::_notification(int p_what) {
output.filter_gain = Math::db2linear(db_att);
- Vector3 flat_pos = local_pos;
- flat_pos.y = 0;
- flat_pos.normalize();
+ //TODO: The lower the second parameter (tightness) the more the sound will "enclose" the listener (more undirected / playing from
+ // speakers not facing the source) - this could be made distance dependent.
+ _calc_output_vol(local_pos.normalized(), 4.0, output);
unsigned int cc = AudioServer::get_singleton()->get_channel_count();
- if (cc == 1) {
- // Stereo pair
- float c = flat_pos.x * 0.5 + 0.5;
-
- output.vol[0].l = 1.0 - c;
- output.vol[0].r = c;
- } else {
- Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin;
- float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
- float angle = Math::rad2deg(Math::acos(c));
- float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0;
-
- if (cc >= 1) {
- // Stereo pair
- float fl = Math::abs(1.0 - Math::abs(-0.8 - av));
- float fr = Math::abs(1.0 - Math::abs(0.8 - av));
-
- output.vol[0].l = fl;
- output.vol[0].r = fr;
- }
-
- if (cc >= 2) {
- // Center pair
- float center = 1.0 - Math::sin(Math::acos(c));
-
- output.vol[1].l = center;
- output.vol[1].r = center;
- }
-
- if (cc >= 3) {
- // Side pair
- float sleft = Math::abs(1.0 - Math::abs(-0.4 - av));
- float sright = Math::abs(1.0 - Math::abs(0.4 - av));
-
- output.vol[2].l = sleft;
- output.vol[2].r = sright;
- }
-
- if (cc >= 4) {
- // Rear pair
- float rleft = Math::abs(1.0 - Math::abs(-0.2 - av));
- float rright = Math::abs(1.0 - Math::abs(0.2 - av));
-
- output.vol[3].l = rleft;
- output.vol[3].r = rright;
- }
- }
-
for (unsigned int k = 0; k < cc; k++) {
output.vol[k] *= multiplier;
}
@@ -975,7 +1020,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/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 93954e758a..494aa70097 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -115,6 +115,7 @@ private:
bool stream_paused_fade_out;
StringName bus;
+ static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output);
void _mix_audio();
static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer3D *>(self)->_mix_audio(); }
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index c7d6919a2b..9f8510248c 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -279,10 +279,7 @@ Vector3 Camera::project_ray_normal(const Point2 &p_pos) const {
Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- }
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_camera_rect_size();
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
@@ -304,10 +301,7 @@ Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
Vector3 Camera::project_ray_origin(const Point2 &p_pos) const {
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- }
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_camera_rect_size();
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
@@ -345,10 +339,7 @@ bool Camera::is_position_behind(const Vector3 &p_pos) const {
}
Vector<Vector3> Camera::get_near_plane_points() const {
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector<Vector3>());
- }
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector<Vector3>(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_visible_rect().size;
@@ -372,10 +363,7 @@ Vector<Vector3> Camera::get_near_plane_points() const {
Point2 Camera::unproject_position(const Vector3 &p_pos) const {
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector2());
- }
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector2(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_visible_rect().size;
@@ -400,10 +388,7 @@ Point2 Camera::unproject_position(const Vector3 &p_pos) const {
Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const {
- if (!is_inside_tree()) {
- ERR_EXPLAIN("Camera is not inside scene.");
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- }
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
if (p_z_depth == 0) {
return get_global_transform().origin;
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index 6460f17e85..22223880c1 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -35,9 +35,7 @@
#include "scene/3d/spatial_velocity_tracker.h"
#include "scene/main/viewport.h"
#include "scene/resources/environment.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Camera : public Spatial {
GDCLASS(Camera, Spatial);
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 9d3e2983c4..735b393171 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -105,7 +105,8 @@ void CollisionObject::_mouse_exit() {
void CollisionObject::_update_pickable() {
if (!is_inside_tree())
return;
- bool pickable = ray_pickable && is_inside_tree() && is_visible_in_tree();
+
+ bool pickable = ray_pickable && is_visible_in_tree();
if (area)
PhysicsServer::get_singleton()->area_set_ray_pickable(rid, pickable);
else
@@ -370,7 +371,7 @@ String CollisionObject::get_configuration_warning() const {
String warning = Spatial::get_configuration_warning();
if (shapes.empty()) {
- if (warning == String()) {
+ if (!warning.empty()) {
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_polygon.cpp b/scene/3d/collision_polygon.cpp
index db07059b32..37aa95fb43 100644
--- a/scene/3d/collision_polygon.cpp
+++ b/scene/3d/collision_polygon.cpp
@@ -151,6 +151,8 @@ float CollisionPolygon::get_depth() const {
void CollisionPolygon::set_disabled(bool p_disabled) {
disabled = p_disabled;
+ update_gizmo();
+
if (parent) {
parent->shape_owner_set_disabled(owner_id, p_disabled);
}
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 86b407b9e6..fc16bc36cb 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 {
@@ -583,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) {
@@ -636,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) {
@@ -701,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;
@@ -1059,9 +1074,6 @@ void CPUParticles::_notification(int p_what) {
_set_redraw(false);
}
- if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
- }
-
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (particles.size() == 0 || !is_visible_in_tree()) {
@@ -1221,6 +1233,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)); \
@@ -1255,6 +1268,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);
@@ -1267,6 +1281,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);
@@ -1290,6 +1305,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", "");
@@ -1472,6 +1488,7 @@ 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);
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
index 517df8490d..66b37f359a 100644
--- a/scene/3d/cpu_particles.h
+++ b/scene/3d/cpu_particles.h
@@ -34,10 +34,6 @@
#include "core/rid.h"
#include "scene/3d/visual_instance.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CPUParticles : public GeometryInstance {
private:
GDCLASS(CPUParticles, GeometryInstance);
@@ -95,6 +91,7 @@ private:
float hue_rot_rand;
float anim_offset_rand;
float time;
+ float lifetime;
Color base_color;
uint32_t seed;
@@ -137,6 +134,7 @@ private:
float pre_process_time;
float explosiveness_ratio;
float randomness_ratio;
+ float lifetime_randomness;
float speed_scale;
bool local_coords;
int fixed_fps;
@@ -200,6 +198,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);
@@ -211,6 +210,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;
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 4ef945ab8d..85ee925248 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -200,9 +200,6 @@ void Light::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
_update_visibility();
}
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- }
}
void Light::set_editor_only(bool p_editor_only) {
@@ -413,7 +410,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);
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 5d365758b5..cc8675ead1 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -35,10 +35,6 @@
#include "scene/resources/texture.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Light : public VisualInstance {
GDCLASS(Light, VisualInstance);
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index 89072519d5..50ca466df3 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -149,12 +149,38 @@ Ref<Mesh> MeshInstance::get_mesh() const {
void MeshInstance::_resolve_skeleton_path() {
- if (skeleton_path.is_empty())
+ Ref<SkinReference> new_skin_reference;
+
+ if (!skeleton_path.is_empty()) {
+ Skeleton *skeleton = Object::cast_to<Skeleton>(get_node(skeleton_path));
+ if (skeleton) {
+ new_skin_reference = skeleton->register_skin(skin);
+ if (skin.is_null()) {
+ //a skin was created for us
+ skin = new_skin_reference->get_skin();
+ _change_notify();
+ }
+ }
+ }
+
+ skin_ref = new_skin_reference;
+
+ if (skin_ref.is_valid()) {
+ VisualServer::get_singleton()->instance_attach_skeleton(get_instance(), skin_ref->get_skeleton());
+ } else {
+ VisualServer::get_singleton()->instance_attach_skeleton(get_instance(), RID());
+ }
+}
+
+void MeshInstance::set_skin(const Ref<Skin> &p_skin) {
+ skin = p_skin;
+ if (!is_inside_tree())
return;
+ _resolve_skeleton_path();
+}
- Skeleton *skeleton = Object::cast_to<Skeleton>(get_node(skeleton_path));
- if (skeleton)
- VisualServer::get_singleton()->instance_attach_skeleton(get_instance(), skeleton->get_skeleton());
+Ref<Skin> MeshInstance::get_skin() const {
+ return skin;
}
void MeshInstance::set_skeleton_path(const NodePath &p_skeleton) {
@@ -365,6 +391,8 @@ void MeshInstance::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance::get_mesh);
ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &MeshInstance::set_skeleton_path);
ClassDB::bind_method(D_METHOD("get_skeleton_path"), &MeshInstance::get_skeleton_path);
+ ClassDB::bind_method(D_METHOD("set_skin", "skin"), &MeshInstance::set_skin);
+ ClassDB::bind_method(D_METHOD("get_skin"), &MeshInstance::get_skin);
ClassDB::bind_method(D_METHOD("get_surface_material_count"), &MeshInstance::get_surface_material_count);
ClassDB::bind_method(D_METHOD("set_surface_material", "surface", "material"), &MeshInstance::set_surface_material);
@@ -380,6 +408,7 @@ void MeshInstance::_bind_methods() {
ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
}
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
index 022ef15aad..77ead75dd3 100644
--- a/scene/3d/mesh_instance.h
+++ b/scene/3d/mesh_instance.h
@@ -31,18 +31,19 @@
#ifndef MESH_INSTANCE_H
#define MESH_INSTANCE_H
+#include "scene/3d/skeleton.h"
#include "scene/3d/visual_instance.h"
#include "scene/resources/mesh.h"
+#include "scene/resources/skin.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class MeshInstance : public GeometryInstance {
GDCLASS(MeshInstance, GeometryInstance);
protected:
Ref<Mesh> mesh;
+ Ref<Skin> skin;
+ Ref<SkinReference> skin_ref;
NodePath skeleton_path;
struct BlendShapeTrack {
@@ -73,6 +74,9 @@ public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
+ void set_skin(const Ref<Skin> &p_skin);
+ Ref<Skin> get_skin() const;
+
void set_skeleton_path(const NodePath &p_skeleton);
NodePath get_skeleton_path();
diff --git a/scene/3d/multimesh_instance.h b/scene/3d/multimesh_instance.h
index 8f41aa8fd2..ca69c73251 100644
--- a/scene/3d/multimesh_instance.h
+++ b/scene/3d/multimesh_instance.h
@@ -34,10 +34,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/multimesh.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MultiMeshInstance : public GeometryInstance {
GDCLASS(MultiMeshInstance, GeometryInstance);
diff --git a/scene/3d/particles.h b/scene/3d/particles.h
index 42c68010db..391491e8b8 100644
--- a/scene/3d/particles.h
+++ b/scene/3d/particles.h
@@ -35,10 +35,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/material.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Particles : public GeometryInstance {
private:
GDCLASS(Particles, GeometryInstance);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 2f8b2ecc5c..71040d2d68 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -129,10 +129,7 @@ void PhysicsBody::add_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
- if (!collision_object) {
- ERR_EXPLAIN("Collision exception only works between two CollisionObject");
- }
- ERR_FAIL_COND(!collision_object);
+ ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
PhysicsServer::get_singleton()->body_add_collision_exception(get_rid(), collision_object->get_rid());
}
@@ -140,10 +137,7 @@ void PhysicsBody::remove_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
- if (!collision_object) {
- ERR_EXPLAIN("Collision exception only works between two CollisionObject");
- }
- ERR_FAIL_COND(!collision_object);
+ ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
}
@@ -192,8 +186,7 @@ void StaticBody::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -206,8 +199,7 @@ void StaticBody::set_friction(real_t p_friction) {
real_t StaticBody::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -222,8 +214,7 @@ void StaticBody::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -236,8 +227,7 @@ void StaticBody::set_bounce(real_t p_bounce) {
real_t StaticBody::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
@@ -636,8 +626,7 @@ void RigidBody::set_friction(real_t p_friction) {
return;
}
- ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
@@ -649,8 +638,7 @@ void RigidBody::set_friction(real_t p_friction) {
}
real_t RigidBody::get_friction() const {
- ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 1;
@@ -665,8 +653,7 @@ void RigidBody::set_bounce(real_t p_bounce) {
return;
}
- ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.");
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
@@ -677,8 +664,7 @@ void RigidBody::set_bounce(real_t p_bounce) {
physics_material_override->set_bounce(p_bounce);
}
real_t RigidBody::get_bounce() const {
- ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.");
if (physics_material_override.is_null()) {
return 0;
}
@@ -867,10 +853,7 @@ void RigidBody::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
- if (contact_monitor->locked) {
- ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead");
- }
- ERR_FAIL_COND(contact_monitor->locked);
+ ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
@@ -1044,10 +1027,10 @@ void RigidBody::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
@@ -1154,7 +1137,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
return colliding;
}
-//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45.
+//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
@@ -1209,7 +1192,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
//all is a wall
on_wall = true;
} else {
- if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor
+ if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
on_floor_body = collision.collider_rid;
@@ -1226,7 +1209,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
is_on_slope = true;
- } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1404,6 +1387,18 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
return slide_colliders[p_bounce];
}
+void KinematicBody::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ // Reset move_and_slide() data.
+ on_floor = false;
+ on_floor_body = RID();
+ on_ceiling = false;
+ on_wall = false;
+ colliders.clear();
+ floor_velocity = Vector3();
+ }
+}
+
void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
@@ -2187,7 +2182,7 @@ void PhysicalBone::_notification(int p_what) {
void PhysicalBone::_direct_state_changed(Object *p_state) {
- if (!simulate_physics) {
+ if (!simulate_physics || !_internal_simulate_physics) {
return;
}
@@ -2210,7 +2205,7 @@ void PhysicalBone::_direct_state_changed(Object *p_state) {
// Update skeleton
if (parent_skeleton) {
if (-1 != bone_id) {
- parent_skeleton->set_bone_global_pose(bone_id, parent_skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse));
+ parent_skeleton->set_bone_global_pose_override(bone_id, parent_skeleton->get_global_transform().affine_inverse() * (global_transform * body_offset_inverse), 1.0, true);
}
}
}
@@ -2721,7 +2716,6 @@ void PhysicalBone::_start_physics_simulation() {
PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer());
PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask());
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
- parent_skeleton->set_bone_ignore_animation(bone_id, true);
_internal_simulate_physics = true;
}
@@ -2733,6 +2727,6 @@ void PhysicalBone::_stop_physics_simulation() {
PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0);
PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0);
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
- parent_skeleton->set_bone_ignore_animation(bone_id, false);
+ parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false);
_internal_simulate_physics = false;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index aa6030d44e..0967cb9cd5 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -162,6 +162,7 @@ protected:
ShapePair(int p_bs, int p_ls) {
body_shape = p_bs;
local_shape = p_ls;
+ tagged = false;
}
};
struct RigidBody_RemoveAction {
@@ -314,6 +315,7 @@ private:
Ref<KinematicCollision> _get_slide_collision(int p_bounce);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
diff --git a/scene/3d/portal.h b/scene/3d/portal.h
index f053867917..04af3a750c 100644
--- a/scene/3d/portal.h
+++ b/scene/3d/portal.h
@@ -32,9 +32,6 @@
#define PORTAL_H
#include "scene/3d/visual_instance.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
/* Portal Logic:
If a portal is placed next (very close to) a similar, opposing portal, they automatically connect,
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index 10f92058e0..30eed8f1a7 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -102,6 +102,8 @@ Vector3 RayCast::get_collision_normal() const {
void RayCast::set_enabled(bool p_enabled) {
enabled = p_enabled;
+ update_gizmo();
+
if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
set_physics_process_internal(p_enabled);
if (!p_enabled)
diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h
index 9ee140d522..01efde53c9 100644
--- a/scene/3d/room_instance.h
+++ b/scene/3d/room_instance.h
@@ -34,10 +34,6 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/room.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
/* RoomInstance Logic:
a) Instances that belong to the room are drawn only if the room is visible (seen through portal, or player inside)
b) Instances that don't belong to any room are considered to belong to the root room (RID empty)
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index e192e040f2..ead1e69f90 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -36,6 +36,34 @@
#include "scene/3d/physics_body.h"
#include "scene/resources/surface_tool.h"
+void SkinReference::_skin_changed() {
+ if (skeleton_node) {
+ skeleton_node->_make_dirty();
+ }
+}
+
+void SkinReference::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_skin_changed"), &SkinReference::_skin_changed);
+ ClassDB::bind_method(D_METHOD("get_skeleton"), &SkinReference::get_skeleton);
+ ClassDB::bind_method(D_METHOD("get_skin"), &SkinReference::get_skin);
+}
+
+RID SkinReference::get_skeleton() const {
+ return skeleton;
+}
+
+Ref<Skin> SkinReference::get_skin() const {
+ return skin;
+}
+
+SkinReference::~SkinReference() {
+ if (skeleton_node) {
+ skeleton_node->skin_bindings.erase(this);
+ }
+
+ VS::get_singleton()->free(skeleton);
+}
+
bool Skeleton::_set(const StringName &p_path, const Variant &p_value) {
String path = p_path;
@@ -196,110 +224,77 @@ void Skeleton::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_WORLD: {
-
- VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
-
- } break;
- case NOTIFICATION_EXIT_WORLD: {
-
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
- } break;
case NOTIFICATION_UPDATE_SKELETON: {
VisualServer *vs = VisualServer::get_singleton();
Bone *bonesptr = bones.ptrw();
int len = bones.size();
- vs->skeleton_allocate(skeleton, len); // if same size, nothing really happens
-
_update_process_order();
const int *order = process_order.ptr();
- // pose changed, rebuild cache of inverses
- if (rest_global_inverse_dirty) {
-
- // calculate global rests and invert them
- for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[order[i]];
- if (b.parent >= 0)
- b.rest_global_inverse = bonesptr[b.parent].rest_global_inverse * b.rest;
- else
- b.rest_global_inverse = b.rest;
- }
- for (int i = 0; i < len; i++) {
- Bone &b = bonesptr[order[i]];
- b.rest_global_inverse.affine_invert();
- }
-
- rest_global_inverse_dirty = false;
- }
-
for (int i = 0; i < len; i++) {
Bone &b = bonesptr[order[i]];
- if (b.disable_rest) {
- if (b.enabled) {
+ if (b.global_pose_override_amount >= 0.999) {
+ b.pose_global = b.global_pose_override;
+ } else {
+ if (b.disable_rest) {
+ if (b.enabled) {
- Transform pose = b.pose;
- if (b.custom_pose_enable) {
+ Transform pose = b.pose;
+ if (b.parent >= 0) {
- pose = b.custom_pose * pose;
- }
+ b.pose_global = bonesptr[b.parent].pose_global * pose;
+ } else {
- if (b.parent >= 0) {
-
- b.pose_global = bonesptr[b.parent].pose_global * pose;
+ b.pose_global = pose;
+ }
} else {
- b.pose_global = pose;
- }
- } else {
-
- if (b.parent >= 0) {
+ if (b.parent >= 0) {
- b.pose_global = bonesptr[b.parent].pose_global;
- } else {
+ b.pose_global = bonesptr[b.parent].pose_global;
+ } else {
- b.pose_global = Transform();
+ b.pose_global = Transform();
+ }
}
- }
- } else {
- if (b.enabled) {
+ } else {
+ if (b.enabled) {
- Transform pose = b.pose;
- if (b.custom_pose_enable) {
+ Transform pose = b.pose;
- pose = b.custom_pose * pose;
- }
+ if (b.parent >= 0) {
- if (b.parent >= 0) {
+ b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
+ } else {
- b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
+ b.pose_global = b.rest * pose;
+ }
} else {
- b.pose_global = b.rest * pose;
- }
- } else {
+ if (b.parent >= 0) {
- if (b.parent >= 0) {
+ b.pose_global = bonesptr[b.parent].pose_global * b.rest;
+ } else {
- b.pose_global = bonesptr[b.parent].pose_global * b.rest;
- } else {
-
- b.pose_global = b.rest;
+ b.pose_global = b.rest;
+ }
}
}
+
+ if (b.global_pose_override_amount >= CMP_EPSILON) {
+ b.pose_global = b.pose_global.interpolate_with(b.global_pose_override, b.global_pose_override_amount);
+ }
}
- b.transform_final = b.pose_global * b.rest_global_inverse;
- vs->skeleton_bone_set_transform(skeleton, order[i], b.transform_final);
+ if (b.global_pose_override_reset) {
+ b.global_pose_override_amount = 0.0;
+ }
for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
@@ -311,28 +306,37 @@ void Skeleton::_notification(int p_what) {
}
}
+ //update skins
+ for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
+
+ const Skin *skin = E->get()->skin.operator->();
+ RID skeleton = E->get()->skeleton;
+ uint32_t bind_count = skin->get_bind_count();
+
+ if (E->get()->bind_count != bind_count) {
+ VS::get_singleton()->skeleton_allocate(skeleton, bind_count);
+ E->get()->bind_count = bind_count;
+ }
+
+ for (uint32_t i = 0; i < bind_count; i++) {
+ uint32_t bone_index = skin->get_bind_bone(i);
+ ERR_CONTINUE(bone_index >= (uint32_t)len);
+ vs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i));
+ }
+ }
+
dirty = false;
} break;
}
}
-Transform Skeleton::get_bone_transform(int p_bone) const {
- ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
- if (dirty)
- const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
- return bones[p_bone].pose_global * bones[p_bone].rest_global_inverse;
-}
-
-void Skeleton::set_bone_global_pose(int p_bone, const Transform &p_pose) {
+void Skeleton::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) {
ERR_FAIL_INDEX(p_bone, bones.size());
- if (bones[p_bone].parent == -1) {
-
- set_bone_pose(p_bone, bones[p_bone].rest_global_inverse * p_pose); //fast
- } else {
-
- set_bone_pose(p_bone, bones[p_bone].rest.affine_inverse() * (get_bone_global_pose(bones[p_bone].parent).affine_inverse() * p_pose)); //slow
- }
+ bones.write[p_bone].global_pose_override_amount = p_amount;
+ bones.write[p_bone].global_pose_override = p_pose;
+ bones.write[p_bone].global_pose_override_reset = !p_persistent;
+ _make_dirty();
}
Transform Skeleton::get_bone_global_pose(int p_bone) const {
@@ -343,11 +347,6 @@ Transform Skeleton::get_bone_global_pose(int p_bone) const {
return bones[p_bone].pose_global;
}
-RID Skeleton::get_skeleton() const {
-
- return skeleton;
-}
-
// skeleton creation api
void Skeleton::add_bone(const String &p_name) {
@@ -362,8 +361,6 @@ void Skeleton::add_bone(const String &p_name) {
b.name = p_name;
bones.push_back(b);
process_order_dirty = true;
-
- rest_global_inverse_dirty = true;
_make_dirty();
update_gizmo();
}
@@ -408,7 +405,6 @@ void Skeleton::set_bone_parent(int p_bone, int p_parent) {
ERR_FAIL_COND(p_parent != -1 && (p_parent < 0));
bones.write[p_bone].parent = p_parent;
- rest_global_inverse_dirty = true;
process_order_dirty = true;
_make_dirty();
}
@@ -426,23 +422,11 @@ void Skeleton::unparent_bone_and_rest(int p_bone) {
}
bones.write[p_bone].parent = -1;
- bones.write[p_bone].rest_global_inverse = bones[p_bone].rest.affine_inverse(); //same thing
process_order_dirty = true;
_make_dirty();
}
-void Skeleton::set_bone_ignore_animation(int p_bone, bool p_ignore) {
- ERR_FAIL_INDEX(p_bone, bones.size());
- bones.write[p_bone].ignore_animation = p_ignore;
-}
-
-bool Skeleton::is_bone_ignore_animation(int p_bone) const {
-
- ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
- return bones[p_bone].ignore_animation;
-}
-
void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) {
ERR_FAIL_INDEX(p_bone, bones.size());
@@ -467,7 +451,6 @@ void Skeleton::set_bone_rest(int p_bone, const Transform &p_rest) {
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].rest = p_rest;
- rest_global_inverse_dirty = true;
_make_dirty();
}
Transform Skeleton::get_bone_rest(int p_bone) const {
@@ -482,7 +465,6 @@ void Skeleton::set_bone_enabled(int p_bone, bool p_enabled) {
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].enabled = p_enabled;
- rest_global_inverse_dirty = true;
_make_dirty();
}
bool Skeleton::is_bone_enabled(int p_bone) const {
@@ -529,7 +511,6 @@ void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound)
void Skeleton::clear_bones() {
bones.clear();
- rest_global_inverse_dirty = true;
process_order_dirty = true;
_make_dirty();
@@ -552,23 +533,6 @@ Transform Skeleton::get_bone_pose(int p_bone) const {
return bones[p_bone].pose;
}
-void Skeleton::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) {
-
- ERR_FAIL_INDEX(p_bone, bones.size());
- //ERR_FAIL_COND( !is_inside_scene() );
-
- bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform());
- bones.write[p_bone].custom_pose = p_custom_pose;
-
- _make_dirty();
-}
-
-Transform Skeleton::get_bone_custom_pose(int p_bone) const {
-
- ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
- return bones[p_bone].custom_pose;
-}
-
void Skeleton::_make_dirty() {
if (dirty)
@@ -747,14 +711,66 @@ void Skeleton::physical_bones_remove_collision_exception(RID p_exception) {
#endif // _3D_DISABLED
-void Skeleton::set_use_bones_in_world_transform(bool p_enable) {
- use_bones_in_world_transform = p_enable;
- if (is_inside_tree()) {
- VS::get_singleton()->skeleton_set_world_transform(skeleton, use_bones_in_world_transform, get_global_transform());
- }
+void Skeleton::_skin_changed() {
+ _make_dirty();
}
-bool Skeleton::is_using_bones_in_world_transform() const {
- return use_bones_in_world_transform;
+
+Ref<SkinReference> Skeleton::register_skin(const Ref<Skin> &p_skin) {
+
+ for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
+ if (E->get()->skin == p_skin) {
+ return Ref<SkinReference>(E->get());
+ }
+ }
+
+ Ref<Skin> skin = p_skin;
+
+ if (skin.is_null()) {
+ //need to create one from existing code, this is for compatibility only
+ //when skeletons did not support skins. It is also used by gizmo
+ //to display the skeleton.
+
+ skin.instance();
+ skin->set_bind_count(bones.size());
+ _update_process_order(); //just in case
+
+ // pose changed, rebuild cache of inverses
+ const Bone *bonesptr = bones.ptr();
+ int len = bones.size();
+ const int *order = process_order.ptr();
+
+ // calculate global rests and invert them
+ for (int i = 0; i < len; i++) {
+ const Bone &b = bonesptr[order[i]];
+ if (b.parent >= 0) {
+ skin->set_bind_pose(order[i], skin->get_bind_pose(b.parent) * b.rest);
+ } else {
+ skin->set_bind_pose(order[i], b.rest);
+ }
+ }
+
+ for (int i = 0; i < len; i++) {
+ //the inverse is what is actually required
+ skin->set_bind_bone(i, i);
+ skin->set_bind_pose(i, skin->get_bind_pose(i).affine_inverse());
+ }
+ }
+
+ ERR_FAIL_COND_V(skin.is_null(), Ref<SkinReference>());
+
+ Ref<SkinReference> skin_ref;
+ skin_ref.instance();
+
+ skin_ref->skeleton_node = this;
+ skin_ref->bind_count = 0;
+ skin_ref->skeleton = VisualServer::get_singleton()->skeleton_create();
+ skin_ref->skeleton_node = this;
+ skin_ref->skin = skin;
+
+ skin_bindings.insert(skin_ref.operator->());
+
+ skin->connect("changed", skin_ref.operator->(), "_skin_changed");
+ return skin_ref;
}
void Skeleton::_bind_methods() {
@@ -773,6 +789,8 @@ void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_rest", "bone_idx"), &Skeleton::get_bone_rest);
ClassDB::bind_method(D_METHOD("set_bone_rest", "bone_idx", "rest"), &Skeleton::set_bone_rest);
+ ClassDB::bind_method(D_METHOD("register_skin", "skin"), &Skeleton::register_skin);
+
ClassDB::bind_method(D_METHOD("localize_rests"), &Skeleton::localize_rests);
ClassDB::bind_method(D_METHOD("set_bone_disable_rest", "bone_idx", "disable"), &Skeleton::set_bone_disable_rest);
@@ -787,17 +805,9 @@ void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton::get_bone_pose);
ClassDB::bind_method(D_METHOD("set_bone_pose", "bone_idx", "pose"), &Skeleton::set_bone_pose);
- ClassDB::bind_method(D_METHOD("set_bone_global_pose", "bone_idx", "pose"), &Skeleton::set_bone_global_pose);
+ ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton::set_bone_global_pose_override, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton::get_bone_global_pose);
- ClassDB::bind_method(D_METHOD("get_bone_custom_pose", "bone_idx"), &Skeleton::get_bone_custom_pose);
- ClassDB::bind_method(D_METHOD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton::set_bone_custom_pose);
-
- ClassDB::bind_method(D_METHOD("get_bone_transform", "bone_idx"), &Skeleton::get_bone_transform);
-
- ClassDB::bind_method(D_METHOD("set_use_bones_in_world_transform", "enable"), &Skeleton::set_use_bones_in_world_transform);
- ClassDB::bind_method(D_METHOD("is_using_bones_in_world_transform"), &Skeleton::is_using_bones_in_world_transform);
-
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation);
@@ -807,22 +817,19 @@ void Skeleton::_bind_methods() {
#endif // _3D_DISABLED
- ClassDB::bind_method(D_METHOD("set_bone_ignore_animation", "bone", "ignore"), &Skeleton::set_bone_ignore_animation);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones_in_world_transform"), "set_use_bones_in_world_transform", "is_using_bones_in_world_transform");
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
}
Skeleton::Skeleton() {
- rest_global_inverse_dirty = true;
dirty = false;
process_order_dirty = true;
- skeleton = VisualServer::get_singleton()->skeleton_create();
- set_notify_transform(true);
- use_bones_in_world_transform = false;
}
Skeleton::~Skeleton() {
- VisualServer::get_singleton()->free(skeleton);
+
+ //some skins may remain bound
+ for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
+ E->get()->skeleton_node = nullptr;
+ }
}
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 5f43b3c6c3..f20c550055 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -33,10 +33,7 @@
#include "core/rid.h"
#include "scene/3d/spatial.h"
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+#include "scene/resources/skin.h"
#ifndef _3D_DISABLED
typedef int BoneId;
@@ -44,10 +41,38 @@ typedef int BoneId;
class PhysicalBone;
#endif // _3D_DISABLED
+class Skeleton;
+
+class SkinReference : public Reference {
+ GDCLASS(SkinReference, Reference)
+ friend class Skeleton;
+
+ Skeleton *skeleton_node;
+ RID skeleton;
+ Ref<Skin> skin;
+ uint32_t bind_count = 0;
+ void _skin_changed();
+
+protected:
+ static void _bind_methods();
+
+public:
+ RID get_skeleton() const;
+ Ref<Skin> get_skin() const;
+ ~SkinReference();
+};
+
class Skeleton : public Spatial {
GDCLASS(Skeleton, Spatial);
+private:
+ friend class SkinReference;
+
+ Set<SkinReference *> skin_bindings;
+
+ void _skin_changed();
+
struct Bone {
String name;
@@ -56,19 +81,15 @@ class Skeleton : public Spatial {
int parent;
int sort_index; //used for re-sorting process order
- bool ignore_animation;
-
bool disable_rest;
Transform rest;
- Transform rest_global_inverse;
Transform pose;
Transform pose_global;
- bool custom_pose_enable;
- Transform custom_pose;
-
- Transform transform_final;
+ float global_pose_override_amount;
+ bool global_pose_override_reset;
+ Transform global_pose_override;
#ifndef _3D_DISABLED
PhysicalBone *physical_bone;
@@ -80,9 +101,9 @@ class Skeleton : public Spatial {
Bone() {
parent = -1;
enabled = true;
- ignore_animation = false;
- custom_pose_enable = false;
disable_rest = false;
+ global_pose_override_amount = 0;
+ global_pose_override_reset = false;
#ifndef _3D_DISABLED
physical_bone = NULL;
cache_parent_physical_bone = NULL;
@@ -90,17 +111,12 @@ class Skeleton : public Spatial {
}
};
- bool rest_global_inverse_dirty;
-
Vector<Bone> bones;
Vector<int> process_order;
bool process_order_dirty;
- RID skeleton;
-
void _make_dirty();
bool dirty;
- bool use_bones_in_world_transform;
// bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
@@ -131,8 +147,6 @@ public:
NOTIFICATION_UPDATE_SKELETON = 50
};
- RID get_skeleton() const;
-
// skeleton creation api
void add_bone(const String &p_name);
int find_bone(const String &p_name) const;
@@ -145,9 +159,6 @@ public:
void unparent_bone_and_rest(int p_bone);
- void set_bone_ignore_animation(int p_bone, bool p_ignore);
- bool is_bone_ignore_animation(int p_bone) const;
-
void set_bone_disable_rest(int p_bone, bool p_disable);
bool is_bone_rest_disabled(int p_bone) const;
@@ -155,10 +166,9 @@ public:
void set_bone_rest(int p_bone, const Transform &p_rest);
Transform get_bone_rest(int p_bone) const;
- Transform get_bone_transform(int p_bone) const;
Transform get_bone_global_pose(int p_bone) const;
- void set_bone_global_pose(int p_bone, const Transform &p_pose);
+ void set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent = false);
void set_bone_enabled(int p_bone, bool p_enabled);
bool is_bone_enabled(int p_bone) const;
@@ -174,14 +184,10 @@ public:
void set_bone_pose(int p_bone, const Transform &p_pose);
Transform get_bone_pose(int p_bone) const;
- void set_bone_custom_pose(int p_bone, const Transform &p_custom_pose);
- Transform get_bone_custom_pose(int p_bone) const;
-
void localize_rests(); // used for loaders and tools
int get_process_order(int p_idx);
- void set_use_bones_in_world_transform(bool p_enable);
- bool is_using_bones_in_world_transform() const;
+ Ref<SkinReference> register_skin(const Ref<Skin> &p_skin);
#ifndef _3D_DISABLED
// Physical bone API
diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp
index 386e127f8b..6c3949a0a8 100644
--- a/scene/3d/soft_body.cpp
+++ b/scene/3d/soft_body.cpp
@@ -577,20 +577,14 @@ Array SoftBody::get_collision_exceptions() {
void SoftBody::add_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
- if (!collision_object) {
- ERR_EXPLAIN("Collision exception only works between two CollisionObject");
- }
- ERR_FAIL_COND(!collision_object);
+ ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
PhysicsServer::get_singleton()->soft_body_add_collision_exception(physics_rid, collision_object->get_rid());
}
void SoftBody::remove_collision_exception_with(Node *p_node) {
ERR_FAIL_NULL(p_node);
CollisionObject *collision_object = Object::cast_to<CollisionObject>(p_node);
- if (!collision_object) {
- ERR_EXPLAIN("Collision exception only works between two CollisionObject");
- }
- ERR_FAIL_COND(!collision_object);
+ ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject.");
PhysicsServer::get_singleton()->soft_body_remove_collision_exception(physics_rid, collision_object->get_rid());
}
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 1a41a31253..df831f92ef 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -684,15 +684,8 @@ void Spatial::look_at(const Vector3 &p_target, const Vector3 &p_up) {
void Spatial::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) {
- if (p_pos == p_target) {
- ERR_EXPLAIN("Node origin and target are in the same position, look_at() failed");
- ERR_FAIL();
- }
-
- if (p_up.cross(p_target - p_pos) == Vector3()) {
- ERR_EXPLAIN("Up vector and direction between node origin and target are aligned, look_at() failed");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed.");
+ ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed.");
Transform lookat;
lookat.origin = p_pos;
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 18a4a5b54d..eea2696767 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -34,10 +34,6 @@
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class SpatialGizmo : public Reference {
GDCLASS(SpatialGizmo, Reference);
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 67c79d8b5a..a9dacc442c 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -286,6 +286,18 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const {
return alpha_cut;
}
+void SpriteBase3D::set_billboard_mode(SpatialMaterial::BillboardMode p_mode) {
+
+ ERR_FAIL_INDEX(p_mode, 3);
+ billboard_mode = p_mode;
+ _queue_update();
+}
+
+SpatialMaterial::BillboardMode SpriteBase3D::get_billboard_mode() const {
+
+ return billboard_mode;
+}
+
void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_centered", "centered"), &SpriteBase3D::set_centered);
@@ -318,6 +330,9 @@ void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_alpha_cut_mode", "mode"), &SpriteBase3D::set_alpha_cut_mode);
ClassDB::bind_method(D_METHOD("get_alpha_cut_mode"), &SpriteBase3D::get_alpha_cut_mode);
+ ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpriteBase3D::set_billboard_mode);
+ ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpriteBase3D::get_billboard_mode);
+
ClassDB::bind_method(D_METHOD("get_item_rect"), &SpriteBase3D::get_item_rect);
ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &SpriteBase3D::generate_triangle_mesh);
@@ -333,6 +348,7 @@ void SpriteBase3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X-Axis,Y-Axis,Z-Axis"), "set_axis", "get_axis");
ADD_GROUP("Flags", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard"), "set_billboard_mode", "get_billboard_mode");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transparent"), "set_draw_flag", "get_draw_flag", FLAG_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shaded"), "set_draw_flag", "get_draw_flag", FLAG_SHADED);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED);
@@ -361,6 +377,7 @@ SpriteBase3D::SpriteBase3D() {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
alpha_cut = ALPHA_CUT_DISABLED;
+ billboard_mode = SpatialMaterial::BILLBOARD_DISABLED;
axis = Vector3::AXIS_Z;
pixel_size = 0.01;
modulate = Color(1, 1, 1, 1);
@@ -463,7 +480,7 @@ void Sprite3D::_draw() {
tangent = Plane(1, 0, 0, 1);
}
- RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
+ RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y);
VS::get_singleton()->immediate_set_material(immediate, mat);
VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid());
@@ -558,12 +575,15 @@ Rect2 Sprite3D::get_region_rect() const {
void Sprite3D::set_frame(int p_frame) {
- ERR_FAIL_INDEX(p_frame, vframes * hframes);
+ ERR_FAIL_INDEX(p_frame, int64_t(vframes) * hframes);
if (frame != p_frame)
frame = p_frame;
_queue_update();
+
+ _change_notify("frame");
+ _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -572,6 +592,17 @@ int Sprite3D::get_frame() const {
return frame;
}
+void Sprite3D::set_frame_coords(const Vector2 &p_coord) {
+ ERR_FAIL_INDEX(int(p_coord.x), vframes);
+ ERR_FAIL_INDEX(int(p_coord.y), hframes);
+
+ set_frame(int(p_coord.y) * hframes + int(p_coord.x));
+}
+
+Vector2 Sprite3D::get_frame_coords() const {
+ return Vector2(frame % hframes, frame / hframes);
+}
+
void Sprite3D::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
@@ -628,10 +659,9 @@ Rect2 Sprite3D::get_item_rect() const {
void Sprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame") {
-
- property.hint = PROPERTY_HINT_SPRITE_FRAME;
-
+ property.hint = PROPERTY_HINT_RANGE;
property.hint_string = "0," + itos(vframes * hframes - 1) + ",1";
+ property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
}
@@ -649,6 +679,9 @@ void Sprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite3D::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &Sprite3D::get_frame);
+ ClassDB::bind_method(D_METHOD("set_frame_coords", "coords"), &Sprite3D::set_frame_coords);
+ ClassDB::bind_method(D_METHOD("get_frame_coords"), &Sprite3D::get_frame_coords);
+
ClassDB::bind_method(D_METHOD("set_vframes", "vframes"), &Sprite3D::set_vframes);
ClassDB::bind_method(D_METHOD("get_vframes"), &Sprite3D::get_vframes);
@@ -659,7 +692,8 @@ void Sprite3D::_bind_methods() {
ADD_GROUP("Animation", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords");
ADD_GROUP("Region", "region_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
@@ -771,7 +805,7 @@ void AnimatedSprite3D::_draw() {
tangent = Plane(1, 0, 0, -1);
}
- RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
+ RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y);
VS::get_singleton()->immediate_set_material(immediate, mat);
@@ -851,14 +885,11 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
}
if (property.name == "frame") {
-
property.hint = PROPERTY_HINT_RANGE;
-
- if (frames->has_animation(animation)) {
+ if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) {
property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1";
- } else {
- property.hint_string = "0,0,0";
}
+ property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
}
@@ -1091,7 +1122,7 @@ void AnimatedSprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing");
}
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index 0e086ef31e..065931de84 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -80,6 +80,7 @@ private:
bool flags[FLAG_MAX];
AlphaCutMode alpha_cut;
+ SpatialMaterial::BillboardMode billboard_mode;
bool pending_update;
void _im_update();
@@ -130,6 +131,8 @@ public:
void set_alpha_cut_mode(AlphaCutMode p_mode);
AlphaCutMode get_alpha_cut_mode() const;
+ void set_billboard_mode(SpatialMaterial::BillboardMode p_mode);
+ SpatialMaterial::BillboardMode get_billboard_mode() const;
virtual Rect2 get_item_rect() const = 0;
@@ -173,6 +176,9 @@ public:
void set_frame(int p_frame);
int get_frame() const;
+ void set_frame_coords(const Vector2 &p_coord);
+ Vector2 get_frame_coords() const;
+
void set_vframes(int p_amount);
int get_vframes() const;
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 89e96e0227..98e68cfbda 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -272,6 +272,20 @@ void VehicleWheel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rpm"), &VehicleWheel::get_rpm);
+ ClassDB::bind_method(D_METHOD("set_engine_force", "engine_force"), &VehicleWheel::set_engine_force);
+ ClassDB::bind_method(D_METHOD("get_engine_force"), &VehicleWheel::get_engine_force);
+
+ ClassDB::bind_method(D_METHOD("set_brake", "brake"), &VehicleWheel::set_brake);
+ ClassDB::bind_method(D_METHOD("get_brake"), &VehicleWheel::get_brake);
+
+ ClassDB::bind_method(D_METHOD("set_steering", "steering"), &VehicleWheel::set_steering);
+ ClassDB::bind_method(D_METHOD("get_steering"), &VehicleWheel::get_steering);
+
+ ADD_GROUP("Per-Wheel Motion", "");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering");
+ ADD_GROUP("VehicleBody Motion", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_traction"), "set_use_as_traction", "is_used_as_traction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_steering"), "set_use_as_steering", "is_used_as_steering");
ADD_GROUP("Wheel", "wheel_");
@@ -288,6 +302,34 @@ void VehicleWheel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation");
}
+void VehicleWheel::set_engine_force(float p_engine_force) {
+
+ m_engineForce = p_engine_force;
+}
+
+float VehicleWheel::get_engine_force() const {
+
+ return m_engineForce;
+}
+
+void VehicleWheel::set_brake(float p_brake) {
+
+ m_brake = p_brake;
+}
+float VehicleWheel::get_brake() const {
+
+ return m_brake;
+}
+
+void VehicleWheel::set_steering(float p_steering) {
+
+ m_steering = p_steering;
+}
+float VehicleWheel::get_steering() const {
+
+ return m_steering;
+}
+
void VehicleWheel::set_use_as_traction(bool p_enable) {
engine_traction = p_enable;
@@ -374,10 +416,7 @@ void VehicleBody::_update_wheel(int p_idx, PhysicsDirectBodyState *s) {
Vector3 fwd = up.cross(right);
fwd = fwd.normalized();
- //rotate around steering over de wheelAxleWS
- real_t steering = wheel.steers ? m_steeringValue : 0.0;
-
- Basis steeringMat(up, steering);
+ Basis steeringMat(up, wheel.m_steering);
Basis rotatingMat(right, wheel.m_rotation);
@@ -723,12 +762,11 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
real_t rollingFriction = 0.f;
if (wheelInfo.m_raycastInfo.m_isInContact) {
- if (engine_force != 0.f && wheelInfo.engine_traction) {
- rollingFriction = -engine_force * s->get_step();
+ if (wheelInfo.m_engineForce != 0.f) {
+ rollingFriction = -wheelInfo.m_engineForce * s->get_step();
} else {
real_t defaultRollingFrictionImpulse = 0.f;
- float cbrake = MAX(wheelInfo.m_brake, brake);
- real_t maxImpulse = cbrake ? cbrake : defaultRollingFrictionImpulse;
+ real_t maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
btVehicleWheelContactPoint contactPt(s, wheelInfo.m_raycastInfo.m_groundObject, wheelInfo.m_raycastInfo.m_contactPointWS, m_forwardWS[wheel], maxImpulse);
rollingFriction = _calc_rolling_friction(contactPt);
}
@@ -886,6 +924,11 @@ void VehicleBody::_direct_state_changed(Object *p_state) {
void VehicleBody::set_engine_force(float p_engine_force) {
engine_force = p_engine_force;
+ for (int i = 0; i < wheels.size(); i++) {
+ VehicleWheel &wheelInfo = *wheels[i];
+ if (wheelInfo.engine_traction)
+ wheelInfo.m_engineForce = p_engine_force;
+ }
}
float VehicleBody::get_engine_force() const {
@@ -896,6 +939,10 @@ float VehicleBody::get_engine_force() const {
void VehicleBody::set_brake(float p_brake) {
brake = p_brake;
+ for (int i = 0; i < wheels.size(); i++) {
+ VehicleWheel &wheelInfo = *wheels[i];
+ wheelInfo.m_brake = p_brake;
+ }
}
float VehicleBody::get_brake() const {
@@ -905,6 +952,11 @@ float VehicleBody::get_brake() const {
void VehicleBody::set_steering(float p_steering) {
m_steeringValue = p_steering;
+ for (int i = 0; i < wheels.size(); i++) {
+ VehicleWheel &wheelInfo = *wheels[i];
+ if (wheelInfo.steers)
+ wheelInfo.m_steering = p_steering;
+ }
}
float VehicleBody::get_steering() const {
diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h
index 9e3fe72282..914bfd54bd 100644
--- a/scene/3d/vehicle_body.h
+++ b/scene/3d/vehicle_body.h
@@ -70,7 +70,7 @@ class VehicleWheel : public Spatial {
real_t m_deltaRotation;
real_t m_rpm;
real_t m_rollInfluence;
- //real_t m_engineForce;
+ real_t m_engineForce;
real_t m_brake;
real_t m_clippedInvContactDotSuspension;
@@ -137,6 +137,15 @@ public:
float get_rpm() const;
+ void set_engine_force(float p_engine_force);
+ float get_engine_force() const;
+
+ void set_brake(float p_brake);
+ float get_brake() const;
+
+ void set_steering(float p_steering);
+ float get_steering() const;
+
String get_configuration_warning() const;
VehicleWheel();
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 5141c84803..d1de0c56a7 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -215,17 +215,6 @@ float GeometryInstance::get_lod_max_hysteresis() const {
}
void GeometryInstance::_notification(int p_what) {
-
- if (p_what == NOTIFICATION_ENTER_WORLD) {
-
- if (flags[FLAG_USE_BAKED_LIGHT]) {
- }
-
- } else if (p_what == NOTIFICATION_EXIT_WORLD) {
-
- if (flags[FLAG_USE_BAKED_LIGHT]) {
- }
- }
}
void GeometryInstance::set_flag(Flags p_flag, bool p_value) {
@@ -236,8 +225,6 @@ void GeometryInstance::set_flag(Flags p_flag, bool p_value) {
flags[p_flag] = p_value;
VS::get_singleton()->instance_geometry_set_flag(get_instance(), (VS::InstanceFlags)p_flag, p_value);
- if (p_flag == FLAG_USE_BAKED_LIGHT) {
- }
}
bool GeometryInstance::get_flag(Flags p_flag) const {
diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h
index 3b924e0454..63d15680aa 100644
--- a/scene/3d/visual_instance.h
+++ b/scene/3d/visual_instance.h
@@ -35,9 +35,7 @@
#include "core/rid.h"
#include "scene/3d/spatial.h"
#include "scene/resources/material.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class VisualInstance : public Spatial {
GDCLASS(VisualInstance, Spatial);
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index bf36a0a532..656e16371f 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -33,10 +33,6 @@
#include "scene/3d/spatial.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class WorldEnvironment : public Node {
GDCLASS(WorldEnvironment, Node);
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index dded44b990..416a291da1 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -266,7 +266,7 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
// fill in weights
- if (point_lower == -1) {
+ if (point_lower == -1 && point_higher != -1) {
// we are on the left side, no other point to the left
// we just play the next point.
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 95d4644004..75031f0149 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -527,7 +527,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
}
- if (new_closest != closest) {
+ if (new_closest != closest && new_closest != -1) {
float from = 0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index 84b3f103c5..e26bd5b5a1 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -80,8 +80,7 @@ void AnimationCache::_update_cache() {
if (!node) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Invalid Track Path in Animation: " + np);
- ERR_CONTINUE(!node);
+ ERR_CONTINUE_MSG(!node, "Invalid track path in animation: " + np + ".");
}
Path path;
@@ -92,8 +91,7 @@ void AnimationCache::_update_cache() {
if (np.get_subname_count() > 1) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Transform tracks can't have a subpath: " + np);
- ERR_CONTINUE(animation->track_get_type(i) == Animation::TYPE_TRANSFORM);
+ ERR_CONTINUE_MSG(animation->track_get_type(i) == Animation::TYPE_TRANSFORM, "Transform tracks can't have a subpath: " + np + ".");
}
Spatial *sp = Object::cast_to<Spatial>(node);
@@ -101,8 +99,7 @@ void AnimationCache::_update_cache() {
if (!sp) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Transform track not of type Spatial: " + np);
- ERR_CONTINUE(!sp);
+ ERR_CONTINUE_MSG(!sp, "Transform track not of type Spatial: " + np + ".");
}
if (np.get_subname_count() == 1) {
@@ -113,15 +110,13 @@ void AnimationCache::_update_cache() {
if (!sk) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Property defined in Transform track, but not a Skeleton!: " + np);
- ERR_CONTINUE(!sk);
+ ERR_CONTINUE_MSG(!sk, "Property defined in Transform track, but not a Skeleton!: " + np + ".");
}
int idx = sk->find_bone(ps);
if (idx == -1) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Property defined in Transform track, but not a Skeleton Bone!: " + np);
- ERR_CONTINUE(idx == -1);
+ ERR_CONTINUE_MSG(idx == -1, "Property defined in Transform track, but not a Skeleton Bone!: " + np + ".");
}
path.bone_idx = idx;
@@ -161,8 +156,7 @@ void AnimationCache::_update_cache() {
if (np.get_subname_count() == 0) {
path_cache.push_back(Path());
- ERR_EXPLAIN("Value Track lacks property: " + np);
- ERR_CONTINUE(np.get_subname_count() == 0);
+ ERR_CONTINUE_MSG(np.get_subname_count() == 0, "Value Track lacks property: " + np + ".");
}
} else if (animation->track_get_type(i) == Animation::TYPE_METHOD) {
@@ -170,8 +164,7 @@ void AnimationCache::_update_cache() {
if (path.subpath.size() != 0) { // Trying to call a method of a non-resource
path_cache.push_back(Path());
- ERR_EXPLAIN("Method Track has property: " + np);
- ERR_CONTINUE(path.subpath.size() != 0);
+ ERR_CONTINUE_MSG(path.subpath.size() != 0, "Method Track has property: " + np + ".");
}
}
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index f1ce948c43..65bf1e0134 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -235,6 +235,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
if (cost < least_cost) {
least_cost_transition = E;
+ least_cost = cost;
}
}
@@ -316,8 +317,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
if (!playing) {
String node_name = start_request;
start_request = StringName();
- ERR_EXPLAIN("Can't travel to '" + node_name + "' if state machine is not playing.");
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing.");
}
if (!_travel(p_state_machine, start_request)) {
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 54df346374..728c23fbaa 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -248,10 +248,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
RES resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
- if (!child) {
- ERR_EXPLAIN("On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'");
- }
- ERR_CONTINUE(!child); // couldn't find the child node
+ ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node
uint32_t id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
int bone_idx = -1;
@@ -259,7 +256,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
Skeleton *sk = Object::cast_to<Skeleton>(child);
bone_idx = sk->find_bone(a->track_get_path(i).get_subname(0));
- if (bone_idx == -1 || sk->is_bone_ignore_animation(bone_idx)) {
+ if (bone_idx == -1) {
continue;
}
@@ -973,8 +970,7 @@ void AnimationPlayer::_animation_process(float p_delta) {
Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animation> &p_animation) {
#ifdef DEBUG_ENABLED
- ERR_EXPLAIN("Invalid animation name: " + String(p_name));
- ERR_FAIL_COND_V(String(p_name).find("/") != -1 || String(p_name).find(":") != -1 || String(p_name).find(",") != -1 || String(p_name).find("[") != -1, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(String(p_name).find("/") != -1 || String(p_name).find(":") != -1 || String(p_name).find(",") != -1 || String(p_name).find("[") != -1, ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
#endif
ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER);
@@ -1158,10 +1154,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
if (String(name) == "")
name = playback.assigned;
- if (!animation_set.has(name)) {
- ERR_EXPLAIN("Animation not found: " + name);
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(!animation_set.has(name), "Animation not found: " + name + ".");
Playback &c = playback;
@@ -1207,7 +1200,9 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
}
}
- _stop_playing_caches();
+ if (get_current_animation() != p_name) {
+ _stop_playing_caches();
+ }
c.current.from = &animation_set[name];
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index f3d38110c6..320fd2084c 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -35,9 +35,6 @@
#include "scene/3d/skeleton.h"
#include "scene/3d/spatial.h"
#include "scene/resources/animation.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#ifdef TOOLS_ENABLED
// To save/restore animated values
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 6745b57cff..eb152bc41e 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -622,7 +622,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
Skeleton *sk = Object::cast_to<Skeleton>(spatial);
int bone_idx = sk->find_bone(path.get_subname(0));
- if (bone_idx != -1 && !sk->is_bone_ignore_animation(bone_idx)) {
+ if (bone_idx != -1) {
track_xform->skeleton = sk;
track_xform->bone_idx = bone_idx;
@@ -1412,6 +1412,7 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A
Vector<Activity> activity;
for (int i = 0; i < node->get_input_count(); i++) {
Activity a;
+ a.activity = 0;
a.last_pass = 0;
activity.push_back(a);
}
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 5c3e123ac3..ba5936562a 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -403,8 +403,7 @@ void AnimationTreePlayer::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- ERR_EXPLAIN("AnimationTreePlayer has been deprecated. Use AnimationTree instead.");
- WARN_DEPRECATED;
+ WARN_DEPRECATED_MSG("AnimationTreePlayer has been deprecated. Use AnimationTree instead.");
if (!processing) {
//make sure that a previous process state was not saved
@@ -821,11 +820,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
t.value = t.object->get_indexed(t.subpath);
t.value.zero();
- if (t.skeleton) {
- t.skip = t.skeleton->is_bone_ignore_animation(t.bone_idx);
- } else {
- t.skip = false;
- }
+ t.skip = false;
}
/* STEP 2 PROCESS ANIMATIONS */
@@ -993,10 +988,9 @@ int AnimationTreePlayer::node_get_input_count(const StringName &p_node) const {
ERR_FAIL_COND_V(!node_map.has(p_node), -1);
return node_map[p_node]->inputs.size();
}
-#define GET_NODE(m_type, m_cast) \
- ERR_FAIL_COND(!node_map.has(p_node)); \
- ERR_EXPLAIN("Invalid parameter for node type."); \
- ERR_FAIL_COND(node_map[p_node]->type != m_type); \
+#define GET_NODE(m_type, m_cast) \
+ ERR_FAIL_COND(!node_map.has(p_node)); \
+ ERR_FAIL_COND_MSG(node_map[p_node]->type != m_type, "Invalid parameter for node type."); \
m_cast *n = static_cast<m_cast *>(node_map[p_node]);
void AnimationTreePlayer::animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation) {
@@ -1209,10 +1203,9 @@ Point2 AnimationTreePlayer::node_get_position(const StringName &p_node) const {
return node_map[p_node]->pos;
}
-#define GET_NODE_V(m_type, m_cast, m_ret) \
- ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \
- ERR_EXPLAIN("Invalid parameter for node type."); \
- ERR_FAIL_COND_V(node_map[p_node]->type != m_type, m_ret); \
+#define GET_NODE_V(m_type, m_cast, m_ret) \
+ ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \
+ ERR_FAIL_COND_V_MSG(node_map[p_node]->type != m_type, m_ret, "Invalid parameter for node type."); \
m_cast *n = static_cast<m_cast *>(node_map[p_node]);
Ref<Animation> AnimationTreePlayer::animation_node_get_animation(const StringName &p_node) const {
@@ -1367,8 +1360,7 @@ void AnimationTreePlayer::get_node_list(List<StringName> *p_node_list) const {
void AnimationTreePlayer::remove_node(const StringName &p_node) {
ERR_FAIL_COND(!node_map.has(p_node));
- ERR_EXPLAIN("Node 0 (output) can't be removed.");
- ERR_FAIL_COND(p_node == out_name);
+ ERR_FAIL_COND_MSG(p_node == out_name, "Node 0 (output) can't be removed.");
for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp
index 7a1b10792b..4ec22cf3df 100644
--- a/scene/animation/skeleton_ik.cpp
+++ b/scene/animation/skeleton_ik.cpp
@@ -320,7 +320,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
}
- p_task->skeleton->set_bone_global_pose(ci->bone, new_bone_pose);
+ p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0);
if (!ci->children.empty())
ci = &ci->children.write[0];
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 4dee4e1d12..1f9793190d 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -191,7 +191,7 @@ void Tween::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Are we processing during 'regular' time?
if (tween_process_mode == TWEEN_PROCESS_IDLE)
- // Do nothing since we whould only process during idle time
+ // Do nothing since we would only process during idle time
break;
// Should we update?
@@ -783,10 +783,12 @@ float Tween::get_speed_scale() const {
}
bool Tween::start() {
+
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), false, "Tween was not added to the SceneTree!");
+
// Are there any pending updates?
if (pending_update != 0) {
// Start the tweens after deferring
- call_deferred("start");
return true;
}
@@ -1185,35 +1187,29 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Validate and apply interpolation data
// Give it the object
- ERR_EXPLAIN("Invalid object provided to Tween!");
- ERR_FAIL_COND_V(p_object == NULL, false); // Is the object real
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); // Is the object a valid instance?
+ ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween.");
+ ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween.");
data.id = p_object->get_instance_id();
// Validate the initial and final values
- ERR_EXPLAIN("Initial value type does not match final value type!"); // TODO: Print both types to make debugging easier
- ERR_FAIL_COND_V(p_initial_val.get_type() != p_final_val.get_type(), false); // Do the initial and final value types match?
+ ERR_FAIL_COND_V_MSG(p_initial_val.get_type() != p_final_val.get_type(), false, "Initial value type '" + Variant::get_type_name(p_initial_val.get_type()) + "' does not match final value type '" + Variant::get_type_name(p_final_val.get_type()) + "'.");
data.initial_val = p_initial_val;
data.final_val = p_final_val;
// Check the Duration
- ERR_EXPLAIN("Only non-negative duration values allowed in Tweens!");
- ERR_FAIL_COND_V(p_duration < 0, false); // Is the tween duration non-negative
+ ERR_FAIL_COND_V_MSG(p_duration < 0, false, "Only non-negative duration values allowed in Tweens.");
data.duration = p_duration;
// Tween Delay
- ERR_EXPLAIN("Only non-negative delay values allowed in Tweens!");
- ERR_FAIL_COND_V(p_delay < 0, false); // Is the delay non-negative?
+ ERR_FAIL_COND_V_MSG(p_delay < 0, false, "Only non-negative delay values allowed in Tweens.");
data.delay = p_delay;
// Transition type
- ERR_EXPLAIN("Invalid transition type provided to Tween");
- ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false); // Is the transition type valid
+ ERR_FAIL_COND_V_MSG(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false, "Invalid transition type provided to Tween.");
data.trans_type = p_trans_type;
// Easing type
- ERR_EXPLAIN("Invalid easing type provided to Tween");
- ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false); // Is the easing type valid
+ ERR_FAIL_COND_V_MSG(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false, "Invalid easing type provided to Tween.");
data.ease_type = p_ease_type;
// Is the property defined?
@@ -1221,8 +1217,7 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Check that the object actually contains the given property
bool prop_valid = false;
p_object->get_indexed(p_property->get_subnames(), &prop_valid);
- ERR_EXPLAIN("Tween target object has no property named: " + p_property->get_concatenated_subnames());
- ERR_FAIL_COND_V(!prop_valid, false);
+ ERR_FAIL_COND_V_MSG(!prop_valid, false, "Tween target object has no property named: " + p_property->get_concatenated_subnames() + ".");
data.key = p_property->get_subnames();
data.concatenated_key = p_property->get_concatenated_subnames();
@@ -1231,8 +1226,7 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Is the method defined?
if (p_method) {
// Does the object even have the requested method?
- ERR_EXPLAIN("Tween target object has no method named: " + *p_method); // TODO: Fix this error message
- ERR_FAIL_COND_V(!p_object->has_method(*p_method), false);
+ ERR_FAIL_COND_V_MSG(!p_object->has_method(*p_method), false, "Tween target object has no method named: " + *p_method + ".");
data.key.push_back(*p_method);
data.concatenated_key = *p_method;
@@ -1301,8 +1295,7 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
ERR_FAIL_COND_V(p_duration < 0, false);
// Check whether the object even has the callback
- ERR_EXPLAIN("Object has no callback named: %s" + p_callback);
- ERR_FAIL_COND_V(!p_object->has_method(p_callback), false);
+ ERR_FAIL_COND_V_MSG(!p_object->has_method(p_callback), false, "Object has no callback named: " + p_callback + ".");
// Build a new InterpolationData
InterpolateData data;
@@ -1361,8 +1354,7 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
ERR_FAIL_COND_V(p_duration < 0, false);
// Confirm the callback exists on the object
- ERR_EXPLAIN("Object has no callback named: %s" + p_callback);
- ERR_FAIL_COND_V(!p_object->has_method(p_callback), false);
+ ERR_FAIL_COND_V_MSG(!p_object->has_method(p_callback), false, "Object has no callback named: " + p_callback + ".");
// Create a new InterpolateData for the callback
InterpolateData data;
@@ -1505,10 +1497,8 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
ERR_FAIL_COND_V(p_delay < 0, false);
// Confirm both objects have the target methods
- ERR_EXPLAIN("Object has no method named: %s" + p_method);
- ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
- ERR_EXPLAIN("Target has no method named: %s" + p_target_method);
- ERR_FAIL_COND_V(!p_target->has_method(p_target_method), false);
+ ERR_FAIL_COND_V_MSG(!p_object->has_method(p_method), false, "Object has no method named: " + p_method + ".");
+ ERR_FAIL_COND_V_MSG(!p_target->has_method(p_target_method), false, "Target has no method named: " + p_target_method + ".");
// Call the method to get the target value
Variant::CallError error;
@@ -1641,10 +1631,8 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
ERR_FAIL_COND_V(p_delay < 0, false);
// Make sure both objects have the given method
- ERR_EXPLAIN("Object has no method named: %s" + p_method);
- ERR_FAIL_COND_V(!p_object->has_method(p_method), false);
- ERR_EXPLAIN("Initial Object has no method named: %s" + p_initial_method);
- ERR_FAIL_COND_V(!p_initial->has_method(p_initial_method), false);
+ ERR_FAIL_COND_V_MSG(!p_object->has_method(p_method), false, "Object has no method named: " + p_method + ".");
+ ERR_FAIL_COND_V_MSG(!p_initial->has_method(p_initial_method), false, "Initial Object has no method named: " + p_initial_method + ".");
// Call the method to get the initial value
Variant::CallError error;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 52fcea2a71..4f71481280 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -115,9 +115,6 @@ void BaseButton::_notification(int p_what) {
}
}
- if (p_what == NOTIFICATION_ENTER_TREE) {
- }
-
if (p_what == NOTIFICATION_EXIT_TREE || (p_what == NOTIFICATION_VISIBILITY_CHANGED && !is_visible_in_tree())) {
if (!toggle_mode) {
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index ffccdd69d6..2773f024df 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -32,9 +32,6 @@
#define BASE_BUTTON_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class ButtonGroup;
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 65e9cccd05..6b3e89af6c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -39,158 +39,191 @@ Size2 Button::get_minimum_size() const {
if (clip_text)
minsize.width = 0;
- Ref<Texture> _icon;
- if (icon.is_null() && has_icon("icon"))
- _icon = Control::get_icon("icon");
- else
- _icon = icon;
-
- if (!_icon.is_null()) {
-
- minsize.height = MAX(minsize.height, _icon->get_height());
- minsize.width += _icon->get_width();
- if (xl_text != "")
- minsize.width += get_constant("hseparation");
+ if (!expand_icon) {
+ Ref<Texture> _icon;
+ if (icon.is_null() && has_icon("icon"))
+ _icon = Control::get_icon("icon");
+ else
+ _icon = icon;
+
+ if (!_icon.is_null()) {
+
+ minsize.height = MAX(minsize.height, _icon->get_height());
+ minsize.width += _icon->get_width();
+ if (xl_text != "")
+ minsize.width += get_constant("hseparation");
+ }
}
return get_stylebox("normal")->get_minimum_size() + minsize;
}
void Button::_set_internal_margin(Margin p_margin, float p_value) {
+
_internal_margin[p_margin] = p_value;
}
void Button::_notification(int p_what) {
- if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
+ switch (p_what) {
+ case NOTIFICATION_TRANSLATION_CHANGED: {
- xl_text = tr(text);
- minimum_size_changed();
- update();
- }
+ xl_text = tr(text);
+ minimum_size_changed();
+ update();
+ } break;
+ case NOTIFICATION_DRAW: {
- if (p_what == NOTIFICATION_DRAW) {
+ RID ci = get_canvas_item();
+ Size2 size = get_size();
+ Color color;
+ Color color_icon(1, 1, 1, 1);
- RID ci = get_canvas_item();
- Size2 size = get_size();
- Color color;
- Color color_icon(1, 1, 1, 1);
+ Ref<StyleBox> style = get_stylebox("normal");
- Ref<StyleBox> style = get_stylebox("normal");
+ switch (get_draw_mode()) {
+ case DRAW_NORMAL: {
- switch (get_draw_mode()) {
-
- case DRAW_NORMAL: {
+ style = get_stylebox("normal");
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
+ color = get_color("font_color");
+ if (has_color("icon_color_normal"))
+ color_icon = get_color("icon_color_normal");
+ } break;
+ case DRAW_HOVER_PRESSED: {
+
+ if (has_stylebox("hover_pressed") && has_stylebox_override("hover_pressed")) {
+ style = get_stylebox("hover_pressed");
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
+ if (has_color("font_color_hover_pressed"))
+ color = get_color("font_color_hover_pressed");
+ else
+ color = get_color("font_color");
+ if (has_color("icon_color_hover_pressed"))
+ color_icon = get_color("icon_color_hover_pressed");
+
+ break;
+ }
+ FALLTHROUGH;
+ }
+ case DRAW_PRESSED: {
- style = get_stylebox("normal");
- if (!flat)
- style->draw(ci, Rect2(Point2(0, 0), size));
- color = get_color("font_color");
- if (has_color("icon_color_normal"))
- color_icon = get_color("icon_color_normal");
- } break;
- case DRAW_HOVER_PRESSED: {
- if (has_stylebox("hover_pressed") && has_stylebox_override("hover_pressed")) {
- style = get_stylebox("hover_pressed");
+ style = get_stylebox("pressed");
if (!flat)
style->draw(ci, Rect2(Point2(0, 0), size));
- if (has_color("font_color_hover_pressed"))
- color = get_color("font_color_hover_pressed");
+ if (has_color("font_color_pressed"))
+ color = get_color("font_color_pressed");
else
color = get_color("font_color");
- if (has_color("icon_color_hover_pressed"))
- color_icon = get_color("icon_color_hover_pressed");
+ if (has_color("icon_color_pressed"))
+ color_icon = get_color("icon_color_pressed");
- break;
- }
- FALLTHROUGH;
+ } break;
+ case DRAW_HOVER: {
+
+ style = get_stylebox("hover");
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
+ color = get_color("font_color_hover");
+ if (has_color("icon_color_hover"))
+ color_icon = get_color("icon_color_hover");
+
+ } break;
+ case DRAW_DISABLED: {
+
+ style = get_stylebox("disabled");
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
+ color = get_color("font_color_disabled");
+ if (has_color("icon_color_disabled"))
+ color_icon = get_color("icon_color_disabled");
+
+ } break;
}
- case DRAW_PRESSED: {
-
- style = get_stylebox("pressed");
- if (!flat)
- style->draw(ci, Rect2(Point2(0, 0), size));
- if (has_color("font_color_pressed"))
- color = get_color("font_color_pressed");
- else
- color = get_color("font_color");
- if (has_color("icon_color_pressed"))
- color_icon = get_color("icon_color_pressed");
-
- } break;
- case DRAW_HOVER: {
-
- style = get_stylebox("hover");
- if (!flat)
- style->draw(ci, Rect2(Point2(0, 0), size));
- color = get_color("font_color_hover");
- if (has_color("icon_color_hover"))
- color_icon = get_color("icon_color_hover");
-
- } break;
- case DRAW_DISABLED: {
-
- style = get_stylebox("disabled");
- if (!flat)
- style->draw(ci, Rect2(Point2(0, 0), size));
- color = get_color("font_color_disabled");
- if (has_color("icon_color_disabled"))
- color_icon = get_color("icon_color_disabled");
-
- } break;
- }
- if (has_focus()) {
+ if (has_focus()) {
- Ref<StyleBox> style2 = get_stylebox("focus");
- style2->draw(ci, Rect2(Point2(), size));
- }
+ Ref<StyleBox> style2 = get_stylebox("focus");
+ style2->draw(ci, Rect2(Point2(), size));
+ }
- Ref<Font> font = get_font("font");
- Ref<Texture> _icon;
- if (icon.is_null() && has_icon("icon"))
- _icon = Control::get_icon("icon");
- else
- _icon = icon;
+ Ref<Font> font = get_font("font");
+ Ref<Texture> _icon;
+ if (icon.is_null() && has_icon("icon"))
+ _icon = Control::get_icon("icon");
+ else
+ _icon = icon;
+
+ Rect2 icon_region = Rect2();
+ if (!_icon.is_null()) {
- Point2 icon_ofs = (!_icon.is_null()) ? Point2(_icon->get_width() + get_constant("hseparation"), 0) : Point2();
- int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width;
- Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size(xl_text) - Point2(_internal_margin[MARGIN_RIGHT] - _internal_margin[MARGIN_LEFT], 0)) / 2.0;
-
- switch (align) {
- case ALIGN_LEFT: {
- text_ofs.x = style->get_margin(MARGIN_LEFT) + icon_ofs.x + _internal_margin[MARGIN_LEFT] + get_constant("hseparation");
- text_ofs.y += style->get_offset().y;
- } break;
- case ALIGN_CENTER: {
- if (text_ofs.x < 0)
- text_ofs.x = 0;
- text_ofs += icon_ofs;
- text_ofs += style->get_offset();
- } break;
- case ALIGN_RIGHT: {
- if (_internal_margin[MARGIN_RIGHT] > 0) {
- text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x - _internal_margin[MARGIN_RIGHT] - get_constant("hseparation");
+ int valign = size.height - style->get_minimum_size().y;
+ if (is_disabled()) {
+ color_icon.a = 0.4;
+ }
+
+ float icon_ofs_region = 0;
+ if (_internal_margin[MARGIN_LEFT] > 0) {
+ icon_ofs_region = _internal_margin[MARGIN_LEFT] + get_constant("hseparation");
+ }
+
+ if (expand_icon) {
+ Size2 _size = get_size() - style->get_offset() * 2;
+ _size.width -= get_constant("hseparation") + icon_ofs_region;
+ if (!clip_text)
+ _size.width -= get_font("font")->get_string_size(xl_text).width;
+ float icon_width = icon->get_width() * _size.height / icon->get_height();
+ float icon_height = _size.height;
+
+ if (icon_width > _size.width) {
+ icon_width = _size.width;
+ icon_height = icon->get_height() * icon_width / icon->get_width();
+ }
+
+ icon_region = Rect2(style->get_offset() + Point2(icon_ofs_region, (_size.height - icon_height) / 2), Size2(icon_width, icon_height));
} else {
- text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x;
+ icon_region = Rect2(style->get_offset() + Point2(icon_ofs_region, Math::floor((valign - _icon->get_height()) / 2.0)), icon->get_size());
}
- text_ofs.y += style->get_offset().y;
- } break;
- }
+ }
- text_ofs.y += font->get_ascent();
- font->draw(ci, text_ofs.floor(), xl_text, color, clip_text ? text_clip : -1);
- if (!_icon.is_null()) {
+ Point2 icon_ofs = !_icon.is_null() ? Point2(icon_region.size.width + get_constant("hseparation"), 0) : Point2();
+ int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width;
+ Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size(xl_text) - Point2(_internal_margin[MARGIN_RIGHT] - _internal_margin[MARGIN_LEFT], 0)) / 2.0;
+
+ switch (align) {
+ case ALIGN_LEFT: {
+ if (_internal_margin[MARGIN_LEFT] > 0) {
+ text_ofs.x = style->get_margin(MARGIN_LEFT) + icon_ofs.x + _internal_margin[MARGIN_LEFT] + get_constant("hseparation");
+ } else {
+ text_ofs.x = style->get_margin(MARGIN_LEFT) + icon_ofs.x;
+ }
+ text_ofs.y += style->get_offset().y;
+ } break;
+ case ALIGN_CENTER: {
+ if (text_ofs.x < 0)
+ text_ofs.x = 0;
+ text_ofs += icon_ofs;
+ text_ofs += style->get_offset();
+ } break;
+ case ALIGN_RIGHT: {
+ if (_internal_margin[MARGIN_RIGHT] > 0) {
+ text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x - _internal_margin[MARGIN_RIGHT] - get_constant("hseparation");
+ } else {
+ text_ofs.x = size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size(xl_text).x;
+ }
+ text_ofs.y += style->get_offset().y;
+ } break;
+ }
+
+ text_ofs.y += font->get_ascent();
+ font->draw(ci, text_ofs.floor(), xl_text, color, clip_text ? text_clip : -1);
- int valign = size.height - style->get_minimum_size().y;
- if (is_disabled())
- color_icon.a = 0.4;
- if (_internal_margin[MARGIN_LEFT] > 0) {
- _icon->draw(ci, style->get_offset() + Point2(_internal_margin[MARGIN_LEFT] + get_constant("hseparation"), Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
- } else {
- _icon->draw(ci, style->get_offset() + Point2(0, Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
+ if (!_icon.is_null() && icon_region.size.width > 0) {
+ draw_texture_rect_region(_icon, icon_region, Rect2(Point2(), icon->get_size()), color_icon);
}
- }
+ } break;
}
}
@@ -224,6 +257,18 @@ Ref<Texture> Button::get_icon() const {
return icon;
}
+void Button::set_expand_icon(bool p_expand_icon) {
+
+ expand_icon = p_expand_icon;
+ update();
+ minimum_size_changed();
+}
+
+bool Button::is_expand_icon() const {
+
+ return expand_icon;
+}
+
void Button::set_flat(bool p_flat) {
flat = p_flat;
@@ -265,6 +310,8 @@ void Button::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &Button::get_text);
ClassDB::bind_method(D_METHOD("set_button_icon", "texture"), &Button::set_icon);
ClassDB::bind_method(D_METHOD("get_button_icon"), &Button::get_icon);
+ ClassDB::bind_method(D_METHOD("set_expand_icon"), &Button::set_expand_icon);
+ ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &Button::set_flat);
ClassDB::bind_method(D_METHOD("set_clip_text", "enabled"), &Button::set_clip_text);
ClassDB::bind_method(D_METHOD("get_clip_text"), &Button::get_clip_text);
@@ -281,12 +328,14 @@ void Button::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon");
}
Button::Button(const String &p_text) {
flat = false;
clip_text = false;
+ expand_icon = false;
set_mouse_filter(MOUSE_FILTER_STOP);
set_text(p_text);
align = ALIGN_CENTER;
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 6ba3475e5a..1fff2cfda7 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -32,9 +32,6 @@
#define BUTTON_H
#include "scene/gui/base_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Button : public BaseButton {
@@ -52,6 +49,7 @@ private:
String text;
String xl_text;
Ref<Texture> icon;
+ bool expand_icon;
bool clip_text;
TextAlign align;
float _internal_margin[4];
@@ -62,8 +60,6 @@ protected:
static void _bind_methods();
public:
- //
-
virtual Size2 get_minimum_size() const;
void set_text(const String &p_text);
@@ -72,6 +68,9 @@ public:
void set_icon(const Ref<Texture> &p_icon);
Ref<Texture> get_icon() const;
+ void set_expand_icon(bool p_expand_icon);
+ bool is_expand_icon() const;
+
void set_flat(bool p_flat);
bool is_flat() const;
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 1d8b74d9db..8744407763 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -79,7 +79,7 @@ void CheckBox::_notification(int p_what) {
Vector2 ofs;
ofs.x = sb->get_margin(MARGIN_LEFT);
- ofs.y = int((get_size().height - get_icon_size().height) / 2);
+ ofs.y = int((get_size().height - get_icon_size().height) / 2) + get_constant("check_vadjust");
if (is_pressed())
on->draw(ci, ofs);
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index a2d0f388c4..f47547f2cc 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -76,7 +76,7 @@ void CheckButton::_notification(int p_what) {
Size2 tex_size = get_icon_size();
ofs.x = get_size().width - (tex_size.width + sb->get_margin(MARGIN_RIGHT));
- ofs.y = (get_size().height - tex_size.height) / 2;
+ ofs.y = (get_size().height - tex_size.height) / 2 + get_constant("check_vadjust");
if (is_pressed())
on->draw(ci, ofs);
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index b197971b61..6dd9e401f6 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -247,15 +247,19 @@ void ColorPicker::_update_color(bool p_update_sliders) {
}
void ColorPicker::_update_presets() {
+ presets_per_row = 10;
Size2 size = bt_add_preset->get_size();
- Size2 preset_size = Size2(size.width * presets.size(), size.height);
+ Size2 preset_size = Size2(MIN(size.width * presets.size(), presets_per_row * size.width), size.height * (Math::ceil((float)presets.size() / presets_per_row)));
preset->set_custom_minimum_size(preset_size);
-
- preset->draw_texture_rect(get_icon("preset_bg", "ColorPicker"), Rect2(Point2(), preset_size), true);
+ preset_container->set_custom_minimum_size(preset_size);
+ preset->draw_rect(Rect2(Point2(), preset_size), Color(1, 1, 1, 0));
for (int i = 0; i < presets.size(); i++) {
- preset->draw_rect(Rect2(Point2(size.width * i, 0), size), presets[i]);
+ int x = (i % presets_per_row) * size.width;
+ int y = (Math::floor((float)i / presets_per_row)) * size.height;
+ preset->draw_rect(Rect2(Point2(x, y), size), presets[i]);
}
+ _notification(NOTIFICATION_VISIBILITY_CHANGED);
}
void ColorPicker::_text_type_toggled() {
@@ -288,8 +292,6 @@ void ColorPicker::add_preset(const Color &p_color) {
presets.push_back(p_color);
}
preset->update();
- if (presets.size() == 10)
- bt_add_preset->hide();
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
@@ -533,14 +535,20 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
-
+ int index = 0;
if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
- int index = bev->get_position().x / (preset->get_size().x / presets.size());
+ for (int i = 0; i < presets.size(); i++) {
+ int x = (i % presets_per_row) * bt_add_preset->get_size().x;
+ int y = (Math::floor((float)i / presets_per_row)) * bt_add_preset->get_size().y;
+ if (bev->get_position().x > x && bev->get_position().x < x + preset->get_size().x && bev->get_position().y > y && bev->get_position().y < y + preset->get_size().y) {
+ index = i;
+ }
+ }
set_pick_color(presets[index]);
_update_color();
emit_signal("color_changed", color);
} else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT && presets_enabled) {
- int index = bev->get_position().x / (preset->get_size().x / presets.size());
+ index = bev->get_position().x / (preset->get_size().x / presets.size());
Color clicked_preset = presets[index];
erase_preset(clicked_preset);
emit_signal("preset_removed", clicked_preset);
@@ -841,6 +849,7 @@ ColorPicker::ColorPicker() :
add_child(preset_separator);
preset_container = memnew(HBoxContainer);
+ preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(preset_container);
preset = memnew(TextureRect);
@@ -848,8 +857,11 @@ ColorPicker::ColorPicker() :
preset->connect("gui_input", this, "_preset_input");
preset->connect("draw", this, "_update_presets");
+ preset_container2 = memnew(HBoxContainer);
+ preset_container2->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(preset_container2);
bt_add_preset = memnew(Button);
- preset_container->add_child(bt_add_preset);
+ preset_container2->add_child(bt_add_preset);
bt_add_preset->set_tooltip(TTR("Add current color as a preset."));
bt_add_preset->connect("pressed", this, "_add_preset_pressed");
}
@@ -952,6 +964,7 @@ void ColorPickerButton::_update_picker() {
popup->connect("popup_hide", this, "set_pressed", varray(false));
picker->set_pick_color(color);
picker->set_edit_alpha(edit_alpha);
+ emit_signal("picker_created");
}
}
@@ -968,6 +981,7 @@ void ColorPickerButton::_bind_methods() {
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("popup_closed"));
+ ADD_SIGNAL(MethodInfo("picker_created"));
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha");
}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 3af27a9856..167f7b33b3 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -54,6 +54,7 @@ private:
TextureRect *sample;
TextureRect *preset;
HBoxContainer *preset_container;
+ HBoxContainer *preset_container2;
HSeparator *preset_separator;
Button *bt_add_preset;
List<Color> presets;
@@ -68,6 +69,7 @@ private:
bool edit_alpha;
Size2i ms;
bool text_is_constructor;
+ int presets_per_row;
Color color;
bool raw_mode_enabled;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 26be17f6c1..d39f017cad 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -289,7 +289,7 @@ void Control::_update_minimum_size() {
Size2 minsize = get_combined_minimum_size();
if (minsize.x > data.size_cache.x ||
minsize.y > data.size_cache.y) {
- set_size(data.size_cache);
+ _size_changed();
}
data.updating_last_minimum_size = false;
@@ -818,7 +818,7 @@ Size2 Control::get_minimum_size() const {
Ref<Texture> Control::get_icon(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const Ref<Texture> *tex = data.icon_override.getptr(p_name);
if (tex)
@@ -850,11 +850,17 @@ Ref<Texture> Control::get_icon(const StringName &p_name, const StringName &p_typ
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_icon(p_name, type)) {
+ return Theme::get_project_default()->get_icon(p_name, type);
+ }
+ }
+
return Theme::get_default()->get_icon(p_name, type);
}
Ref<Shader> Control::get_shader(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const Ref<Shader> *sdr = data.shader_override.getptr(p_name);
if (sdr)
@@ -886,12 +892,18 @@ Ref<Shader> Control::get_shader(const StringName &p_name, const StringName &p_ty
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_shader(p_name, type)) {
+ return Theme::get_project_default()->get_shader(p_name, type);
+ }
+ }
+
return Theme::get_default()->get_shader(p_name, type);
}
Ref<StyleBox> Control::get_stylebox(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
if (style)
return *style;
@@ -925,6 +937,9 @@ Ref<StyleBox> Control::get_stylebox(const StringName &p_name, const StringName &
}
while (class_name != StringName()) {
+ if (Theme::get_project_default().is_valid() && Theme::get_project_default()->has_stylebox(p_name, type))
+ return Theme::get_project_default()->get_stylebox(p_name, type);
+
if (Theme::get_default()->has_stylebox(p_name, class_name))
return Theme::get_default()->get_stylebox(p_name, class_name);
@@ -934,7 +949,7 @@ Ref<StyleBox> Control::get_stylebox(const StringName &p_name, const StringName &
}
Ref<Font> Control::get_font(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const Ref<Font> *font = data.font_override.getptr(p_name);
if (font)
return *font;
@@ -971,7 +986,7 @@ Ref<Font> Control::get_font(const StringName &p_name, const StringName &p_type)
}
Color Control::get_color(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const Color *color = data.color_override.getptr(p_name);
if (color)
return *color;
@@ -1001,12 +1016,17 @@ Color Control::get_color(const StringName &p_name, const StringName &p_type) con
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_color(p_name, type)) {
+ return Theme::get_project_default()->get_color(p_name, type);
+ }
+ }
return Theme::get_default()->get_color(p_name, type);
}
int Control::get_constant(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
const int *constant = data.constant_override.getptr(p_name);
if (constant)
return *constant;
@@ -1036,6 +1056,11 @@ int Control::get_constant(const StringName &p_name, const StringName &p_type) co
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_constant(p_name, type)) {
+ return Theme::get_project_default()->get_constant(p_name, type);
+ }
+ }
return Theme::get_default()->get_constant(p_name, type);
}
@@ -1077,7 +1102,7 @@ bool Control::has_constant_override(const StringName &p_name) const {
bool Control::has_icon(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_icon_override(p_name))
return true;
}
@@ -1106,12 +1131,17 @@ bool Control::has_icon(const StringName &p_name, const StringName &p_type) const
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_color(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_icon(p_name, type);
}
bool Control::has_shader(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_shader_override(p_name))
return true;
}
@@ -1140,11 +1170,16 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_shader(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_shader(p_name, type);
}
bool Control::has_stylebox(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_stylebox_override(p_name))
return true;
}
@@ -1173,11 +1208,16 @@ bool Control::has_stylebox(const StringName &p_name, const StringName &p_type) c
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_stylebox(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_stylebox(p_name, type);
}
bool Control::has_font(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_font_override(p_name))
return true;
}
@@ -1206,12 +1246,17 @@ bool Control::has_font(const StringName &p_name, const StringName &p_type) const
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_font(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_font(p_name, type);
}
bool Control::has_color(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_color_override(p_name))
return true;
}
@@ -1240,12 +1285,17 @@ bool Control::has_color(const StringName &p_name, const StringName &p_type) cons
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_color(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_color(p_name, type);
}
bool Control::has_constant(const StringName &p_name, const StringName &p_type) const {
- if (p_type == StringName() || p_type == "") {
+ if (p_type == StringName() || p_type == get_class_name()) {
if (has_constant_override(p_name))
return true;
}
@@ -1274,6 +1324,11 @@ bool Control::has_constant(const StringName &p_name, const StringName &p_type) c
theme_owner = NULL;
}
+ if (Theme::get_project_default().is_valid()) {
+ if (Theme::get_project_default()->has_constant(p_name, type)) {
+ return true;
+ }
+ }
return Theme::get_default()->has_constant(p_name, type);
}
@@ -1717,17 +1772,6 @@ void Control::set_global_position(const Point2 &p_point, bool p_keep_margins) {
set_position(inv.xform(p_point), p_keep_margins);
}
-Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margins[4]) const {
-
- Rect2 anchorable = get_parent_anchorable_rect();
- Rect2 result = anchorable;
- for (int i = 0; i < 4; i++) {
- result.grow_margin((Margin)i, p_anchors[i] * anchorable.get_size()[i % 2] + p_margins[i]);
- }
-
- return result;
-}
-
void Control::_compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]) {
Size2 parent_rect_size = get_parent_anchorable_rect().size;
@@ -1951,12 +1995,7 @@ Control *Control::find_next_valid_focus() const {
Node *n = get_node(data.focus_next);
if (n) {
from = Object::cast_to<Control>(n);
-
- if (!from) {
-
- ERR_EXPLAIN("Next focus node is not a control: " + n->get_name());
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!from, NULL, "Next focus node is not a control: " + n->get_name() + ".");
} else {
return NULL;
}
@@ -2046,12 +2085,7 @@ Control *Control::find_prev_valid_focus() const {
Node *n = get_node(data.focus_prev);
if (n) {
from = Object::cast_to<Control>(n);
-
- if (!from) {
-
- ERR_EXPLAIN("Previous focus node is not a control: " + n->get_name());
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!from, NULL, "Previous focus node is not a control: " + n->get_name() + ".");
} else {
return NULL;
}
@@ -2115,9 +2149,7 @@ bool Control::has_focus() const {
void Control::grab_focus() {
- if (!is_inside_tree()) {
- ERR_FAIL_COND(!is_inside_tree());
- }
+ ERR_FAIL_COND(!is_inside_tree());
if (data.focus_mode == FOCUS_NONE) {
WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus.");
@@ -2333,12 +2365,7 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
Node *n = get_node(data.focus_neighbour[p_margin]);
if (n) {
c = Object::cast_to<Control>(n);
-
- if (!c) {
-
- ERR_EXPLAIN("Neighbour focus node is not a control: " + n->get_name());
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!c, NULL, "Neighbor focus node is not a control: " + n->get_name() + ".");
} else {
return NULL;
}
@@ -2889,17 +2916,21 @@ void Control::_bind_methods() {
BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size"));
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_drag_data", PropertyInfo(Variant::VECTOR2, "position")));
+
+ MethodInfo get_drag_data = MethodInfo("get_drag_data", PropertyInfo(Variant::VECTOR2, "position"));
+ get_drag_data.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ BIND_VMETHOD(get_drag_data);
+
BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
BIND_VMETHOD(MethodInfo("drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input"));
ADD_GROUP("Anchor", "anchor_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.01,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_BOTTOM);
ADD_GROUP("Margin", "margin_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_left", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_LEFT);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 1a59a6d2e4..7305b3ce93 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -38,9 +38,6 @@
#include "scene/main/node.h"
#include "scene/main/timer.h"
#include "scene/resources/theme.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Viewport;
class Label;
@@ -230,7 +227,6 @@ private:
void _update_scroll();
void _resize(const Size2 &p_size);
- Rect2 _compute_child_rect(const float p_anchors[4], const float p_margins[4]) const;
void _compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]);
void _compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 4da11b671e..9ed1d2bf45 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -35,6 +35,7 @@
#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
+#include "scene/main/viewport.h" // Only used to check for more modals when dimming the editor.
#endif
// WindowDialog
@@ -59,7 +60,7 @@ void WindowDialog::_fix_size() {
float left = 0;
float bottom = 0;
float right = 0;
- // Check validity, because the theme could contain a different type of StyleBox
+ // Check validity, because the theme could contain a different type of StyleBox.
if (panel->get_class() == "StyleBoxTexture") {
Ref<StyleBoxTexture> panel_texture = Object::cast_to<StyleBoxTexture>(*panel);
top = panel_texture->get_expand_margin_size(MARGIN_TOP);
@@ -219,6 +220,14 @@ void WindowDialog::_notification(int p_what) {
close_button->set_begin(Point2(-get_constant("close_h_ofs", "WindowDialog"), -get_constant("close_v_ofs", "WindowDialog")));
} break;
+ case NOTIFICATION_TRANSLATION_CHANGED: {
+ String new_title = tr(title);
+ if (title != new_title) {
+ title = new_title;
+ update();
+ }
+ } break;
+
case NOTIFICATION_MOUSE_EXIT: {
// Reset the mouse cursor when leaving the resizable window border.
if (resizable && !drag_type) {
@@ -226,13 +235,15 @@ void WindowDialog::_notification(int p_what) {
set_default_cursor_shape(CURSOR_ARROW);
}
} break;
+
#ifdef TOOLS_ENABLED
case NOTIFICATION_POST_POPUP: {
if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton())
EditorNode::get_singleton()->dim_editor(true);
} break;
+
case NOTIFICATION_POPUP_HIDE: {
- if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton())
+ if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !get_viewport()->gui_has_modal_stack())
EditorNode::get_singleton()->dim_editor(false);
} break;
#endif
@@ -272,8 +283,11 @@ int WindowDialog::_drag_hit_test(const Point2 &pos) const {
void WindowDialog::set_title(const String &p_title) {
- title = tr(p_title);
- update();
+ String new_title = tr(p_title);
+ if (title != new_title) {
+ title = new_title;
+ update();
+ }
}
String WindowDialog::get_title() const {
@@ -296,8 +310,8 @@ Size2 WindowDialog::get_minimum_size() const {
const int padding = button_width / 2;
const int button_area = button_width + padding;
- // as the title gets centered, title_width + close_button_width is not enough.
- // we want a width w, such that w / 2 - title_width / 2 >= button_area, i.e.
+ // As the title gets centered, title_width + close_button_width is not enough.
+ // We want a width w, such that w / 2 - title_width / 2 >= button_area, i.e.
// w >= 2 * button_area + title_width
return Size2(2 * button_area + title_width, 1);
@@ -324,7 +338,6 @@ void WindowDialog::_bind_methods() {
WindowDialog::WindowDialog() {
- //title="Hello!";
drag_type = DRAG_NONE;
resizable = false;
close_button = memnew(TextureButton);
@@ -340,7 +353,6 @@ WindowDialog::~WindowDialog() {
void PopupDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size()));
}
@@ -362,15 +374,15 @@ void AcceptDialog::_post_popup() {
void AcceptDialog::_notification(int p_what) {
- if (p_what == NOTIFICATION_MODAL_CLOSE) {
-
- cancel_pressed();
- } else if (p_what == NOTIFICATION_READY) {
-
- _update_child_rects();
- } else if (p_what == NOTIFICATION_RESIZED) {
+ switch (p_what) {
+ case NOTIFICATION_MODAL_CLOSE: {
+ cancel_pressed();
+ } break;
- _update_child_rects();
+ case NOTIFICATION_READY:
+ case NOTIFICATION_RESIZED: {
+ _update_child_rects();
+ } break;
}
}
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index c1a7f26a85..1a0350ba18 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -37,9 +37,6 @@
#include "scene/gui/panel.h"
#include "scene/gui/popup.h"
#include "scene/gui/texture_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class WindowDialog : public Popup {
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 04fb991f78..9bc593ea3b 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -400,14 +400,14 @@ void FileDialog::update_file_list() {
TreeItem *root = tree->create_item();
Ref<Texture> folder = get_icon("folder");
+ const Color folder_color = get_color("folder_icon_modulate");
List<String> files;
List<String> dirs;
- bool is_dir;
bool is_hidden;
String item;
- while ((item = dir_access->get_next(&is_dir)) != "") {
+ while ((item = dir_access->get_next()) != "") {
if (item == "." || item == "..")
continue;
@@ -415,7 +415,7 @@ void FileDialog::update_file_list() {
is_hidden = dir_access->current_is_hidden();
if (show_hidden_files || !is_hidden) {
- if (!is_dir)
+ if (!dir_access->current_is_dir())
files.push_back(item);
else
dirs.push_back(item);
@@ -430,6 +430,7 @@ void FileDialog::update_file_list() {
TreeItem *ti = tree->create_item(root);
ti->set_text(0, dir_name);
ti->set_icon(0, folder);
+ ti->set_icon_modulate(0, folder_color);
Dictionary d;
d["name"] = dir_name;
@@ -880,14 +881,14 @@ FileDialog::FileDialog() {
dir->set_h_size_flags(SIZE_EXPAND_FILL);
refresh = memnew(ToolButton);
- refresh->set_tooltip(RTR("Refresh"));
+ refresh->set_tooltip(RTR("Refresh files."));
refresh->connect("pressed", this, "_update_file_list");
hbc->add_child(refresh);
show_hidden = memnew(ToolButton);
show_hidden->set_toggle_mode(true);
show_hidden->set_pressed(is_showing_hidden_files());
- show_hidden->set_tooltip(RTR("Toggle Hidden Files"));
+ show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files."));
show_hidden->connect("toggled", this, "set_show_hidden_files");
hbc->add_child(show_hidden);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 191af5fef3..4fd6d0d13c 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -38,9 +38,7 @@
#include "scene/gui/option_button.h"
#include "scene/gui/tool_button.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class FileDialog : public ConfirmationDialog {
GDCLASS(FileDialog, ConfirmationDialog);
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 75f5f79873..09ef6f26bf 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -241,9 +241,13 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
float newofs = CLAMP(x / float(total_w), 0, 1);
- //Snap to nearest point if holding shift
- if (mm->get_shift()) {
- float snap_threshold = 0.03;
+ // Snap to "round" coordinates if holding Ctrl.
+ // Be more precise if holding Shift as well
+ if (mm->get_control()) {
+ newofs = Math::stepify(newofs, mm->get_shift() ? 0.025 : 0.1);
+ } else if (mm->get_shift()) {
+ // Snap to nearest point if holding just Shift
+ const float snap_threshold = 0.03;
float smallest_ofs = snap_threshold;
bool found = false;
int nearest_point = 0;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index f238aeb392..7827c66841 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -276,6 +276,11 @@ void GraphEdit::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
port_grab_distance_horizontal = get_constant("port_grab_distance_horizontal");
port_grab_distance_vertical = get_constant("port_grab_distance_vertical");
+
+ zoom_minus->set_icon(get_icon("minus"));
+ zoom_reset->set_icon(get_icon("reset"));
+ zoom_plus->set_icon(get_icon("more"));
+ snap_button->set_icon(get_icon("snap"));
}
if (p_what == NOTIFICATION_READY) {
Size2 hmin = h_scroll->get_combined_minimum_size();
@@ -290,11 +295,6 @@ void GraphEdit::_notification(int p_what) {
h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height);
h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
-
- zoom_minus->set_icon(get_icon("minus"));
- zoom_reset->set_icon(get_icon("reset"));
- zoom_plus->set_icon(get_icon("more"));
- snap_button->set_icon(get_icon("snap"));
}
if (p_what == NOTIFICATION_DRAW) {
@@ -776,10 +776,16 @@ void GraphEdit::_top_layer_draw() {
_draw_cos_line(top_layer, pos, topos, col, col);
}
- if (box_selecting)
+ if (box_selecting) {
top_layer->draw_rect(
box_selecting_rect,
- get_color("accent_color", "Editor") * Color(1, 1, 1, 0.375));
+ get_color("box_selection_fill_color", "Editor"));
+
+ top_layer->draw_rect(
+ box_selecting_rect,
+ get_color("box_selection_stroke_color", "Editor"),
+ false);
+ }
}
void GraphEdit::set_selected(Node *p_child) {
@@ -1030,14 +1036,28 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
Ref<InputEventKey> k = p_ev;
- if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) {
- emit_signal("duplicate_nodes_request");
- accept_event();
- }
- if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) {
- emit_signal("delete_nodes_request");
- accept_event();
+ if (k.is_valid()) {
+
+ if (k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) {
+ emit_signal("duplicate_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_C && k->is_pressed() && k->get_command()) {
+ emit_signal("copy_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_V && k->is_pressed() && k->get_command()) {
+ emit_signal("paste_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_DELETE && k->is_pressed()) {
+ emit_signal("delete_nodes_request");
+ accept_event();
+ }
}
Ref<InputEventMagnifyGesture> magnify_gesture = p_ev;
@@ -1297,6 +1317,8 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot")));
ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position")));
ADD_SIGNAL(MethodInfo("duplicate_nodes_request"));
+ ADD_SIGNAL(MethodInfo("copy_nodes_request"));
+ ADD_SIGNAL(MethodInfo("paste_nodes_request"));
ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 6463ee5ad5..5b2f8812d5 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -210,6 +210,7 @@ void GraphNode::_notification(int p_what) {
int close_offset = get_constant("close_offset");
int close_h_offset = get_constant("close_h_offset");
Color close_color = get_color("close_color");
+ Color resizer_color = get_color("resizer_color");
Ref<Font> title_font = get_font("title_font");
int title_offset = get_constant("title_offset");
int title_h_offset = get_constant("title_h_offset");
@@ -274,7 +275,7 @@ void GraphNode::_notification(int p_what) {
}
if (resizable) {
- draw_texture(resizer, get_size() - resizer->get_size());
+ draw_texture(resizer, get_size() - resizer->get_size(), resizer_color);
}
} break;
@@ -592,13 +593,14 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid()) {
- ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node.");
- ERR_FAIL_COND(get_parent_control() == NULL);
+ ERR_FAIL_COND_MSG(get_parent_control() == NULL, "GraphNode must be the child of a GraphEdit node.");
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
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/label.h b/scene/gui/label.h
index 561c42ef9e..2cc55a47ef 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -32,9 +32,7 @@
#define LABEL_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Label : public Control {
GDCLASS(Label, Control);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 3dcbf64e7c..04e03f569e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -59,6 +59,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
menu->set_scale(get_global_transform().get_scale());
menu->popup();
grab_focus();
+ accept_event();
return;
}
@@ -86,7 +87,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} else {
- if (b->is_doubleclick()) {
+ if (b->is_doubleclick() && selecting_enabled) {
selection.enabled = true;
selection.begin = 0;
@@ -194,13 +195,13 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
unsigned int code = k->get_scancode();
- if (k->get_command()) {
+ if (k->get_command() && is_shortcut_keys_enabled()) {
bool handled = true;
switch (code) {
- case (KEY_X): { // CUT
+ case (KEY_X): { // CUT.
if (editable) {
cut_text();
@@ -208,13 +209,13 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
- case (KEY_C): { // COPY
+ case (KEY_C): { // COPY.
copy_text();
} break;
- case (KEY_V): { // PASTE
+ case (KEY_V): { // PASTE.
if (editable) {
@@ -223,7 +224,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
- case (KEY_Z): { // undo / redo
+ case (KEY_Z): { // Undo/redo.
if (editable) {
if (k->get_shift()) {
redo();
@@ -233,7 +234,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
} break;
- case (KEY_U): { // Delete from start to cursor
+ case (KEY_U): { // Delete from start to cursor.
if (editable) {
@@ -254,7 +255,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
- case (KEY_Y): { // PASTE (Yank for unix users)
+ case (KEY_Y): { // PASTE (Yank for unix users).
if (editable) {
@@ -262,7 +263,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
} break;
- case (KEY_K): { // Delete from cursor_pos to end
+ case (KEY_K): { // Delete from cursor_pos to end.
if (editable) {
@@ -272,14 +273,15 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
} break;
- case (KEY_A): { //Select All
+ case (KEY_A): { // Select all.
select();
+
} break;
#ifdef APPLE_STYLE_KEYS
- case (KEY_LEFT): { // Go to start of text - like HOME key
+ case (KEY_LEFT): { // Go to start of text - like HOME key.
set_cursor_position(0);
} break;
- case (KEY_RIGHT): { // Go to end of text - like END key
+ case (KEY_RIGHT): { // Go to end of text - like END key.
set_cursor_position(text.length());
} break;
#endif
@@ -472,7 +474,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
int text_len = text.length();
if (cursor_pos == text_len)
- break; // nothing to do
+ break; // Nothing to do.
#ifdef APPLE_STYLE_KEYS
if (k->get_alt()) {
@@ -530,6 +532,16 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
set_cursor_position(text.length());
shift_selection_check_post(k->get_shift());
} break;
+ case KEY_MENU: {
+ if (context_menu_enabled) {
+ Point2 pos = Point2(get_cursor_pixel_pos(), (get_size().y + get_font("font")->get_height()) / 2);
+ menu->set_position(get_global_transform().xform(pos));
+ menu->set_size(Vector2(1, 1));
+ menu->set_scale(get_global_transform().get_scale());
+ menu->popup();
+ menu->grab_focus();
+ }
+ } break;
default: {
@@ -729,7 +741,7 @@ void LineEdit::_notification(int p_what) {
Color cursor_color = get_color("cursor_color");
const String &t = using_placeholder ? placeholder_translated : text;
- // draw placeholder color
+ // Draw placeholder color.
if (using_placeholder)
font_color.a *= placeholder_alpha;
@@ -744,24 +756,28 @@ void LineEdit::_notification(int p_what) {
color_icon = get_color("clear_button_color");
}
}
- r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon);
+
+ float icon_width = MIN(r_icon->get_width(), r_icon->get_width() * (height - (style->get_margin(MARGIN_TOP) + style->get_margin(MARGIN_BOTTOM))) / r_icon->get_height());
+ float icon_height = MIN(r_icon->get_height(), height - (style->get_margin(MARGIN_TOP) + style->get_margin(MARGIN_BOTTOM)));
+ Rect2 icon_region = Rect2(Point2(width - icon_width - style->get_margin(MARGIN_RIGHT), height / 2 - icon_height / 2), Size2(icon_width, icon_height));
+ draw_texture_rect_region(r_icon, icon_region, Rect2(Point2(), r_icon->get_size()), color_icon);
if (align == ALIGN_CENTER) {
if (window_pos == 0) {
- x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - cached_text_width - r_icon->get_width() - style->get_margin(MARGIN_RIGHT) * 2) / 2);
+ x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - cached_text_width - icon_width - style->get_margin(MARGIN_RIGHT) * 2) / 2);
}
} else {
- x_ofs = MAX(style->get_margin(MARGIN_LEFT), x_ofs - r_icon->get_width() - style->get_margin(MARGIN_RIGHT));
+ x_ofs = MAX(style->get_margin(MARGIN_LEFT), x_ofs - icon_width - style->get_margin(MARGIN_RIGHT));
}
- ofs_max -= r_icon->get_width();
+ ofs_max -= icon_width;
}
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
FontDrawer drawer(font, Color(1, 1, 1));
while (true) {
- //end of string, break!
+ // End of string, break.
if (char_ofs >= t.length())
break;
@@ -798,7 +814,7 @@ void LineEdit::_notification(int p_what) {
CharType next = (pass && !text.empty()) ? secret_character[0] : t[char_ofs + 1];
int char_width = font->get_char_size(cchar, next).width;
- // end of widget, break!
+ // End of widget, break.
if ((x_ofs + char_width) > ofs_max)
break;
@@ -853,7 +869,7 @@ void LineEdit::_notification(int p_what) {
}
}
- if (char_ofs == cursor_pos && draw_caret) { //may be at the end
+ if (char_ofs == cursor_pos && draw_caret) { // May be at the end.
if (ime_text.length() == 0) {
#ifdef TOOLS_ENABLED
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(Math::round(EDSCALE), caret_height)), cursor_color);
@@ -871,7 +887,9 @@ void LineEdit::_notification(int p_what) {
} break;
case NOTIFICATION_FOCUS_ENTER: {
- if (!caret_blink_enabled) {
+ if (caret_blink_enabled) {
+ caret_blink_timer->start();
+ } else {
draw_caret = true;
}
@@ -885,6 +903,10 @@ void LineEdit::_notification(int p_what) {
} break;
case NOTIFICATION_FOCUS_EXIT: {
+ if (caret_blink_enabled) {
+ caret_blink_timer->stop();
+ }
+
OS::get_singleton()->set_ime_position(Point2());
OS::get_singleton()->set_ime_active(false);
ime_text = "";
@@ -999,6 +1021,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 +1037,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;
}
@@ -1028,7 +1058,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
}
pixel_ofs += char_w;
- if (pixel_ofs > p_x) { //found what we look for
+ if (pixel_ofs > p_x) { // Found what we look for.
break;
}
@@ -1038,17 +1068,67 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
set_cursor_position(ofs);
}
+int LineEdit::get_cursor_pixel_pos() {
+
+ Ref<Font> font = get_font("font");
+ int ofs = window_pos;
+ 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) {
+
+ case ALIGN_FILL:
+ case ALIGN_LEFT: {
+
+ pixel_ofs = int(style->get_offset().x);
+ } break;
+ case ALIGN_CENTER: {
+
+ if (window_pos != 0)
+ 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;
+ }
+
+ while (ofs < cursor_pos) {
+ if (font != NULL) {
+ pixel_ofs += font->get_char_size(text[ofs]).width;
+ }
+ ofs++;
+ }
+
+ return pixel_ofs;
+}
+
bool LineEdit::cursor_get_blink_enabled() const {
return caret_blink_enabled;
}
void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
caret_blink_enabled = p_enabled;
- if (p_enabled) {
- caret_blink_timer->start();
- } else {
- caret_blink_timer->stop();
+
+ if (has_focus()) {
+ if (p_enabled) {
+ caret_blink_timer->start();
+ } else {
+ caret_blink_timer->stop();
+ }
}
+
draw_caret = true;
}
@@ -1063,10 +1143,12 @@ void LineEdit::cursor_set_blink_speed(const float p_speed) {
void LineEdit::_reset_caret_blink_timer() {
if (caret_blink_enabled) {
- caret_blink_timer->stop();
- caret_blink_timer->start();
draw_caret = true;
- update();
+ if (has_focus()) {
+ caret_blink_timer->stop();
+ caret_blink_timer->start();
+ update();
+ }
}
}
@@ -1189,15 +1271,18 @@ void LineEdit::set_cursor_position(int p_pos) {
Ref<Font> font = get_font("font");
if (cursor_pos <= window_pos) {
- /* Adjust window if cursor goes too much to the left */
+ // Adjust window if cursor goes too much to the left.
set_window_pos(MAX(0, cursor_pos - 1));
} else {
- /* Adjust window if cursor goes too much to the right */
+ // 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;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon;
- window_width -= r_icon->get_width();
+
+ float icon_width = MIN(r_icon->get_width(), r_icon->get_width() * (get_size().height - (style->get_margin(MARGIN_TOP) + style->get_margin(MARGIN_BOTTOM))) / r_icon->get_height());
+
+ window_width -= icon_width;
}
if (window_width < 0)
@@ -1211,10 +1296,10 @@ void LineEdit::set_cursor_position(int p_pos) {
for (int i = cursor_pos; i >= window_pos; i--) {
if (i >= text.length()) {
- //do not do this, because if the cursor is at the end, its just fine that it takes no space
- //accum_width = font->get_char_size(' ').width; //anything should do
+ // Do not do this, because if the cursor is at the end, its just fine that it takes no space.
+ // accum_width = font->get_char_size(' ').width;
} else {
- accum_width += font->get_char_size(text[i], i + 1 < text.length() ? text[i + 1] : 0).width; //anything should do
+ accum_width += font->get_char_size(text[i], i + 1 < text.length() ? text[i + 1] : 0).width; // Anything should do.
}
if (accum_width > window_width)
break;
@@ -1279,12 +1364,13 @@ Size2 LineEdit::get_minimum_size() const {
Size2 min = style->get_minimum_size();
min.height += font->get_height();
- //minimum size of text
+ // Minimum size of text.
int space_size = font->get_char_size(' ').x;
int mstext = get_constant("minimum_spaces") * space_size;
if (expand_to_text_length) {
- mstext = MAX(mstext, font->get_string_size(text).x + space_size); //add a spce because some fonts are too exact, and because cursor needs a bit more when at the end
+ // Add a space because some fonts are too exact, and because cursor needs a bit more when at the end.
+ mstext = MAX(mstext, font->get_string_size(text).x + space_size);
}
min.width += mstext;
@@ -1292,8 +1378,6 @@ Size2 LineEdit::get_minimum_size() const {
return min;
}
-/* selection */
-
void LineEdit::deselect() {
selection.begin = 0;
@@ -1326,6 +1410,8 @@ int LineEdit::get_max_length() const {
}
void LineEdit::selection_fill_at_cursor() {
+ if (!selecting_enabled)
+ return;
selection.begin = cursor_pos;
selection.end = selection.cursor_start;
@@ -1340,6 +1426,8 @@ void LineEdit::selection_fill_at_cursor() {
}
void LineEdit::select_all() {
+ if (!selecting_enabled)
+ return;
if (!text.length())
return;
@@ -1356,22 +1444,7 @@ void LineEdit::set_editable(bool p_editable) {
return;
editable = p_editable;
-
- // Reorganize context menu.
- menu->clear();
- if (editable)
- menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
- menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
- if (editable)
- menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
- menu->add_separator();
- menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
- if (editable) {
- menu->add_item(RTR("Clear"), MENU_CLEAR);
- menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
- }
+ _generate_context_menu();
update();
}
@@ -1394,10 +1467,9 @@ bool LineEdit::is_secret() const {
void LineEdit::set_secret_character(const String &p_string) {
- // An empty string as the secret character would crash the engine
- // It also wouldn't make sense to use multiple characters as the secret character
- ERR_EXPLAIN("Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given)");
- ERR_FAIL_COND(p_string.length() != 1);
+ // An empty string as the secret character would crash the engine.
+ // It also wouldn't make sense to use multiple characters as the secret character.
+ ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given).");
secret_character = p_string;
update();
@@ -1408,6 +1480,8 @@ String LineEdit::get_secret_character() const {
}
void LineEdit::select(int p_from, int p_to) {
+ if (!selecting_enabled)
+ return;
if (p_from == 0 && p_to == 0) {
deselect();
@@ -1515,6 +1589,29 @@ bool LineEdit::is_clear_button_enabled() const {
return clear_button_enabled;
}
+void LineEdit::set_shortcut_keys_enabled(bool p_enabled) {
+ shortcut_keys_enabled = p_enabled;
+
+ _generate_context_menu();
+}
+
+bool LineEdit::is_shortcut_keys_enabled() const {
+ return shortcut_keys_enabled;
+}
+
+void LineEdit::set_selecting_enabled(bool p_enabled) {
+ selecting_enabled = p_enabled;
+
+ if (!selecting_enabled)
+ deselect();
+
+ _generate_context_menu();
+}
+
+bool LineEdit::is_selecting_enabled() const {
+ return selecting_enabled;
+}
+
void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
if (right_icon == p_icon) {
return;
@@ -1523,8 +1620,11 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
update();
}
-void LineEdit::_text_changed() {
+Ref<Texture> LineEdit::get_right_icon() {
+ return right_icon;
+}
+void LineEdit::_text_changed() {
if (expand_to_text_length)
minimum_size_changed();
@@ -1578,6 +1678,25 @@ void LineEdit::_create_undo_state() {
undo_stack.push_back(op);
}
+void LineEdit::_generate_context_menu() {
+ // Reorganize context menu.
+ menu->clear();
+ if (editable)
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ if (editable)
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_separator();
+ if (is_selecting_enabled())
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ if (editable) {
+ menu->add_item(RTR("Clear"), MENU_CLEAR);
+ menu->add_separator();
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ }
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
@@ -1622,6 +1741,12 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled);
ClassDB::bind_method(D_METHOD("set_clear_button_enabled", "enable"), &LineEdit::set_clear_button_enabled);
ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled);
+ ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &LineEdit::set_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &LineEdit::is_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &LineEdit::set_selecting_enabled);
+ ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &LineEdit::is_selecting_enabled);
+ ClassDB::bind_method(D_METHOD("set_right_icon", "icon"), &LineEdit::set_right_icon);
+ ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
@@ -1650,6 +1775,9 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon");
ADD_GROUP("Placeholder", "placeholder_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
@@ -1677,6 +1805,8 @@ LineEdit::LineEdit() {
clear_button_enabled = false;
clear_button_status.press_attempt = false;
clear_button_status.pressing_inside = false;
+ shortcut_keys_enabled = true;
+ selecting_enabled = true;
deselect();
set_focus_mode(FOCUS_ALL);
@@ -1694,7 +1824,7 @@ LineEdit::LineEdit() {
context_menu_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
- editable = false; // initialise to opposite first, so we get past the early-out in set_editable
+ editable = false; // Initialise to opposite first, so we get past the early-out in set_editable.
set_editable(true);
menu->connect("id_pressed", this, "menu_option");
expand_to_text_length = false;
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 3002f6f637..3424131dad 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -34,9 +34,6 @@
#include "scene/gui/control.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class LineEdit : public Control {
GDCLASS(LineEdit, Control);
@@ -78,18 +75,22 @@ private:
String ime_text;
Point2 ime_selection;
+ bool selecting_enabled;
+
bool context_menu_enabled;
PopupMenu *menu;
int cursor_pos;
int window_pos;
- int max_length; // 0 for no maximum
+ int max_length; // 0 for no maximum.
int cached_width;
int cached_placeholder_width;
bool clear_button_enabled;
+ bool shortcut_keys_enabled;
+
Ref<Texture> right_icon;
struct Selection {
@@ -121,6 +122,8 @@ private:
void _clear_redo();
void _create_undo_state();
+ void _generate_context_menu();
+
Timer *caret_blink_timer;
void _text_changed();
@@ -140,6 +143,7 @@ private:
void set_window_pos(int p_pos);
void set_cursor_at_pixel_pos(int p_x);
+ int get_cursor_pixel_pos();
void _reset_caret_blink_timer();
void _toggle_draw_caret();
@@ -219,7 +223,14 @@ public:
void set_clear_button_enabled(bool p_enabled);
bool is_clear_button_enabled() const;
+ void set_shortcut_keys_enabled(bool p_enabled);
+ bool is_shortcut_keys_enabled() const;
+
+ void set_selecting_enabled(bool p_enabled);
+ bool is_selecting_enabled() const;
+
void set_right_icon(const Ref<Texture> &p_icon);
+ Ref<Texture> get_right_icon();
virtual bool is_text_field() const;
LineEdit();
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 42e909d991..5448ff13f2 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -33,9 +33,7 @@
#include "scene/gui/button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class MenuButton : public Button {
GDCLASS(MenuButton, Button);
diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h
index ac17e52fc1..f31a09a482 100644
--- a/scene/gui/nine_patch_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -32,9 +32,7 @@
#define NINE_PATCH_RECT_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class NinePatchRect : public Control {
GDCLASS(NinePatchRect, Control);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 58671655dc..de8df4215d 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -43,40 +43,42 @@ Size2 OptionButton::get_minimum_size() const {
void OptionButton::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW) {
-
- if (!has_icon("arrow"))
- return;
-
- RID ci = get_canvas_item();
- Ref<Texture> arrow = Control::get_icon("arrow");
- Ref<StyleBox> normal = get_stylebox("normal");
- Color clr = Color(1, 1, 1);
- if (get_constant("modulate_arrow")) {
- switch (get_draw_mode()) {
- case DRAW_PRESSED:
- clr = get_color("font_color_pressed");
- break;
- case DRAW_HOVER:
- clr = get_color("font_color_hover");
- break;
- case DRAW_DISABLED:
- clr = get_color("font_color_disabled");
- break;
- default:
- clr = get_color("font_color");
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+
+ if (!has_icon("arrow"))
+ return;
+
+ RID ci = get_canvas_item();
+ Ref<Texture> arrow = Control::get_icon("arrow");
+ Color clr = Color(1, 1, 1);
+ if (get_constant("modulate_arrow")) {
+ switch (get_draw_mode()) {
+ case DRAW_PRESSED:
+ clr = get_color("font_color_pressed");
+ break;
+ case DRAW_HOVER:
+ clr = get_color("font_color_hover");
+ break;
+ case DRAW_DISABLED:
+ clr = get_color("font_color_disabled");
+ break;
+ default:
+ clr = get_color("font_color");
+ }
}
- }
- Size2 size = get_size();
+ Size2 size = get_size();
- Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2)));
- arrow->draw(ci, ofs, clr);
- } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2)));
+ arrow->draw(ci, ofs, clr);
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
- if (!is_visible_in_tree()) {
- popup->hide();
- }
+ if (!is_visible_in_tree()) {
+ popup->hide();
+ }
+ } break;
}
}
@@ -114,10 +116,16 @@ void OptionButton::add_item(const String &p_label, int p_id) {
void OptionButton::set_item_text(int p_idx, const String &p_text) {
popup->set_item_text(p_idx, p_text);
+
+ if (current == p_idx)
+ set_text(p_text);
}
void OptionButton::set_item_icon(int p_idx, const Ref<Texture> &p_icon) {
popup->set_item_icon(p_idx, p_icon);
+
+ if (current == p_idx)
+ set_icon(p_icon);
}
void OptionButton::set_item_id(int p_idx, int p_id) {
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 51d5fd6947..7210708042 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -33,9 +33,7 @@
#include "scene/gui/button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class OptionButton : public Button {
GDCLASS(OptionButton, Button);
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index f8d15e4261..84bf6e75f5 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -32,9 +32,7 @@
#define PANEL_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Panel : public Control {
GDCLASS(Panel, Control);
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 3e003af396..32380b6457 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -74,7 +74,7 @@ void Popup::_fix_size() {
Point2 pos = get_global_position();
Size2 size = get_size() * get_scale();
- Point2 window_size = get_viewport_rect().size;
+ Point2 window_size = get_viewport_rect().size - get_viewport_transform().get_origin();
if (pos.x + size.width > window_size.width)
pos.x = window_size.width - size.width;
@@ -207,6 +207,7 @@ bool Popup::is_exclusive() const {
void Popup::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_as_minsize"), &Popup::set_as_minsize);
ClassDB::bind_method(D_METHOD("popup_centered", "size"), &Popup::popup_centered, DEFVAL(Size2()));
ClassDB::bind_method(D_METHOD("popup_centered_ratio", "ratio"), &Popup::popup_centered_ratio, DEFVAL(0.75));
ClassDB::bind_method(D_METHOD("popup_centered_minsize", "minsize"), &Popup::popup_centered_minsize, DEFVAL(Size2()));
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index d6d96dfe64..925760984e 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -33,9 +33,6 @@
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Popup : public Control {
GDCLASS(Popup, Control);
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 2cac345dae..a7c6c5ccab 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -148,11 +148,9 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
void PopupMenu::_activate_submenu(int over) {
Node *n = get_node(items[over].submenu);
- ERR_EXPLAIN("Item subnode does not exist: " + items[over].submenu);
- ERR_FAIL_COND(!n);
+ ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
Popup *pm = Object::cast_to<Popup>(n);
- ERR_EXPLAIN("Item subnode is not a Popup: " + items[over].submenu);
- ERR_FAIL_COND(!pm);
+ ERR_FAIL_COND_MSG(!pm, "Item subnode is not a Popup: " + items[over].submenu + ".");
if (pm->is_visible_in_tree())
return; //already visible!
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index babdd21281..8bfe8fc607 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -33,10 +33,6 @@
#include "scene/gui/popup.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PopupMenu : public Popup {
GDCLASS(PopupMenu, Popup);
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index 264eda4035..0154a452ad 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -60,7 +60,7 @@ void ProgressBar::_notification(int p_what) {
draw_style_box(bg, Rect2(Point2(), get_size()));
float r = get_as_ratio();
int mp = fg->get_minimum_size().width;
- int p = r * get_size().width - mp;
+ int p = r * (get_size().width - mp);
if (p > 0) {
draw_style_box(fg, Rect2(Point2(), Size2(p + fg->get_minimum_size().width, get_size().height)));
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index e709bac377..ed5dd77f53 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -180,12 +180,12 @@ double Range::get_as_ratio() const {
float value = CLAMP(get_value(), shared->min, shared->max);
double v = Math::log(value) / Math::log((double)2);
- return (v - exp_min) / (exp_max - exp_min);
+ return CLAMP((v - exp_min) / (exp_max - exp_min), 0, 1);
} else {
float value = CLAMP(get_value(), shared->min, shared->max);
- return (value - get_min()) / (get_max() - get_min());
+ return CLAMP((value - get_min()) / (get_max() - get_min()), 0, 1);
}
}
diff --git a/scene/gui/range.h b/scene/gui/range.h
index cf0add8c89..8ce450f8fc 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -32,9 +32,7 @@
#define RANGE_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Range : public Control {
GDCLASS(Range, Control);
diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp
new file mode 100644
index 0000000000..67fa85b832
--- /dev/null
+++ b/scene/gui/rich_text_effect.cpp
@@ -0,0 +1,122 @@
+/*************************************************************************/
+/* rich_text_effect.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 "rich_text_effect.h"
+
+#include "core/script_language.h"
+
+void RichTextEffect::_bind_methods() {
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process_custom_fx", PropertyInfo(Variant::OBJECT, "char_fx", PROPERTY_HINT_RESOURCE_TYPE, "CharFXTransform")));
+}
+
+Variant RichTextEffect::get_bbcode() const {
+ Variant r;
+ if (get_script_instance()) {
+ if (!get_script_instance()->get("bbcode", r)) {
+ String path = get_script_instance()->get_script()->get_path();
+ r = path.get_file().get_basename();
+ }
+ }
+ return r;
+}
+
+bool RichTextEffect::_process_effect_impl(Ref<CharFXTransform> p_cfx) {
+ bool return_value = false;
+ if (get_script_instance()) {
+ Variant v = get_script_instance()->call("_process_custom_fx", p_cfx);
+ if (v.get_type() != Variant::BOOL) {
+ return_value = false;
+ } else {
+ return_value = (bool)v;
+ }
+ }
+ return return_value;
+}
+
+RichTextEffect::RichTextEffect() {
+}
+
+void CharFXTransform::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_relative_index"), &CharFXTransform::get_relative_index);
+ ClassDB::bind_method(D_METHOD("set_relative_index", "index"), &CharFXTransform::set_relative_index);
+
+ ClassDB::bind_method(D_METHOD("get_absolute_index"), &CharFXTransform::get_absolute_index);
+ ClassDB::bind_method(D_METHOD("set_absolute_index", "index"), &CharFXTransform::set_absolute_index);
+
+ ClassDB::bind_method(D_METHOD("get_elapsed_time"), &CharFXTransform::get_elapsed_time);
+ ClassDB::bind_method(D_METHOD("set_elapsed_time", "time"), &CharFXTransform::set_elapsed_time);
+
+ ClassDB::bind_method(D_METHOD("is_visible"), &CharFXTransform::is_visible);
+ ClassDB::bind_method(D_METHOD("set_visibility", "visibility"), &CharFXTransform::set_visibility);
+
+ ClassDB::bind_method(D_METHOD("get_offset"), &CharFXTransform::get_offset);
+ ClassDB::bind_method(D_METHOD("set_offset", "offset"), &CharFXTransform::set_offset);
+
+ ClassDB::bind_method(D_METHOD("get_color"), &CharFXTransform::get_color);
+ ClassDB::bind_method(D_METHOD("set_color", "color"), &CharFXTransform::set_color);
+
+ ClassDB::bind_method(D_METHOD("get_environment"), &CharFXTransform::get_environment);
+ ClassDB::bind_method(D_METHOD("set_environment", "environment"), &CharFXTransform::set_environment);
+
+ ClassDB::bind_method(D_METHOD("get_character"), &CharFXTransform::get_character);
+ ClassDB::bind_method(D_METHOD("set_character", "character"), &CharFXTransform::set_character);
+
+ ClassDB::bind_method(D_METHOD("get_value_or", "key", "default_value"), &CharFXTransform::get_value_or);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "relative_index"), "set_relative_index", "get_relative_index");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "absolute_index"), "set_absolute_index", "get_absolute_index");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "elapsed_time"), "set_elapsed_time", "get_elapsed_time");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visibility", "is_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "env"), "set_environment", "get_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "character"), "set_character", "get_character");
+}
+
+Variant CharFXTransform::get_value_or(String p_key, Variant p_default_value) {
+ if (!this->environment.has(p_key))
+ return p_default_value;
+
+ Variant r = environment[p_key];
+ if (r.get_type() != p_default_value.get_type())
+ return p_default_value;
+
+ return r;
+}
+
+CharFXTransform::CharFXTransform() {
+ relative_index = 0;
+ absolute_index = 0;
+ visibility = true;
+ offset = Point2();
+ color = Color();
+ character = 0;
+}
diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h
new file mode 100644
index 0000000000..f9c3e15399
--- /dev/null
+++ b/scene/gui/rich_text_effect.h
@@ -0,0 +1,87 @@
+/*************************************************************************/
+/* rich_text_effect.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 RICH_TEXT_EFFECT_H
+#define RICH_TEXT_EFFECT_H
+
+#include "core/resource.h"
+
+class RichTextEffect : public Resource {
+ GDCLASS(RichTextEffect, Resource);
+ OBJ_SAVE_TYPE(RichTextEffect);
+
+protected:
+ static void _bind_methods();
+
+public:
+ Variant get_bbcode() const;
+ bool _process_effect_impl(Ref<class CharFXTransform> p_cfx);
+
+ RichTextEffect();
+};
+
+class CharFXTransform : public Reference {
+ GDCLASS(CharFXTransform, Reference);
+
+protected:
+ static void _bind_methods();
+
+public:
+ uint64_t relative_index;
+ uint64_t absolute_index;
+ bool visibility;
+ Point2 offset;
+ Color color;
+ CharType character;
+ float elapsed_time;
+ Dictionary environment;
+
+ CharFXTransform();
+ uint64_t get_relative_index() { return relative_index; }
+ void set_relative_index(uint64_t p_index) { relative_index = p_index; }
+ uint64_t get_absolute_index() { return absolute_index; }
+ void set_absolute_index(uint64_t p_index) { absolute_index = p_index; }
+ float get_elapsed_time() { return elapsed_time; }
+ void set_elapsed_time(float p_elapsed_time) { elapsed_time = p_elapsed_time; }
+ bool is_visible() { return visibility; }
+ void set_visibility(bool p_vis) { visibility = p_vis; }
+ Point2 get_offset() { return offset; }
+ void set_offset(Point2 p_offset) { offset = p_offset; }
+ Color get_color() { return color; }
+ void set_color(Color p_color) { color = p_color; }
+ int get_character() { return (int)character; }
+ void set_character(int p_char) { character = (CharType)p_char; }
+ Dictionary get_environment() { return environment; }
+ void set_environment(Dictionary p_environment) { environment = p_environment; }
+
+ Variant get_value_or(String p_key, Variant p_default_value);
+};
+
+#endif // RICH_TEXT_EFFECT_H
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index d6c0981ebc..d9ae42d6e6 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -30,10 +30,11 @@
#include "rich_text_label.h"
+#include "core/math/math_defs.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
+#include "modules/regex/regex.h"
#include "scene/scene_string_names.h"
-
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
#endif
@@ -139,6 +140,7 @@ Rect2 RichTextLabel::_get_text_rect() {
Ref<StyleBox> style = get_stylebox("normal");
return Rect2(style->get_offset(), get_size() - style->get_minimum_size());
}
+
int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) {
RID ci;
@@ -292,7 +294,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
Color selection_bg;
if (p_mode == PROCESS_DRAW) {
-
selection_fg = get_color("font_color_selected");
selection_bg = get_color("selection_color");
}
@@ -343,18 +344,24 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
Color font_color_shadow;
bool underline = false;
bool strikethrough = false;
+ ItemFade *fade = NULL;
+ int it_char_start = p_char_count;
+
+ Vector<ItemFX *> fx_stack = Vector<ItemFX *>();
+ bool custom_fx_ok = true;
if (p_mode == PROCESS_DRAW) {
color = _find_color(text, p_base_color);
font_color_shadow = _find_color(text, p_font_color_shadow);
if (_find_underline(text) || (_find_meta(text, &meta) && underline_meta)) {
-
underline = true;
} else if (_find_strikethrough(text)) {
-
strikethrough = true;
}
+ fade = _fetch_by_type<ItemFade>(text, ITEM_FADE);
+ _fetch_item_stack<ItemFX>(text, fx_stack);
+
} else if (p_mode == PROCESS_CACHE) {
l.char_count += text->text.length();
}
@@ -431,8 +438,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
ofs += cw;
} else if (p_mode == PROCESS_DRAW) {
-
bool selected = false;
+ Color fx_color = Color(color);
+ Point2 fx_offset;
+ CharType fx_char = c[i];
+
if (selection.active) {
int cofs = (&c[i]) - cf;
@@ -442,8 +452,78 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
int cw = 0;
+ int c_item_offset = p_char_count - it_char_start;
+
+ float faded_visibility = 1.0f;
+ if (fade) {
+ if (c_item_offset >= fade->starting_index) {
+ faded_visibility -= (float)(c_item_offset - fade->starting_index) / (float)fade->length;
+ faded_visibility = faded_visibility < 0.0f ? 0.0f : faded_visibility;
+ }
+ fx_color.a = faded_visibility;
+ }
+
+ bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) &&
+ faded_visibility > 0.0f);
+
+ for (int j = 0; j < fx_stack.size(); j++) {
+ ItemCustomFX *item_custom = Object::cast_to<ItemCustomFX>(fx_stack[j]);
+ ItemShake *item_shake = Object::cast_to<ItemShake>(fx_stack[j]);
+ ItemWave *item_wave = Object::cast_to<ItemWave>(fx_stack[j]);
+ ItemTornado *item_tornado = Object::cast_to<ItemTornado>(fx_stack[j]);
+ ItemRainbow *item_rainbow = Object::cast_to<ItemRainbow>(fx_stack[j]);
+
+ if (item_custom && custom_fx_ok) {
+ Ref<CharFXTransform> charfx = Ref<CharFXTransform>(memnew(CharFXTransform));
+ Ref<RichTextEffect> custom_effect = _get_custom_effect_by_code(item_custom->identifier);
+ if (!custom_effect.is_null()) {
+ charfx->elapsed_time = item_custom->elapsed_time;
+ charfx->environment = item_custom->environment;
+ charfx->relative_index = c_item_offset;
+ charfx->absolute_index = p_char_count;
+ charfx->visibility = visible;
+ charfx->offset = fx_offset;
+ charfx->color = fx_color;
+ charfx->character = fx_char;
+
+ bool effect_status = custom_effect->_process_effect_impl(charfx);
+ custom_fx_ok = effect_status;
+
+ fx_offset += charfx->offset;
+ fx_color = charfx->color;
+ visible &= charfx->visibility;
+ fx_char = charfx->character;
+ }
+ } else if (item_shake) {
+ uint64_t char_current_rand = item_shake->offset_random(c_item_offset);
+ uint64_t char_previous_rand = item_shake->offset_previous_random(c_item_offset);
+ uint64_t max_rand = 2147483647;
+ double current_offset = Math::range_lerp(char_current_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI);
+ double previous_offset = Math::range_lerp(char_previous_rand % max_rand, 0, max_rand, 0.0f, 2.f * (float)Math_PI);
+ double n_time = (double)(item_shake->elapsed_time / (0.5f / item_shake->rate));
+ n_time = (n_time > 1.0) ? 1.0 : n_time;
+ fx_offset += Point2(Math::lerp(Math::sin(previous_offset),
+ Math::sin(current_offset),
+ n_time),
+ Math::lerp(Math::cos(previous_offset),
+ Math::cos(current_offset),
+ n_time)) *
+ (float)item_shake->strength / 10.0f;
+ } else if (item_wave) {
+ double value = Math::sin(item_wave->frequency * item_wave->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_wave->amplitude / 10.0f);
+ fx_offset += Point2(0, 1) * value;
+ } else if (item_tornado) {
+ double torn_x = Math::sin(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius);
+ double torn_y = Math::cos(item_tornado->frequency * item_tornado->elapsed_time + ((p_ofs.x + pofs) / 50)) * (item_tornado->radius);
+ fx_offset += Point2(torn_x, torn_y);
+ } else if (item_rainbow) {
+ fx_color = fx_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + pofs) / 50)),
+ item_rainbow->saturation,
+ item_rainbow->value,
+ fx_color.a);
+ }
+ }
- bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent));
if (visible)
line_is_blank = false;
@@ -451,27 +531,28 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
visible = false;
if (visible) {
+
if (selected) {
- cw = font->get_char_size(c[i], c[i + 1]).x;
+ cw = font->get_char_size(fx_char, c[i + 1]).x;
draw_rect(Rect2(p_ofs.x + pofs, p_ofs.y + y, cw, lh), selection_bg);
}
if (p_font_color_shadow.a > 0) {
float x_ofs_shadow = align_ofs + pofs;
float y_ofs_shadow = y + lh - line_descent;
- font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + shadow_ofs, c[i], c[i + 1], p_font_color_shadow);
+ font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + shadow_ofs, fx_char, c[i + 1], p_font_color_shadow);
if (p_shadow_as_outline) {
- font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow);
- font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(shadow_ofs.x, -shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow);
- font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, -shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow);
+ font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, shadow_ofs.y), fx_char, c[i + 1], p_font_color_shadow);
+ font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(shadow_ofs.x, -shadow_ofs.y), fx_char, c[i + 1], p_font_color_shadow);
+ font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, -shadow_ofs.y), fx_char, c[i + 1], p_font_color_shadow);
}
}
if (selected) {
- drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent), c[i], c[i + 1], override_selected_font_color ? selection_fg : color);
+ drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent), fx_char, c[i + 1], override_selected_font_color ? selection_fg : fx_color);
} else {
- cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent), c[i], c[i + 1], color);
+ cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color);
}
}
@@ -800,6 +881,31 @@ void RichTextLabel::_update_scroll() {
}
}
+void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_time) {
+ Item *it = p_frame;
+ while (it) {
+ ItemFX *ifx = Object::cast_to<ItemFX>(it);
+
+ if (!ifx) {
+ it = _get_next_item(it, true);
+ continue;
+ }
+
+ ifx->elapsed_time += p_delta_time;
+
+ ItemShake *shake = Object::cast_to<ItemShake>(it);
+ if (shake) {
+ bool cycle = (shake->elapsed_time > (1.0f / shake->rate));
+ if (cycle) {
+ shake->elapsed_time -= (1.0f / shake->rate);
+ shake->reroll_random();
+ }
+ }
+
+ it = _get_next_item(it, true);
+ }
+}
+
void RichTextLabel::_notification(int p_what) {
switch (p_what) {
@@ -821,11 +927,7 @@ void RichTextLabel::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- if (is_inside_tree() && use_bbcode) {
- parse_bbcode(bbcode);
- //first_invalid_line=0; //invalidate ALL
- //update();
- }
+ update();
} break;
case NOTIFICATION_DRAW: {
@@ -877,6 +979,15 @@ void RichTextLabel::_notification(int p_what) {
from_line++;
}
+ } break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ float dt = get_process_delta_time();
+
+ for (int i = 0; i < custom_effects.size(); i++) {
+ }
+
+ _update_fx(main, dt);
+ update();
}
}
}
@@ -920,9 +1031,12 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const {
- if (!underline_meta || selection.click)
+ if (!underline_meta)
return CURSOR_ARROW;
+ if (selection.click)
+ return CURSOR_IBEAM;
+
if (main->first_invalid_line < main->lines.size())
return CURSOR_ARROW; //invalid
@@ -1027,15 +1141,11 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
if (b->get_button_index() == BUTTON_WHEEL_UP) {
-
if (scroll_active)
-
vscroll->set_value(vscroll->get_value() - vscroll->get_page() * b->get_factor() * 0.5 / 8);
}
if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
-
if (scroll_active)
-
vscroll->set_value(vscroll->get_value() + vscroll->get_page() * b->get_factor() * 0.5 / 8);
}
}
@@ -1286,8 +1396,19 @@ bool RichTextLabel::_find_strikethrough(Item *p_item) {
return false;
}
-bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
+bool RichTextLabel::_find_by_type(Item *p_item, ItemType p_type) {
+ Item *item = p_item;
+ while (item) {
+ if (item->type == p_type) {
+ return true;
+ }
+ item = item->parent;
+ }
+ return false;
+}
+
+bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
Item *item = p_item;
while (item) {
@@ -1619,6 +1740,49 @@ void RichTextLabel::push_table(int p_columns) {
_add_item(item, true, true);
}
+void RichTextLabel::push_fade(int p_start_index, int p_length) {
+ ItemFade *item = memnew(ItemFade);
+ item->starting_index = p_start_index;
+ item->length = p_length;
+ _add_item(item, true);
+}
+
+void RichTextLabel::push_shake(int p_strength = 10, float p_rate = 24.0f) {
+ ItemShake *item = memnew(ItemShake);
+ item->strength = p_strength;
+ item->rate = p_rate;
+ _add_item(item, true);
+}
+
+void RichTextLabel::push_wave(float p_frequency = 1.0f, float p_amplitude = 10.0f) {
+ ItemWave *item = memnew(ItemWave);
+ item->frequency = p_frequency;
+ item->amplitude = p_amplitude;
+ _add_item(item, true);
+}
+
+void RichTextLabel::push_tornado(float p_frequency = 1.0f, float p_radius = 10.0f) {
+ ItemTornado *item = memnew(ItemTornado);
+ item->frequency = p_frequency;
+ item->radius = p_radius;
+ _add_item(item, true);
+}
+
+void RichTextLabel::push_rainbow(float p_saturation, float p_value, float p_frequency) {
+ ItemRainbow *item = memnew(ItemRainbow);
+ item->frequency = p_frequency;
+ item->saturation = p_saturation;
+ item->value = p_value;
+ _add_item(item, true);
+}
+
+void RichTextLabel::push_customfx(String p_identifier, Dictionary p_environment) {
+ ItemCustomFX *item = memnew(ItemCustomFX);
+ item->identifier = p_identifier;
+ item->environment = p_environment;
+ _add_item(item, true);
+}
+
void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_ratio) {
ERR_FAIL_COND(current->type != ITEM_TABLE);
@@ -1763,6 +1927,8 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
bool in_bold = false;
bool in_italics = false;
+ set_process_internal(false);
+
while (pos < p_bbcode.length()) {
int brk_pos = p_bbcode.find("[", pos);
@@ -1786,7 +1952,6 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
-
if (tag.begins_with("/") && tag_stack.size()) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
@@ -1799,9 +1964,8 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
indent_level--;
if (!tag_ok) {
-
- add_text("[");
- pos++;
+ add_text("[" + tag);
+ pos = brk_end;
continue;
}
@@ -1993,10 +2157,145 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("font");
- } else {
+ } else if (tag.begins_with("fade")) {
+ Vector<String> tags = tag.split(" ", false);
+ int startIndex = 0;
+ int length = 10;
+
+ if (tags.size() > 1) {
+ tags.remove(0);
+ for (int i = 0; i < tags.size(); i++) {
+ String expr = tags[i];
+ if (expr.begins_with("start=")) {
+ String start_str = expr.substr(6, expr.length());
+ startIndex = start_str.to_int();
+ } else if (expr.begins_with("length=")) {
+ String end_str = expr.substr(7, expr.length());
+ length = end_str.to_int();
+ }
+ }
+ }
- add_text("["); //ignore
- pos = brk_pos + 1;
+ push_fade(startIndex, length);
+ pos = brk_end + 1;
+ tag_stack.push_front("fade");
+ } else if (tag.begins_with("shake")) {
+ Vector<String> tags = tag.split(" ", false);
+ int strength = 5;
+ float rate = 20.0f;
+
+ if (tags.size() > 1) {
+ tags.remove(0);
+ for (int i = 0; i < tags.size(); i++) {
+ String expr = tags[i];
+ if (expr.begins_with("level=")) {
+ String str_str = expr.substr(6, expr.length());
+ strength = str_str.to_int();
+ } else if (expr.begins_with("rate=")) {
+ String rate_str = expr.substr(5, expr.length());
+ rate = rate_str.to_float();
+ }
+ }
+ }
+
+ push_shake(strength, rate);
+ pos = brk_end + 1;
+ tag_stack.push_front("shake");
+ set_process_internal(true);
+ } else if (tag.begins_with("wave")) {
+ Vector<String> tags = tag.split(" ", false);
+ float amplitude = 20.0f;
+ float period = 5.0f;
+
+ if (tags.size() > 1) {
+ tags.remove(0);
+ for (int i = 0; i < tags.size(); i++) {
+ String expr = tags[i];
+ if (expr.begins_with("amp=")) {
+ String amp_str = expr.substr(4, expr.length());
+ amplitude = amp_str.to_float();
+ } else if (expr.begins_with("freq=")) {
+ String period_str = expr.substr(5, expr.length());
+ period = period_str.to_float();
+ }
+ }
+ }
+
+ push_wave(period, amplitude);
+ pos = brk_end + 1;
+ tag_stack.push_front("wave");
+ set_process_internal(true);
+ } else if (tag.begins_with("tornado")) {
+ Vector<String> tags = tag.split(" ", false);
+ float radius = 10.0f;
+ float frequency = 1.0f;
+
+ if (tags.size() > 1) {
+ tags.remove(0);
+ for (int i = 0; i < tags.size(); i++) {
+ String expr = tags[i];
+ if (expr.begins_with("radius=")) {
+ String amp_str = expr.substr(7, expr.length());
+ radius = amp_str.to_float();
+ } else if (expr.begins_with("freq=")) {
+ String period_str = expr.substr(5, expr.length());
+ frequency = period_str.to_float();
+ }
+ }
+ }
+
+ push_tornado(frequency, radius);
+ pos = brk_end + 1;
+ tag_stack.push_front("tornado");
+ set_process_internal(true);
+ } else if (tag.begins_with("rainbow")) {
+ Vector<String> tags = tag.split(" ", false);
+ float saturation = 0.8f;
+ float value = 0.8f;
+ float frequency = 1.0f;
+
+ if (tags.size() > 1) {
+ tags.remove(0);
+ for (int i = 0; i < tags.size(); i++) {
+ String expr = tags[i];
+ if (expr.begins_with("sat=")) {
+ String sat_str = expr.substr(4, expr.length());
+ saturation = sat_str.to_float();
+ } else if (expr.begins_with("val=")) {
+ String val_str = expr.substr(4, expr.length());
+ value = val_str.to_float();
+ } else if (expr.begins_with("freq=")) {
+ String freq_str = expr.substr(5, expr.length());
+ frequency = freq_str.to_float();
+ }
+ }
+ }
+
+ push_rainbow(saturation, value, frequency);
+ pos = brk_end + 1;
+ tag_stack.push_front("rainbow");
+ set_process_internal(true);
+ } else {
+ Vector<String> expr = tag.split(" ", false);
+ if (expr.size() < 1) {
+ add_text("[");
+ pos = brk_pos + 1;
+ } else {
+ String identifier = expr[0];
+ expr.remove(0);
+ Dictionary properties = parse_expressions_for_values(expr);
+ Ref<RichTextEffect> effect = _get_custom_effect_by_code(identifier);
+
+ if (!effect.is_null()) {
+ push_customfx(identifier, properties);
+ pos = brk_end + 1;
+ tag_stack.push_front(identifier);
+ set_process_internal(true);
+ } else {
+ add_text("["); //ignore
+ pos = brk_pos + 1;
+ }
+ }
}
}
@@ -2205,6 +2504,34 @@ float RichTextLabel::get_percent_visible() const {
return percent_visible;
}
+void RichTextLabel::set_effects(const Vector<Variant> &effects) {
+ custom_effects.clear();
+ for (int i = 0; i < effects.size(); i++) {
+ Ref<RichTextEffect> effect = Ref<RichTextEffect>(effects[i]);
+ custom_effects.push_back(effect);
+ }
+
+ parse_bbcode(bbcode);
+}
+
+Vector<Variant> RichTextLabel::get_effects() {
+ Vector<Variant> r;
+ for (int i = 0; i < custom_effects.size(); i++) {
+ r.push_back(custom_effects[i].get_ref_ptr());
+ }
+ return r;
+}
+
+void RichTextLabel::install_effect(const Variant effect) {
+ Ref<RichTextEffect> rteffect;
+ rteffect = effect;
+
+ if (rteffect.is_valid()) {
+ custom_effects.push_back(effect);
+ parse_bbcode(bbcode);
+ }
+}
+
int RichTextLabel::get_content_height() {
int total_height = 0;
if (main->lines.size())
@@ -2281,6 +2608,12 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height);
+ ClassDB::bind_method(D_METHOD("parse_expressions_for_values", "expressions"), &RichTextLabel::parse_expressions_for_values);
+
+ ClassDB::bind_method(D_METHOD("set_effects", "effects"), &RichTextLabel::set_effects);
+ ClassDB::bind_method(D_METHOD("get_effects"), &RichTextLabel::get_effects);
+ ClassDB::bind_method(D_METHOD("install_effect", "effect"), &RichTextLabel::install_effect);
+
ADD_GROUP("BBCode", "bbcode_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "bbcode_text", PROPERTY_HINT_MULTILINE_TEXT), "set_bbcode", "get_bbcode");
@@ -2298,6 +2631,8 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_RESOURCE_TYPE, "17/17:RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE), "RichTextEffect"), "set_effects", "get_effects");
+
ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("meta_hover_ended", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
@@ -2323,11 +2658,16 @@ void RichTextLabel::_bind_methods() {
BIND_ENUM_CONSTANT(ITEM_INDENT);
BIND_ENUM_CONSTANT(ITEM_LIST);
BIND_ENUM_CONSTANT(ITEM_TABLE);
+ BIND_ENUM_CONSTANT(ITEM_FADE);
+ BIND_ENUM_CONSTANT(ITEM_SHAKE);
+ BIND_ENUM_CONSTANT(ITEM_WAVE);
+ BIND_ENUM_CONSTANT(ITEM_TORNADO);
+ BIND_ENUM_CONSTANT(ITEM_RAINBOW);
+ BIND_ENUM_CONSTANT(ITEM_CUSTOMFX);
BIND_ENUM_CONSTANT(ITEM_META);
}
void RichTextLabel::set_visible_characters(int p_visible) {
-
visible_characters = p_visible;
update();
}
@@ -2359,6 +2699,77 @@ Size2 RichTextLabel::get_minimum_size() const {
return Size2();
}
+Ref<RichTextEffect> RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) {
+ Ref<RichTextEffect> r;
+ for (int i = 0; i < custom_effects.size(); i++) {
+ if (!custom_effects[i].is_valid())
+ continue;
+
+ if (custom_effects[i]->get_bbcode() == p_bbcode_identifier) {
+ r = custom_effects[i];
+ }
+ }
+
+ return r;
+}
+
+Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressions) {
+ Dictionary d = Dictionary();
+ for (int i = 0; i < p_expressions.size(); i++) {
+ String expression = p_expressions[i];
+
+ Array a = Array();
+ Vector<String> parts = expression.split("=", true);
+ String key = parts[0];
+ if (parts.size() != 2) {
+ return d;
+ }
+
+ Vector<String> values = parts[1].split(",", false);
+
+ RegEx color = RegEx();
+ color.compile("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
+ RegEx nodepath = RegEx();
+ nodepath.compile("^\\$");
+ RegEx boolean = RegEx();
+ boolean.compile("^(true|false)$");
+ RegEx decimal = RegEx();
+ decimal.compile("^-?^.?\\d+(\\.\\d+?)?$");
+ RegEx numerical = RegEx();
+ numerical.compile("^\\d+$");
+
+ for (int j = 0; j < values.size(); j++) {
+ if (!color.search(values[j]).is_null()) {
+ a.append(Color::html(values[j]));
+ } else if (!nodepath.search(values[j]).is_null()) {
+ if (values[j].begins_with("$")) {
+ String v = values[j].substr(1, values[j].length());
+ a.append(NodePath(v));
+ }
+ } else if (!boolean.search(values[j]).is_null()) {
+ if (values[j] == "true") {
+ a.append(true);
+ } else if (values[j] == "false") {
+ a.append(false);
+ }
+ } else if (!decimal.search(values[j]).is_null()) {
+ a.append(values[j].to_double());
+ } else if (!numerical.search(values[j]).is_null()) {
+ a.append(values[j].to_int());
+ } else {
+ a.append(values[j]);
+ }
+ }
+
+ if (values.size() > 1) {
+ d[key] = a;
+ } else if (values.size() == 1) {
+ d[key] = a[0];
+ }
+ }
+ return d;
+}
+
RichTextLabel::RichTextLabel() {
main = memnew(ItemFrame);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 21d099c37a..1c212700ef 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -31,6 +31,7 @@
#ifndef RICH_TEXT_LABEL_H
#define RICH_TEXT_LABEL_H
+#include "rich_text_effect.h"
#include "scene/gui/scroll_bar.h"
class RichTextLabel : public Control {
@@ -67,7 +68,13 @@ public:
ITEM_INDENT,
ITEM_LIST,
ITEM_TABLE,
- ITEM_META
+ ITEM_FADE,
+ ITEM_SHAKE,
+ ITEM_WAVE,
+ ITEM_TORNADO,
+ ITEM_RAINBOW,
+ ITEM_META,
+ ITEM_CUSTOMFX
};
protected:
@@ -96,7 +103,7 @@ private:
}
};
- struct Item {
+ struct Item : public Object {
int index;
Item *parent;
@@ -214,6 +221,101 @@ private:
ItemTable() { type = ITEM_TABLE; }
};
+ struct ItemFade : public Item {
+ int starting_index;
+ int length;
+
+ ItemFade() { type = ITEM_FADE; }
+ };
+
+ struct ItemFX : public Item {
+ float elapsed_time;
+
+ ItemFX() {
+ elapsed_time = 0.0f;
+ }
+ };
+
+ struct ItemShake : public ItemFX {
+ int strength;
+ float rate;
+ uint64_t _current_rng;
+ uint64_t _previous_rng;
+
+ ItemShake() {
+ strength = 0;
+ rate = 0.0f;
+ _current_rng = 0;
+ type = ITEM_SHAKE;
+ }
+
+ void reroll_random() {
+ _previous_rng = _current_rng;
+ _current_rng = Math::rand();
+ }
+
+ uint64_t offset_random(int index) {
+ return (_current_rng >> (index % 64)) |
+ (_current_rng << (64 - (index % 64)));
+ }
+
+ uint64_t offset_previous_random(int index) {
+ return (_previous_rng >> (index % 64)) |
+ (_previous_rng << (64 - (index % 64)));
+ }
+ };
+
+ struct ItemWave : public ItemFX {
+ float frequency;
+ float amplitude;
+
+ ItemWave() {
+ frequency = 1.0f;
+ amplitude = 1.0f;
+ type = ITEM_WAVE;
+ }
+ };
+
+ struct ItemTornado : public ItemFX {
+ float radius;
+ float frequency;
+
+ ItemTornado() {
+ radius = 1.0f;
+ frequency = 1.0f;
+ type = ITEM_TORNADO;
+ }
+ };
+
+ struct ItemRainbow : public ItemFX {
+ float saturation;
+ float value;
+ float frequency;
+
+ ItemRainbow() {
+ saturation = 0.8f;
+ value = 0.8f;
+ frequency = 1.0f;
+ type = ITEM_RAINBOW;
+ }
+ };
+
+ struct ItemCustomFX : public ItemFX {
+ String identifier;
+ Dictionary environment;
+
+ ItemCustomFX() {
+ identifier = "";
+ environment = Dictionary();
+ type = ITEM_CUSTOMFX;
+ }
+
+ virtual ~ItemCustomFX() {
+ _clear_children();
+ environment.clear();
+ }
+ };
+
ItemFrame *main;
Item *current;
ItemFrame *current_frame;
@@ -239,6 +341,8 @@ private:
ItemMeta *meta_hovering;
Variant current_meta;
+ Vector<Ref<RichTextEffect> > custom_effects;
+
void _invalidate_current_line(ItemFrame *p_frame);
void _validate_line_caches(ItemFrame *p_frame);
@@ -246,7 +350,6 @@ private:
void _remove_item(Item *p_item, const int p_line, const int p_subitem_line);
struct ProcessState {
-
int line_width;
};
@@ -287,8 +390,36 @@ private:
bool _find_strikethrough(Item *p_item);
bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL);
bool _find_layout_subitem(Item *from, Item *to);
+ bool _find_by_type(Item *p_item, ItemType p_type);
+ template <typename T>
+ T *_fetch_by_type(Item *p_item, ItemType p_type) {
+ Item *item = p_item;
+ T *result = NULL;
+ while (item) {
+ if (item->type == p_type) {
+ result = Object::cast_to<T>(item);
+ if (result)
+ return result;
+ }
+ item = item->parent;
+ }
+
+ return result;
+ };
+ template <typename T>
+ void _fetch_item_stack(Item *p_item, Vector<T *> &r_stack) {
+ Item *item = p_item;
+ while (item) {
+ T *found = Object::cast_to<T>(item);
+ if (found) {
+ r_stack.push_back(found);
+ }
+ item = item->parent;
+ }
+ }
void _update_scroll();
+ void _update_fx(ItemFrame *p_frame, float p_delta_time);
void _scroll_changed(double);
void _gui_input(Ref<InputEvent> p_event);
@@ -296,6 +427,8 @@ private:
Item *_get_prev_item(Item *p_item, bool p_free = false);
Rect2 _get_text_rect();
+ Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier);
+ virtual Dictionary parse_expressions_for_values(Vector<String> p_expressions);
bool use_bbcode;
String bbcode;
@@ -322,6 +455,12 @@ public:
void push_list(ListType p_list);
void push_meta(const Variant &p_meta);
void push_table(int p_columns);
+ void push_fade(int p_start_index, int p_length);
+ void push_shake(int p_strength, float p_rate);
+ void push_wave(float p_frequency, float p_amplitude);
+ void push_tornado(float p_frequency, float p_radius);
+ void push_rainbow(float p_saturation, float p_value, float p_frequency);
+ void push_customfx(String p_identifier, Dictionary p_environment);
void set_table_column_expand(int p_column, bool p_expand, int p_ratio = 1);
int get_current_table_column() const;
void push_cell();
@@ -380,6 +519,11 @@ public:
void set_percent_visible(float p_percent);
float get_percent_visible() const;
+ void set_effects(const Vector<Variant> &effects);
+ Vector<Variant> get_effects();
+
+ void install_effect(const Variant effect);
+
void set_fixed_size_to_width(int p_width);
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 5ceabfc06b..cbcee1dae3 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -33,10 +33,6 @@
#include "scene/gui/range.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ScrollBar : public Range {
GDCLASS(ScrollBar, Range);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 461281a4ed..a840e3fec1 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -382,7 +382,10 @@ void ScrollContainer::update_scrollbars() {
Size2 min = child_max_size;
- if (!scroll_v || min.height <= size.height - hmin.height) {
+ bool hide_scroll_v = !scroll_v || min.height <= size.height - hmin.height;
+ bool hide_scroll_h = !scroll_h || min.width <= size.width - vmin.width;
+
+ if (hide_scroll_v) {
v_scroll->hide();
v_scroll->set_max(0);
@@ -391,11 +394,16 @@ void ScrollContainer::update_scrollbars() {
v_scroll->show();
v_scroll->set_max(min.height);
- v_scroll->set_page(size.height - hmin.height);
+ if (hide_scroll_h) {
+ v_scroll->set_page(size.height);
+ } else {
+ v_scroll->set_page(size.height - hmin.height);
+ }
+
scroll.y = v_scroll->get_value();
}
- if (!scroll_h || min.width <= size.width - vmin.width) {
+ if (hide_scroll_h) {
h_scroll->hide();
h_scroll->set_max(0);
@@ -404,7 +412,12 @@ void ScrollContainer::update_scrollbars() {
h_scroll->show();
h_scroll->set_max(min.width);
- h_scroll->set_page(size.width - vmin.width);
+ if (hide_scroll_v) {
+ h_scroll->set_page(size.width);
+ } else {
+ h_scroll->set_page(size.width - vmin.width);
+ }
+
scroll.x = h_scroll->get_value();
}
}
diff --git a/scene/gui/separator.h b/scene/gui/separator.h
index 54ad9b5bb5..89039f3112 100644
--- a/scene/gui/separator.h
+++ b/scene/gui/separator.h
@@ -31,10 +31,6 @@
#ifndef SEPARATOR_H
#define SEPARATOR_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
#include "scene/gui/control.h"
class Separator : public Control {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 279253889c..172c366c41 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "spin_box.h"
+#include "core/math/expression.h"
#include "core/os/input.h"
Size2 SpinBox::get_minimum_size() const {
@@ -40,7 +41,7 @@ Size2 SpinBox::get_minimum_size() const {
void SpinBox::_value_changed(double) {
- String value = String::num(get_value(), Math::step_decimals(get_step()));
+ String value = String::num(get_value(), Math::range_step_decimals(get_step()));
if (prefix != "")
value = prefix + " " + value;
if (suffix != "")
@@ -50,15 +51,19 @@ void SpinBox::_value_changed(double) {
void SpinBox::_text_entered(const String &p_string) {
- /*
- if (!p_string.is_numeric())
+ Ref<Expression> expr;
+ expr.instance();
+ // Ignore the prefix and suffix in the expression
+ Error err = expr->parse(p_string.trim_prefix(prefix + " ").trim_suffix(" " + suffix));
+ if (err != OK) {
return;
- */
- String value = p_string;
- if (prefix != "" && p_string.begins_with(prefix))
- value = p_string.substr(prefix.length(), p_string.length() - prefix.length());
- set_value(value.to_double());
- _value_changed(0);
+ }
+
+ Variant value = expr->execute(Array(), NULL, false);
+ if (value.get_type() != Variant::NIL) {
+ set_value(value);
+ _value_changed(0);
+ }
}
LineEdit *SpinBox::get_line_edit() {
@@ -170,6 +175,10 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
void SpinBox::_line_edit_focus_exit() {
+ // discontinue because the focus_exit was caused by right-click context menu
+ if (line_edit->get_menu()->is_visible())
+ return;
+
_text_entered(line_edit->get_text());
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 39c76e6646..292d80be9d 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -303,7 +303,7 @@ void TabContainer::_notification(int p_what) {
// Draw the tab contents.
Control *control = Object::cast_to<Control>(tabs[i + first_tab_cache]);
- String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(control->get_name());
+ String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(tr(control->get_name()));
int x_content = tab_rect.position.x + tab_style->get_margin(MARGIN_LEFT);
int top_margin = tab_style->get_margin(MARGIN_TOP);
@@ -840,7 +840,7 @@ Size2 TabContainer::get_minimum_size() const {
Control *c = tabs[i];
- if (!c->is_visible_in_tree())
+ if (!c->is_visible_in_tree() && !use_hidden_tabs_for_min_size)
continue;
Size2 cms = c->get_combined_minimum_size();
@@ -887,6 +887,13 @@ int TabContainer::get_tabs_rearrange_group() const {
return tabs_rearrange_group;
}
+void TabContainer::set_use_hidden_tabs_for_min_size(bool p_use_hidden_tabs) {
+ use_hidden_tabs_for_min_size = p_use_hidden_tabs;
+}
+
+bool TabContainer::get_use_hidden_tabs_for_min_size() const {
+ return use_hidden_tabs_for_min_size;
+}
void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &TabContainer::_gui_input);
@@ -913,6 +920,9 @@ void TabContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabContainer::set_tabs_rearrange_group);
ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &TabContainer::get_tabs_rearrange_group);
+ ClassDB::bind_method(D_METHOD("set_use_hidden_tabs_for_min_size", "enabled"), &TabContainer::set_use_hidden_tabs_for_min_size);
+ ClassDB::bind_method(D_METHOD("get_use_hidden_tabs_for_min_size"), &TabContainer::get_use_hidden_tabs_for_min_size);
+
ClassDB::bind_method(D_METHOD("_child_renamed_callback"), &TabContainer::_child_renamed_callback);
ClassDB::bind_method(D_METHOD("_on_theme_changed"), &TabContainer::_on_theme_changed);
ClassDB::bind_method(D_METHOD("_update_current_tab"), &TabContainer::_update_current_tab);
@@ -925,6 +935,7 @@ void TabContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_visible"), "set_tabs_visible", "are_tabs_visible");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hidden_tabs_for_min_size"), "set_use_hidden_tabs_for_min_size", "get_use_hidden_tabs_for_min_size");
BIND_ENUM_CONSTANT(ALIGN_LEFT);
BIND_ENUM_CONSTANT(ALIGN_CENTER);
@@ -945,4 +956,5 @@ TabContainer::TabContainer() {
popup = NULL;
drag_to_rearrange_enabled = false;
tabs_rearrange_group = -1;
+ use_hidden_tabs_for_min_size = false;
}
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index f7a9fb64fd..0314f86837 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -59,6 +59,7 @@ private:
int _get_top_margin() const;
Popup *popup;
bool drag_to_rearrange_enabled;
+ bool use_hidden_tabs_for_min_size;
int tabs_rearrange_group;
Vector<Control *> _get_tabs() const;
@@ -118,6 +119,8 @@ public:
bool get_drag_to_rearrange_enabled() const;
void set_tabs_rearrange_group(int p_group_id);
int get_tabs_rearrange_group() const;
+ void set_use_hidden_tabs_for_min_size(bool p_use_hidden_tabs);
+ bool get_use_hidden_tabs_for_min_size() const;
TabContainer();
};
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index ff0c723141..d5f1d317c7 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -129,7 +129,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
int len = text[p_line].data.length();
const CharType *str = text[p_line].data.c_str();
- //update width
+ // Update width.
for (int i = 0; i < len; i++) {
w += get_char_width(str[i], str[i + 1], w);
@@ -139,7 +139,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
text.write[p_line].wrap_amount_cache = -1;
- //update regions
+ // Update regions.
text.write[p_line].region_info.clear();
@@ -148,7 +148,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
if (!_is_symbol(str[i]))
continue;
if (str[i] == '\\') {
- i++; //skip quoted anything
+ i++; // Skip quoted anything.
continue;
}
@@ -275,7 +275,7 @@ void TextEdit::Text::clear() {
}
int TextEdit::Text::get_max_width(bool p_exclude_hidden) const {
- //quite some work.. but should be fast enough.
+ // Quite some work, but should be fast enough.
int max = 0;
for (int i = 0; i < text.size(); i++) {
@@ -323,7 +323,7 @@ int TextEdit::Text::get_char_width(CharType c, CharType next_c, int px) const {
if (left == 0)
w = tab_w;
else
- w = tab_w - px % tab_w; // is right...
+ w = tab_w - px % tab_w; // Is right.
} else {
w = font->get_char_size(c, next_c).width;
@@ -367,23 +367,25 @@ void TextEdit::_update_scrollbars() {
total_width += cache.fold_gutter_width;
}
+ if (draw_minimap) {
+ total_width += cache.minimap_width;
+ }
+
bool use_hscroll = true;
bool use_vscroll = true;
+ // Thanks yessopie for this clever bit of logic.
if (total_rows <= visible_rows && total_width <= visible_width) {
- //thanks yessopie for this clever bit of logic
+
use_hscroll = false;
use_vscroll = false;
-
} else {
if (total_rows > visible_rows && total_width <= visible_width) {
- //thanks yessopie for this clever bit of logic
use_hscroll = false;
}
if (total_rows <= visible_rows && total_width > visible_width) {
- //thanks yessopie for this clever bit of logic
use_vscroll = false;
}
}
@@ -459,6 +461,7 @@ void TextEdit::_click_selection_held() {
}
void TextEdit::_update_selection_mode_pointer() {
+ dragging_selection = true;
Point2 mp = get_local_mouse_position();
int row, col;
@@ -474,6 +477,7 @@ void TextEdit::_update_selection_mode_pointer() {
}
void TextEdit::_update_selection_mode_word() {
+ dragging_selection = true;
Point2 mp = get_local_mouse_position();
int row, col;
@@ -481,7 +485,7 @@ void TextEdit::_update_selection_mode_word() {
String line = text[row];
int beg = CLAMP(col, 0, line.length());
- // if its the first selection and on whitespace make sure we grab the word instead..
+ // If its the first selection and on whitespace make sure we grab the word instead.
if (!selection.active) {
while (beg > 0 && line[beg] <= 32) {
beg--;
@@ -490,7 +494,7 @@ void TextEdit::_update_selection_mode_word() {
int end = beg;
bool symbol = beg < line.length() && _is_symbol(line[beg]);
- // get the word end and begin points
+ // Get the word end and begin points.
while (beg > 0 && line[beg - 1] > 32 && (symbol == _is_symbol(line[beg - 1]))) {
beg--;
}
@@ -501,7 +505,7 @@ void TextEdit::_update_selection_mode_word() {
end += 1;
}
- // initial selection
+ // Initial selection.
if (!selection.active) {
select(row, beg, row, end);
selection.selecting_column = beg;
@@ -530,6 +534,7 @@ void TextEdit::_update_selection_mode_word() {
}
void TextEdit::_update_selection_mode_line() {
+ dragging_selection = true;
Point2 mp = get_local_mouse_position();
int row, col;
@@ -537,11 +542,11 @@ void TextEdit::_update_selection_mode_line() {
col = 0;
if (row < selection.selecting_line) {
- // cursor is above us
+ // Cursor is above us.
cursor_set_line(row - 1, false);
selection.selecting_column = text[selection.selecting_line].length();
} else {
- // cursor is below us
+ // Cursor is below us.
cursor_set_line(row + 1, false);
selection.selecting_column = 0;
col = text[row].length();
@@ -554,11 +559,58 @@ void TextEdit::_update_selection_mode_line() {
click_select_held->start();
}
+void TextEdit::_update_minimap_click() {
+ Point2 mp = get_local_mouse_position();
+
+ int xmargin_end = get_size().width - cache.style_normal->get_margin(MARGIN_RIGHT);
+ if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.y > xmargin_end)) {
+ minimap_clicked = false;
+ return;
+ }
+ minimap_clicked = true;
+ dragging_minimap = true;
+
+ int row;
+ _get_minimap_mouse_row(Point2i(mp.x, mp.y), row);
+
+ if (row >= get_first_visible_line() && (row < get_last_visible_line() || row >= (text.size() - 1))) {
+ minimap_scroll_ratio = v_scroll->get_as_ratio();
+ minimap_scroll_click_pos = mp.y;
+ can_drag_minimap = true;
+ return;
+ }
+
+ int wi;
+ int first_line = row - num_lines_from_rows(row, 0, -get_visible_rows() / 2, wi) + 1;
+ double delta = get_scroll_pos_for_line(first_line, wi) - get_v_scroll();
+ if (delta < 0) {
+ _scroll_up(-delta);
+ } else {
+ _scroll_down(delta);
+ }
+}
+
+void TextEdit::_update_minimap_drag() {
+
+ if (!can_drag_minimap) {
+ return;
+ }
+
+ int control_height = _get_control_height();
+ int scroll_height = v_scroll->get_max() * (minimap_char_size.y + minimap_line_spacing);
+ if (control_height > scroll_height) {
+ control_height = scroll_height;
+ }
+
+ Point2 mp = get_local_mouse_position();
+ double diff = (mp.y - minimap_scroll_click_pos) / control_height;
+ v_scroll->set_as_ratio(minimap_scroll_ratio + diff);
+}
+
void TextEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
_update_caches();
if (cursor_changed_dirty)
MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit");
@@ -567,14 +619,19 @@ void TextEdit::_notification(int p_what) {
_update_wrap_at();
} break;
case NOTIFICATION_RESIZED: {
-
_update_scrollbars();
- call_deferred("_update_wrap_at");
+ _update_wrap_at();
+ } break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (is_visible()) {
+ call_deferred("_update_scrollbars");
+ call_deferred("_update_wrap_at");
+ }
} break;
case NOTIFICATION_THEME_CHANGED: {
-
_update_caches();
_update_wrap_at();
+ syntax_highlighting_cache.clear();
} break;
case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
window_has_focus = true;
@@ -590,24 +647,26 @@ void TextEdit::_notification(int p_what) {
if (scrolling && get_v_scroll() != target_v_scroll) {
double target_y = target_v_scroll - get_v_scroll();
double dist = sqrt(target_y * target_y);
- double vel = ((target_y / dist) * v_scroll_speed) * get_physics_process_delta_time();
+ // To ensure minimap is responsive override the speed setting.
+ double vel = ((target_y / dist) * ((minimap_clicked) ? 3000 : v_scroll_speed)) * get_physics_process_delta_time();
if (Math::abs(vel) >= dist) {
set_v_scroll(target_v_scroll);
scrolling = false;
+ minimap_clicked = false;
set_physics_process_internal(false);
} else {
set_v_scroll(get_v_scroll() + vel);
}
} else {
scrolling = false;
+ minimap_clicked = false;
set_physics_process_internal(false);
}
} break;
case NOTIFICATION_DRAW: {
-
if (first_draw) {
- //size may not be the final one, so attempts to ensure cursor was visible may have failed
+ // Size may not be the final one, so attempts to ensure cursor was visible may have failed.
adjust_viewport_to_cursor();
first_draw = false;
}
@@ -637,6 +696,11 @@ void TextEdit::_notification(int p_what) {
cache.fold_gutter_width = 0;
}
+ cache.minimap_width = 0;
+ if (draw_minimap) {
+ cache.minimap_width = minimap_width;
+ }
+
int line_number_char_count = 0;
{
@@ -660,8 +724,9 @@ void TextEdit::_notification(int p_what) {
RID ci = get_canvas_item();
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
- int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT);
- //let's do it easy for now:
+
+ int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT) - cache.minimap_width;
+ // Let's do it easy for now.
cache.style_normal->draw(ci, Rect2(Point2(), size));
if (readonly) {
cache.style_readonly->draw(ci, Rect2(Point2(), size));
@@ -701,7 +766,7 @@ void TextEdit::_notification(int p_what) {
if (brace_matching_enabled && cursor.line >= 0 && cursor.line < text.size() && cursor.column >= 0) {
if (cursor.column < text[cursor.line].length()) {
- //check for open
+ // Check for open.
CharType c = text[cursor.line][cursor.column];
CharType closec = 0;
@@ -723,7 +788,7 @@ void TextEdit::_notification(int p_what) {
for (int j = from; j < text[i].length(); j++) {
CharType cc = text[i][j];
- //ignore any brackets inside a string
+ // Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
CharType quotation = cc;
do {
@@ -732,7 +797,7 @@ void TextEdit::_notification(int p_what) {
break;
}
cc = text[i][j];
- //skip over escaped quotation marks inside strings
+ // Skip over escaped quotation marks inside strings.
if (cc == '\\') {
bool escaped = true;
while (j + 1 < text[i].length() && text[i][j + 1] == '\\') {
@@ -789,7 +854,7 @@ void TextEdit::_notification(int p_what) {
for (int j = from; j >= 0; j--) {
CharType cc = text[i][j];
- //ignore any brackets inside a string
+ // Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
CharType quotation = cc;
do {
@@ -798,7 +863,7 @@ void TextEdit::_notification(int p_what) {
break;
}
cc = text[i][j];
- //skip over escaped quotation marks inside strings
+ // Skip over escaped quotation marks inside strings.
if (cc == quotation) {
bool escaped = false;
while (j - 1 >= 0 && text[i][j - 1] == '\\') {
@@ -837,10 +902,10 @@ void TextEdit::_notification(int p_what) {
Point2 cursor_pos;
int cursor_insert_offset_y = 0;
- // get the highlighted words
+ // Get the highlighted words.
String highlighted_text = get_selection_text();
- // check if highlighted words contains only whitespaces (tabs or spaces)
+ // Check if highlighted words contains only whitespaces (tabs or spaces).
bool only_whitespaces_highlighted = highlighted_text.strip_edges() == String();
String line_num_padding = line_numbers_zero_padded ? "0" : " ";
@@ -849,9 +914,156 @@ void TextEdit::_notification(int p_what) {
FontDrawer drawer(cache.font, Color(1, 1, 1));
- int line = get_first_visible_line() - 1;
+ int first_visible_line = get_first_visible_line() - 1;
int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0);
- draw_amount += times_line_wraps(line + 1);
+ draw_amount += times_line_wraps(first_visible_line + 1);
+
+ // minimap
+ if (draw_minimap) {
+ int minimap_visible_lines = _get_minimap_visible_rows();
+ int minimap_line_height = (minimap_char_size.y + minimap_line_spacing);
+ int minimap_tab_size = minimap_char_size.x * indent_size;
+
+ // calculate viewport size and y offset
+ int viewport_height = (draw_amount - 1) * minimap_line_height;
+ int control_height = _get_control_height() - viewport_height;
+ int viewport_offset_y = round(get_scroll_pos_for_line(first_visible_line) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
+
+ // calculate the first line.
+ int num_lines_before = round((viewport_offset_y) / minimap_line_height);
+ int wi;
+ int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line;
+ if (minimap_line >= 0) {
+ minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi);
+ minimap_line -= (smooth_scroll_enabled ? 1 : 0);
+ }
+ int minimap_draw_amount = minimap_visible_lines + times_line_wraps(minimap_line + 1);
+
+ // draw the minimap
+ Color viewport_color = (cache.background_color.get_v() < 0.5) ? Color(1, 1, 1, 0.1) : Color(0, 0, 0, 0.1);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), viewport_offset_y, cache.minimap_width, viewport_height), viewport_color);
+ for (int i = 0; i < minimap_draw_amount; i++) {
+
+ minimap_line++;
+
+ if (minimap_line < 0 || minimap_line >= (int)text.size()) {
+ break;
+ }
+
+ while (is_line_hidden(minimap_line)) {
+ minimap_line++;
+ if (minimap_line < 0 || minimap_line >= (int)text.size()) {
+ break;
+ }
+ }
+
+ Map<int, HighlighterInfo> color_map;
+ if (syntax_coloring) {
+ color_map = _get_line_syntax_highlighting(minimap_line);
+ }
+
+ Color current_color = cache.font_color;
+ if (readonly) {
+ current_color = cache.font_color_readonly;
+ }
+
+ Vector<String> wrap_rows = get_wrap_rows_text(minimap_line);
+ int line_wrap_amount = times_line_wraps(minimap_line);
+ int last_wrap_column = 0;
+
+ for (int line_wrap_index = 0; line_wrap_index < line_wrap_amount + 1; line_wrap_index++) {
+ if (line_wrap_index != 0) {
+ i++;
+ if (i >= minimap_draw_amount)
+ break;
+ }
+
+ const String &str = wrap_rows[line_wrap_index];
+ int indent_px = line_wrap_index != 0 ? get_indent_level(minimap_line) : 0;
+ if (indent_px >= wrap_at) {
+ indent_px = 0;
+ }
+ indent_px = minimap_char_size.x * indent_px;
+
+ if (line_wrap_index > 0) {
+ last_wrap_column += wrap_rows[line_wrap_index - 1].length();
+ }
+
+ if (minimap_line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), i * 3, cache.minimap_width, 2), cache.current_line_color);
+ }
+
+ Color previous_color;
+ int characters = 0;
+ int tabs = 0;
+ for (int j = 0; j < str.length(); j++) {
+ if (syntax_coloring) {
+ if (color_map.has(last_wrap_column + j)) {
+ current_color = color_map[last_wrap_column + j].color;
+ if (readonly) {
+ current_color.a = cache.font_color_readonly.a;
+ }
+ }
+ color = current_color;
+ }
+
+ if (j == 0) {
+ previous_color = color;
+ }
+
+ int xpos = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * j)) + tabs;
+ bool out_of_bounds = (xpos >= xmargin_end + cache.minimap_width);
+
+ bool is_whitespace = _is_whitespace(str[j]);
+ if (!is_whitespace) {
+ characters++;
+
+ if (j < str.length() - 1 && color == previous_color && !out_of_bounds) {
+ continue;
+ }
+
+ // If we've changed colour we are at the start of a new section, therefore we need to go back to the end
+ // of the previous section to draw it, we'll also add the character back on.
+ if (color != previous_color) {
+ characters--;
+ j--;
+
+ if (str[j] == '\t') {
+ tabs -= minimap_tab_size;
+ }
+ }
+ }
+
+ if (characters > 0) {
+ previous_color.a *= 0.6;
+ // take one for zero indexing, and if we hit whitespace / the end of a word.
+ int chars = MAX(0, (j - (characters - 1)) - (is_whitespace ? 1 : 0)) + 1;
+ int char_x_ofs = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * chars)) + tabs;
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(char_x_ofs, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), previous_color);
+ }
+
+ if (out_of_bounds) {
+ break;
+ }
+
+ // re-adjust if we went backwards.
+ if (color != previous_color && !is_whitespace) {
+ characters++;
+ }
+
+ if (str[j] == '\t') {
+ tabs += minimap_tab_size;
+ }
+
+ previous_color = color;
+ characters = 0;
+ }
+ }
+ }
+ }
+
+ // draw main text
+ int line = first_visible_line;
for (int i = 0; i < draw_amount; i++) {
line++;
@@ -875,7 +1087,7 @@ void TextEdit::_notification(int p_what) {
if (syntax_coloring) {
color_map = _get_line_syntax_highlighting(line);
}
- // ensure we at least use the font color
+ // Ensure we at least use the font color.
Color current_color = readonly ? cache.font_color_readonly : cache.font_color;
bool underlined = false;
@@ -916,7 +1128,7 @@ void TextEdit::_notification(int p_what) {
if (smooth_scroll_enabled)
ofs_y += (-get_v_scroll_offset()) * get_row_height();
- // check if line contains highlighted word
+ // Check if line contains highlighted word.
int highlighted_text_col = -1;
int search_text_col = -1;
int highlighted_word_col = -1;
@@ -938,25 +1150,25 @@ void TextEdit::_notification(int p_what) {
}
if (str.length() == 0) {
- // draw line background if empty as we won't loop at at all
+ // Draw line background if empty as we won't loop at at all.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, get_row_height()), cache.current_line_color);
}
- // give visual indication of empty selected line
+ // Give visual indication of empty selected line.
if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) {
int char_w = cache.font->get_char_size(' ').width;
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, char_w, get_row_height()), cache.selection_color);
}
} else {
- // if it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
+ // If it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_beg, get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_beg + ofs_x, get_row_height()), cache.current_line_color);
}
}
if (line_wrap_index == 0) {
- // only do these if we are on the first wrapped part of a line
+ // Only do these if we are on the first wrapped part of a line.
if (text.is_breakpoint(line) && !draw_breakpoint_gutter) {
#ifdef TOOLS_ENABLED
@@ -966,7 +1178,7 @@ void TextEdit::_notification(int p_what) {
#endif
}
- // draw bookmark marker
+ // Draw bookmark marker.
if (text.is_bookmark(line)) {
if (draw_bookmark_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
@@ -976,26 +1188,26 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw breakpoint marker
+ // Draw breakpoint marker.
if (text.is_breakpoint(line)) {
if (draw_breakpoint_gutter) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
int marker_height = get_row_height() - (vertical_gap * 2);
int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2);
- // no transparency on marker
+ // No transparency on marker.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2, ofs_y + vertical_gap, marker_width, marker_height), Color(cache.breakpoint_color.r, cache.breakpoint_color.g, cache.breakpoint_color.b));
}
}
- // draw info icons
+ // Draw info icons.
if (draw_info_gutter && text.has_info_icon(line)) {
int vertical_gap = (get_row_height() * 40) / 100;
int horizontal_gap = (cache.info_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width;
Ref<Texture> info_icon = text.get_info_icon(line);
- // ensure the icon fits the gutter size
+ // Ensure the icon fits the gutter size.
Size2i icon_size = info_icon->get_size();
if (icon_size.width > cache.info_gutter_width - horizontal_gap) {
icon_size.width = cache.info_gutter_width - horizontal_gap;
@@ -1013,7 +1225,7 @@ void TextEdit::_notification(int p_what) {
draw_texture_rect(info_icon, Rect2(icon_pos, icon_size));
}
- // draw execution marker
+ // Draw execution marker.
if (executing_line == line) {
if (draw_breakpoint_gutter) {
int icon_extra_size = 4;
@@ -1031,7 +1243,7 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw fold markers
+ // Draw fold markers.
if (draw_fold_gutter) {
int horizontal_gap = (cache.fold_gutter_width * 30) / 100;
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + cache.line_number_w + cache.info_gutter_width;
@@ -1046,7 +1258,7 @@ void TextEdit::_notification(int p_what) {
}
}
- // draw line numbers
+ // Draw line numbers.
if (cache.line_number_w) {
int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
String fc = String::num(line + 1);
@@ -1058,32 +1270,35 @@ void TextEdit::_notification(int p_what) {
}
}
- //loop through characters in one line
+ // Loop through characters in one line.
for (int j = 0; j < str.length(); j++) {
if (syntax_coloring) {
if (color_map.has(last_wrap_column + j)) {
- current_color = readonly ? cache.font_color_readonly : color_map[last_wrap_column + j].color;
+ current_color = color_map[last_wrap_column + j].color;
+ if (readonly && current_color.a > cache.font_color_readonly.a) {
+ current_color.a = cache.font_color_readonly.a;
+ }
}
color = current_color;
}
int char_w;
- //handle tabulator
+ // Handle tabulator.
char_w = text.get_char_width(str[j], str[j + 1], char_ofs);
if ((char_ofs + char_margin) < xmargin_beg) {
char_ofs += char_w;
- // line highlighting handle horizontal clipping
+ // Line highlighting handle horizontal clipping.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
if (j == str.length() - 1) {
- // end of line when last char is skipped
+ // End of line when last char is skipped.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
} else if ((char_ofs + char_margin) > xmargin_beg) {
- // char next to margin is skipped
+ // Char next to margin is skipped.
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, (char_ofs + char_margin) - (xmargin_beg + ofs_x), get_row_height()), cache.current_line_color);
}
}
@@ -1097,7 +1312,7 @@ void TextEdit::_notification(int p_what) {
bool in_search_result = false;
if (search_text_col != -1) {
- // if we are at the end check for new search result on same line
+ // If we are at the end check for new search result on same line.
if (j >= search_text_col + search_text.length())
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, j);
@@ -1108,19 +1323,19 @@ void TextEdit::_notification(int p_what) {
}
}
- //current line highlighting
+ // Current line highlighting.
bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || last_wrap_column + j >= selection.from_column) && (line < selection.to_line || last_wrap_column + j < selection.to_column));
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
- // draw the wrap indent offset highlight
+ // Draw the wrap indent offset highlight.
if (line_wrap_index != 0 && j == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin - indent_px, ofs_y, indent_px, get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + ofs_x - indent_px, ofs_y, indent_px, get_row_height()), cache.current_line_color);
}
- // if its the last char draw to end of the line
+ // If its the last char draw to end of the line.
if (j == str.length() - 1) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w + ofs_x, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
}
- // actual text
+ // Actual text.
if (!in_selection) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(char_w, get_row_height())), cache.current_line_color);
}
@@ -1145,14 +1360,14 @@ void TextEdit::_notification(int p_what) {
if (highlight_all_occurrences && !only_whitespaces_highlighted) {
if (highlighted_text_col != -1) {
- // if we are at the end check for new word on same line
+ // If we are at the end check for new word on same line.
if (j > highlighted_text_col + highlighted_text.length()) {
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, j);
}
bool in_highlighted_word = (j >= highlighted_text_col && j < highlighted_text_col + highlighted_text.length());
- // if this is the original highlighted text we don't want to highlight it again
+ // If this is the original highlighted text we don't want to highlight it again.
if (cursor.line == line && cursor_wrap_index == line_wrap_index && (cursor.column >= highlighted_text_col && cursor.column <= highlighted_text_col + highlighted_text.length())) {
in_highlighted_word = false;
}
@@ -1349,7 +1564,7 @@ void TextEdit::_notification(int p_what) {
bool completion_below = false;
if (completion_active) {
- // code completion box
+ // Code completion box.
Ref<StyleBox> csb = get_stylebox("completion");
int maxlines = get_constant("completion_lines");
int cmax_width = get_constant("completion_max_width") * cache.font->get_char_size('x').x;
@@ -1371,7 +1586,7 @@ void TextEdit::_notification(int p_what) {
w = cmax_width;
}
- // Add space for completion icons
+ // 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;
@@ -1403,7 +1618,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 + Vector2(icon_area_size.x + icon_hsep, 0), 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(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color);
for (int i = 0; i < lines; i++) {
@@ -1418,7 +1633,7 @@ void TextEdit::_notification(int p_what) {
int yofs = (get_row_height() - cache.font->get_height()) / 2;
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
+ // 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()) {
@@ -1430,11 +1645,11 @@ void TextEdit::_notification(int p_what) {
}
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);
+ draw_string(cache.font, title_pos, completion_options[l].display, text_color, completion_rect.size.width - (icon_area_size.x + icon_hsep));
}
if (scrollw) {
- //draw a small scroll rectangle to show a position in the options
+ // Draw a small scroll rectangle to show a position in the options.
float r = maxlines / (float)completion_options.size();
float o = line_from / (float)completion_options.size();
draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc);
@@ -1443,7 +1658,7 @@ void TextEdit::_notification(int p_what) {
completion_line_ofs = line_from;
}
- // check to see if the hint should be drawn
+ // Check to see if the hint should be drawn.
bool show_hint = false;
if (completion_hint != "") {
if (completion_active) {
@@ -1520,11 +1735,12 @@ void TextEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_active(true);
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
}
-
} break;
case NOTIFICATION_FOCUS_ENTER: {
- if (!caret_blink_enabled) {
+ if (caret_blink_enabled) {
+ caret_blink_timer->start();
+ } else {
draw_caret = true;
}
@@ -1537,6 +1753,10 @@ void TextEdit::_notification(int p_what) {
} break;
case NOTIFICATION_FOCUS_EXIT: {
+ if (caret_blink_enabled) {
+ caret_blink_timer->stop();
+ }
+
OS::get_singleton()->set_ime_position(Point2());
OS::get_singleton()->set_ime_active(false);
ime_text = "";
@@ -1662,9 +1882,9 @@ void TextEdit::backspace_at_cursor() {
_is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
_consume_backspace_for_pair_symbol(prev_line, prev_column);
} else {
- // handle space indentation
+ // Handle space indentation.
if (cursor.column != 0 && indent_using_spaces) {
- // check if there are no other chars before cursor, just indentation
+ // Check if there are no other chars before cursor, just indentation.
bool unindent = true;
int i = 0;
while (i < cursor.column && i < text[cursor.line].length()) {
@@ -1675,10 +1895,9 @@ void TextEdit::backspace_at_cursor() {
i++;
}
- // then we can remove all spaces as a single character.
+ // Then we can remove all spaces as a single character.
if (unindent) {
- // we want to remove spaces up to closest indent
- // or whole indent if cursor is pointing at it
+ // We want to remove spaces up to closest indent, or whole indent if cursor is pointing at it.
int spaces_to_delete = _calculate_spaces_till_next_left_indent(cursor.column);
prev_column = cursor.column - spaces_to_delete;
_remove_text(cursor.line, prev_column, cursor.line, cursor.column);
@@ -1699,8 +1918,8 @@ void TextEdit::indent_right() {
int start_line;
int end_line;
- // this value informs us by how much we changed selection position by indenting right
- // default is 1 for tab indentation
+ // This value informs us by how much we changed selection position by indenting right.
+ // Default is 1 for tab indentation.
int selection_offset = 1;
begin_complex_operation();
@@ -1712,7 +1931,7 @@ void TextEdit::indent_right() {
end_line = start_line;
}
- // ignore if the cursor is not past the first column
+ // Ignore if the cursor is not past the first column.
if (is_selection_active() && get_selection_to_column() == 0) {
end_line--;
}
@@ -1720,10 +1939,10 @@ void TextEdit::indent_right() {
for (int i = start_line; i <= end_line; i++) {
String line_text = get_line(i);
if (indent_using_spaces) {
- // we don't really care where selection is - we just need to know indentation level at the beginning of the line
+ // We don't really care where selection is - we just need to know indentation level at the beginning of the line.
int left = _find_first_non_whitespace_column_of_line(line_text);
int spaces_to_add = _calculate_spaces_till_next_right_indent(left);
- // since we will add this much spaces we want move whole selection and cursor by this much
+ // Since we will add this much spaces we want move whole selection and cursor by this much.
selection_offset = spaces_to_add;
for (int j = 0; j < spaces_to_add; j++)
line_text = ' ' + line_text;
@@ -1733,7 +1952,7 @@ void TextEdit::indent_right() {
set_line(i, line_text);
}
- // fix selection and cursor being off after shifting selection right
+ // Fix selection and cursor being off after shifting selection right.
if (is_selection_active()) {
select(selection.from_line, selection.from_column + selection_offset, selection.to_line, selection.to_column + selection_offset);
}
@@ -1747,10 +1966,9 @@ void TextEdit::indent_left() {
int start_line;
int end_line;
- // moving cursor and selection after unindenting can get tricky
- // because changing content of line can move cursor and selection on it's own (if new line ends before previous position of either)
- // therefore we just remember initial values
- // and at the end of the operation offset them by number of removed characters
+ // Moving cursor and selection after unindenting can get tricky because
+ // changing content of line can move cursor and selection on it's own (if new line ends before previous position of either),
+ // therefore we just remember initial values and at the end of the operation offset them by number of removed characters.
int removed_characters = 0;
int initial_selection_end_column = selection.to_column;
int initial_cursor_column = cursor.column;
@@ -1765,7 +1983,7 @@ void TextEdit::indent_left() {
end_line = start_line;
}
- // ignore if the cursor is not past the first column
+ // Ignore if the cursor is not past the first column.
if (is_selection_active() && get_selection_to_column() == 0) {
end_line--;
}
@@ -1779,12 +1997,12 @@ void TextEdit::indent_left() {
set_line(i, line_text);
removed_characters = 1;
} else if (line_text.begins_with(" ")) {
- // when unindenting we aim to remove spaces before line that has selection no matter what is selected
+ // When unindenting we aim to remove spaces before line that has selection no matter what is selected,
// so we start of by finding first non whitespace character of line
int left = _find_first_non_whitespace_column_of_line(line_text);
- // here we remove only enough spaces to align text to nearest full multiple of indentation_size
- // in case where selection begins at the start of indentation_size multiple we remove whole indentation level
+ // Here we remove only enough spaces to align text to nearest full multiple of indentation_size.
+ // In case where selection begins at the start of indentation_size multiple we remove whole indentation level.
int spaces_to_remove = _calculate_spaces_till_next_left_indent(left);
line_text = line_text.substr(spaces_to_remove, line_text.length());
@@ -1793,7 +2011,7 @@ void TextEdit::indent_left() {
}
}
- // fix selection and cursor being off by one on the last line
+ // Fix selection and cursor being off by one on the last line.
if (is_selection_active() && last_line_text != get_line(end_line)) {
select(selection.from_line, selection.from_column - removed_characters,
selection.to_line, initial_selection_end_column - removed_characters);
@@ -1834,7 +2052,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
}
if (row < 0)
- row = 0; //todo
+ row = 0; // TODO.
int col = 0;
@@ -1848,7 +2066,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
colx += cursor.x_ofs;
col = get_char_pos_for_line(colx, row, wrap_index);
if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) {
- // move back one if we are at the end of the row
+ // Move back one if we are at the end of the row.
Vector<String> rows2 = get_wrap_rows_text(row);
int row_end_col = 0;
for (int i = 0; i < wrap_index + 1; i++) {
@@ -1863,6 +2081,99 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
r_col = col;
}
+Vector2i TextEdit::_get_cursor_pixel_pos() {
+ adjust_viewport_to_cursor();
+ int row = (cursor.line - get_first_visible_line() - cursor.wrap_ofs);
+ // Correct for hidden and wrapped lines
+ for (int i = get_first_visible_line(); i < cursor.line; i++) {
+ if (is_line_hidden(i)) {
+ row -= 1;
+ continue;
+ }
+ row += times_line_wraps(i);
+ }
+ // Row might be wrapped. Adjust row and r_column
+ Vector<String> rows2 = get_wrap_rows_text(cursor.line);
+ while (rows2.size() > 1) {
+ if (cursor.column >= rows2[0].length()) {
+ cursor.column -= rows2[0].length();
+ rows2.remove(0);
+ row++;
+ } else {
+ break;
+ }
+ }
+
+ // Calculate final pixel position
+ int y = (row - get_v_scroll_offset() + 1 /*Bottom of line*/) * get_row_height();
+ int x = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
+ int ix = 0;
+ while (ix < rows2[0].size() && ix < cursor.column) {
+ if (cache.font != NULL) {
+ x += cache.font->get_char_size(rows2[0].get(ix)).width;
+ }
+ ix++;
+ }
+ x += get_indent_level(cursor.line) * cache.font->get_char_size(' ').width;
+
+ return Vector2i(x, y);
+}
+
+void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const {
+
+ float rows = p_mouse.y;
+ rows -= cache.style_normal->get_margin(MARGIN_TOP);
+ rows /= (minimap_char_size.y + minimap_line_spacing);
+ rows += get_v_scroll_offset();
+
+ // calculate visible lines
+ int minimap_visible_lines = _get_minimap_visible_rows();
+ int visible_rows = get_visible_rows() + 1;
+ int first_visible_line = get_first_visible_line() - 1;
+ int draw_amount = visible_rows + (smooth_scroll_enabled ? 1 : 0);
+ draw_amount += times_line_wraps(first_visible_line + 1);
+ int minimap_line_height = (minimap_char_size.y + minimap_line_spacing);
+
+ // calculate viewport size and y offset
+ int viewport_height = (draw_amount - 1) * minimap_line_height;
+ int control_height = _get_control_height() - viewport_height;
+ int viewport_offset_y = round(get_scroll_pos_for_line(first_visible_line) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
+
+ // calculate the first line.
+ int num_lines_before = round((viewport_offset_y) / minimap_line_height);
+ int wi;
+ int minimap_line = (v_scroll->get_max() <= minimap_visible_lines) ? -1 : first_visible_line;
+ if (first_visible_line > 0 && minimap_line >= 0) {
+ minimap_line -= num_lines_from_rows(first_visible_line, 0, -num_lines_before, wi);
+ minimap_line -= (smooth_scroll_enabled ? 1 : 0);
+ } else {
+ minimap_line = 0;
+ }
+
+ int row = minimap_line + Math::floor(rows);
+ int wrap_index = 0;
+
+ if (is_wrap_enabled() || is_hiding_enabled()) {
+
+ int f_ofs = num_lines_from_rows(minimap_line, cursor.wrap_ofs, rows + (1 * SGN(rows)), wrap_index) - 1;
+ if (rows < 0) {
+ row = minimap_line - f_ofs;
+ } else {
+ row = minimap_line + f_ofs;
+ }
+ }
+
+ if (row < 0) {
+ row = 0;
+ }
+
+ if (row >= text.size()) {
+ row = text.size() - 1;
+ }
+
+ r_row = row;
+}
+
void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
double prev_v_scroll = v_scroll->get_value();
@@ -1936,13 +2247,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int row, col;
_get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col);
- if (mb->get_command() && highlighted_word != String()) {
-
- emit_signal("symbol_lookup", highlighted_word, row, col);
- return;
- }
-
- // toggle breakpoint on gutter click
+ // Toggle breakpoint on gutter click.
if (draw_breakpoint_gutter) {
int gutter = cache.style_normal->get_margin(MARGIN_LEFT);
if (mb->get_position().x > gutter - 6 && mb->get_position().x <= gutter + cache.breakpoint_gutter_width - 3) {
@@ -1952,7 +2257,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // emit info clicked
+ // Emit info clicked.
if (draw_info_gutter && text.has_info_icon(row)) {
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
int gutter_left = left_margin + cache.breakpoint_gutter_width;
@@ -1962,7 +2267,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // toggle fold on gutter click if can
+ // Toggle fold on gutter click if can.
if (draw_fold_gutter) {
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
@@ -1977,7 +2282,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- // unfold on folded icon click
+ // Unfold on folded icon click.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.info_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
@@ -1987,6 +2292,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
+ // minimap
+ if (draw_minimap) {
+ _update_minimap_click();
+ if (dragging_minimap) {
+ return;
+ }
+ }
+
int prev_col = cursor.column;
int prev_line = cursor.line;
@@ -2044,9 +2357,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
- //if sel active and dblick last time < something
-
- //else
selection.active = false;
selection.selecting_mode = Selection::MODE_POINTER;
selection.selecting_line = row;
@@ -2054,14 +2364,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
- //tripleclick select line
+
+ // Triple-click select line.
selection.selecting_mode = Selection::MODE_LINE;
_update_selection_mode_line();
last_dblclk = 0;
-
} else if (mb->is_doubleclick() && text[cursor.line].length()) {
- //doubleclick select word
+ // Double-click select word.
selection.selecting_mode = Selection::MODE_WORD;
_update_selection_mode_word();
last_dblclk = OS::get_singleton()->get_ticks_msec();
@@ -2086,7 +2396,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int to_column = get_selection_to_column();
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
+ // Right click is outside the selected text.
deselect();
}
}
@@ -2104,10 +2414,22 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
- if (mb->get_button_index() == BUTTON_LEFT)
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->get_command() && highlighted_word != String()) {
+ int row, col;
+ _get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col);
+
+ emit_signal("symbol_lookup", highlighted_word, row, col);
+ return;
+ }
+
+ dragging_minimap = false;
+ dragging_selection = false;
+ can_drag_minimap = false;
click_select_held->stop();
+ }
- // notify to show soft keyboard
+ // Notify to show soft keyboard.
notification(NOTIFICATION_FOCUS_ENTER);
}
}
@@ -2123,7 +2445,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
h_scroll->set_value(h_scroll->get_value() + pan_gesture->get_delta().x * 100);
if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
- accept_event(); //accept event if scroll changed
+ accept_event(); // Accept event if scroll changed.
return;
}
@@ -2133,7 +2455,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (mm.is_valid()) {
if (select_identifiers_enabled) {
- if (mm->get_command() && mm->get_button_mask() == 0) {
+ if (!dragging_minimap && !dragging_selection && mm->get_command() && mm->get_button_mask() == 0) {
String new_word = get_word_at_pos(mm->get_position());
if (new_word != highlighted_word) {
@@ -2148,34 +2470,40 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging
+ if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { // Ignore if dragging.
_reset_caret_blink_timer();
- switch (selection.selecting_mode) {
- case Selection::MODE_POINTER: {
- _update_selection_mode_pointer();
- } break;
- case Selection::MODE_WORD: {
- _update_selection_mode_word();
- } break;
- case Selection::MODE_LINE: {
- _update_selection_mode_line();
- } break;
- default: {
- break;
+ if (draw_minimap && !dragging_selection) {
+ _update_minimap_drag();
+ }
+
+ if (!dragging_minimap) {
+ switch (selection.selecting_mode) {
+ case Selection::MODE_POINTER: {
+ _update_selection_mode_pointer();
+ } break;
+ case Selection::MODE_WORD: {
+ _update_selection_mode_word();
+ } break;
+ case Selection::MODE_LINE: {
+ _update_selection_mode_line();
+ } break;
+ default: {
+ break;
+ }
}
}
}
}
if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
- accept_event(); //accept event if scroll changed
+ accept_event(); // Accept event if scroll changed.
Ref<InputEventKey> k = p_gui_input;
if (k.is_valid()) {
- k = k->duplicate(); //it will be modified later on
+ k = k->duplicate(); // It will be modified later on.
#ifdef OSX_ENABLED
if (k->get_scancode() == KEY_META) {
@@ -2185,7 +2513,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
#endif
if (select_identifiers_enabled) {
- if (k->is_pressed()) {
+ if (k->is_pressed() && !dragging_minimap && !dragging_selection) {
highlighted_word = get_word_at_pos(get_local_mouse_position());
update();
@@ -2311,11 +2639,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_consume_pair_symbol(chr[0]);
} else {
- // remove the old character if in insert mode
+ // Remove the old character if in insert mode.
if (insert_mode) {
begin_complex_operation();
- // make sure we don't try and remove empty space
+ // Make sure we don't try and remove empty space.
if (cursor.column < get_line(cursor.line).length()) {
_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
@@ -2337,9 +2665,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_cancel_completion();
}
- /* TEST CONTROL FIRST!! */
+ /* TEST CONTROL FIRST! */
- // some remaps for duplicate functions..
+ // Some remaps for duplicate functions.
if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) {
k->set_scancode(KEY_C);
@@ -2383,10 +2711,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_reset_caret_blink_timer();
- // save here for insert mode, just in case it is cleared in the following section
+ // Save here for insert mode, just in case it is cleared in the following section.
bool had_selection = selection.active;
- // stuff to do when selection is active..
+ // Stuff to do when selection is active.
if (!readonly && selection.active) {
bool clear = false;
@@ -2406,7 +2734,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_X:
case KEY_C:
- //special keys often used with control, wait...
+ // Special keys often used with control, wait.
clear = (!k->get_command() || k->get_shift() || k->get_alt());
break;
case KEY_DELETE:
@@ -2431,7 +2759,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
case KEY_PAGEDOWN:
case KEY_HOME:
case KEY_END:
- // ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys)
+ // Ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys).
if (k->get_command() || k->get_shift() || k->get_alt())
break;
unselect = true;
@@ -2469,7 +2797,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
bool scancode_handled = true;
- // special scancode test...
+ // Special scancode test.
switch (k->get_scancode()) {
@@ -2481,7 +2809,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
String ins = "\n";
- //keep indentation
+ // Keep indentation.
int space_count = 0;
for (int i = 0; i < cursor.column; i++) {
if (text[cursor.line][i] == '\t') {
@@ -2512,10 +2840,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
bool brace_indent = false;
- // no need to indent if we are going upwards.
+ // No need to indent if we are going upwards.
if (auto_indent && !(k->get_command() && k->get_shift())) {
- // indent once again if previous line will end with ':' or '{' and the line is not a comment
- // (i.e. colon/brace precedes current cursor position)
+ // Indent once again if previous line will end with ':' or '{' and the line is not a comment
+ // (i.e. colon/brace precedes current cursor position).
if (cursor.column > 0 && (text[cursor.line][cursor.column - 1] == ':' || text[cursor.line][cursor.column - 1] == '{') && !is_line_comment(cursor.line)) {
if (indent_using_spaces) {
ins += space_indent;
@@ -2523,7 +2851,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
ins += "\t";
}
- // no need to move the brace below if we are not taking the text with us.
+ // No need to move the brace below if we are not taking the text with us.
if (text[cursor.line][cursor.column] == '}' && !k->get_command()) {
brace_indent = true;
ins += "\n" + ins.substr(1, ins.length() - 2);
@@ -2565,7 +2893,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} break;
case KEY_TAB: {
- if (k->get_command()) break; // avoid tab when command
+ if (k->get_command()) break; // Avoid tab when command.
if (readonly)
break;
@@ -2579,7 +2907,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (k->get_shift()) {
- // simple unindent
+ // Simple unindent.
int cc = cursor.column;
const String &line = text[cursor.line];
@@ -2591,17 +2919,17 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (cc > 0 && cc <= text[cursor.line].length()) {
if (text[cursor.line][cc - 1] == '\t') {
- // tabs unindentation
+ // Tabs unindentation.
_remove_text(cursor.line, cc - 1, cursor.line, cc);
if (cursor.column >= left)
cursor_set_column(MAX(0, cursor.column - 1));
update();
} else {
- // spaces unindentation
+ // Spaces unindentation.
int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc);
if (spaces_to_remove > 0) {
_remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc);
- if (cursor.column > left - spaces_to_remove) // inside text?
+ if (cursor.column > left - spaces_to_remove) // Inside text?
cursor_set_column(MAX(0, cursor.column - spaces_to_remove));
update();
}
@@ -2611,9 +2939,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
} else {
- // simple indent
+ // Simple indent.
if (indent_using_spaces) {
- // insert only as much spaces as needed till next indentation level
+ // Insert only as much spaces as needed till next indentation level.
int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column);
String indent_to_insert = String();
for (int i = 0; i < spaces_to_add; i++)
@@ -2641,20 +2969,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int line = cursor.line;
int column = cursor.column;
- // check if we are removing a single whitespace, if so remove it and the next char type
- // else we just remove the whitespace
+ // Check if we are removing a single whitespace, if so remove it and the next char type,
+ // else we just remove the whitespace.
bool only_whitespace = false;
if (_is_whitespace(text[line][column - 1]) && _is_whitespace(text[line][column - 2])) {
only_whitespace = true;
} else if (_is_whitespace(text[line][column - 1])) {
- // remove the single whitespace
+ // Remove the single whitespace.
column--;
}
- // check if its a text char
+ // Check if its a text char.
bool only_char = (_is_text_char(text[line][column - 1]) && !only_whitespace);
- // if its not whitespace or char then symbol.
+ // If its not whitespace or char then symbol.
bool only_symbols = !(only_whitespace || only_char);
while (column > 0) {
@@ -2932,7 +3260,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (readonly)
break;
- if (k->get_shift() && !k->get_command() && !k->get_alt()) {
+ if (k->get_shift() && !k->get_command() && !k->get_alt() && is_shortcut_keys_enabled()) {
cut();
break;
}
@@ -2940,7 +3268,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int curline_len = text[cursor.line].length();
if (cursor.line == text.size() - 1 && cursor.column == curline_len)
- break; //nothing to do
+ break; // Nothing to do.
int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
int next_column;
@@ -2957,20 +3285,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int line = cursor.line;
int column = cursor.column;
- // check if we are removing a single whitespace, if so remove it and the next char type
- // else we just remove the whitespace
+ // Check if we are removing a single whitespace, if so remove it and the next char type,
+ // else we just remove the whitespace.
bool only_whitespace = false;
if (_is_whitespace(text[line][column]) && _is_whitespace(text[line][column + 1])) {
only_whitespace = true;
} else if (_is_whitespace(text[line][column])) {
- // remove the single whitespace
+ // Remove the single whitespace.
column++;
}
- // check if its a text char
+ // Check if its a text char.
bool only_char = (_is_text_char(text[line][column]) && !only_whitespace);
- // if its not whitespace or char then symbol.
+ // If its not whitespace or char then symbol.
bool only_symbols = !(only_whitespace || only_char);
while (column < curline_len) {
@@ -3029,7 +3357,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(0);
} else {
- // move cursor column to start of wrapped row and then to start of text
+ // Move cursor column to start of wrapped row and then to start of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
int wi = get_cursor_wrap_index();
int row_start_col = 0;
@@ -3037,7 +3365,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
row_start_col += rows[i].length();
}
if (cursor.column == row_start_col || wi == 0) {
- // compute whitespace symbols seq length
+ // Compute whitespace symbols seq length.
int current_line_whitespace_len = 0;
while (current_line_whitespace_len < text[cursor.line].length()) {
CharType c = text[cursor.line][current_line_whitespace_len];
@@ -3088,7 +3416,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (k->get_command())
cursor_set_line(get_last_unhidden_line(), true, false, 9999);
- // move cursor column to end of wrapped row and then to end of text
+ // Move cursor column to end of wrapped row and then to end of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
int wi = get_cursor_wrap_index();
int row_end_col = -1;
@@ -3163,13 +3491,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
scancode_handled = false;
break;
}
- select_all();
+ if (is_shortcut_keys_enabled()) {
+ select_all();
+ }
#else
if ((!k->get_command() && !k->get_control())) {
scancode_handled = false;
break;
}
- if (!k->get_shift() && k->get_command())
+ if (!k->get_shift() && k->get_command() && is_shortcut_keys_enabled())
select_all();
else if (k->get_control()) {
if (k->get_shift())
@@ -3225,8 +3555,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
scancode_handled = false;
break;
}
-
- cut();
+ if (is_shortcut_keys_enabled()) {
+ cut();
+ }
} break;
case KEY_C: {
@@ -3236,29 +3567,43 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- copy();
+ if (is_shortcut_keys_enabled()) {
+ copy();
+ }
} break;
case KEY_Z: {
+ if (readonly) {
+ break;
+ }
+
if (!k->get_command()) {
scancode_handled = false;
break;
}
- if (k->get_shift())
- redo();
- else
- undo();
+ if (is_shortcut_keys_enabled()) {
+ if (k->get_shift())
+ redo();
+ else
+ undo();
+ }
} break;
case KEY_Y: {
+ if (readonly) {
+ break;
+ }
+
if (!k->get_command()) {
scancode_handled = false;
break;
}
- redo();
+ if (is_shortcut_keys_enabled()) {
+ redo();
+ }
} break;
case KEY_V: {
if (readonly) {
@@ -3269,12 +3614,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- paste();
+ if (is_shortcut_keys_enabled()) {
+ paste();
+ }
} break;
case KEY_SPACE: {
#ifdef OSX_ENABLED
- if (completion_enabled && k->get_metakey()) { //cmd-space is spotlight shortcut in OSX
+ if (completion_enabled && k->get_metakey()) { // cmd-space is spotlight shortcut in OSX
#else
if (completion_enabled && k->get_command()) {
#endif
@@ -3287,6 +3634,16 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
+ case KEY_MENU: {
+ if (context_menu_enabled) {
+ menu->set_position(get_global_transform().xform(_get_cursor_pixel_pos()));
+ menu->set_size(Vector2(1, 1));
+ menu->set_scale(get_global_transform().get_scale());
+ menu->popup();
+ menu->grab_focus();
+ }
+ } break;
+
default: {
scancode_handled = false;
@@ -3302,18 +3659,18 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
return;
}
- if (!scancode_handled && !k->get_command()) { //for German kbds
+ if (!scancode_handled && !k->get_command()) { // For German keyboards.
if (k->get_unicode() >= 32) {
if (readonly)
return;
- // remove the old character if in insert mode and no selection
+ // Remove the old character if in insert mode and no selection.
if (insert_mode && !had_selection) {
begin_complex_operation();
- // make sure we don't try and remove empty space
+ // Make sure we don't try and remove empty space.
if (cursor.column < get_line(cursor.line).length()) {
_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
@@ -3347,8 +3704,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
void TextEdit::_scroll_up(real_t p_delta) {
- if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta))
+ if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta)) {
scrolling = false;
+ minimap_clicked = false;
+ }
if (scrolling) {
target_v_scroll = (target_v_scroll - p_delta);
@@ -3373,8 +3732,10 @@ void TextEdit::_scroll_up(real_t p_delta) {
void TextEdit::_scroll_down(real_t p_delta) {
- if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(p_delta))
+ if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(p_delta)) {
scrolling = false;
+ minimap_clicked = false;
+ }
if (scrolling) {
target_v_scroll = (target_v_scroll + p_delta);
@@ -3423,11 +3784,12 @@ void TextEdit::_post_shift_selection() {
void TextEdit::_scroll_lines_up() {
scrolling = false;
+ minimap_clicked = false;
- // adjust the vertical scroll
+ // Adjust the vertical scroll.
set_v_scroll(get_v_scroll() - 1);
- // adjust the cursor to viewport
+ // Adjust the cursor to viewport.
if (!selection.active) {
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
@@ -3442,11 +3804,12 @@ void TextEdit::_scroll_lines_up() {
void TextEdit::_scroll_lines_down() {
scrolling = false;
+ minimap_clicked = false;
- // adjust the vertical scroll
+ // Adjust the vertical scroll.
set_v_scroll(get_v_scroll() + 1);
- // adjust the cursor to viewport
+ // Adjust the cursor to viewport.
if (!selection.active) {
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
@@ -3463,15 +3826,15 @@ void TextEdit::_scroll_lines_down() {
void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, int &r_end_line, int &r_end_column) {
- //save for undo...
+ // Save for undo.
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_COND(p_char < 0);
- /* STEP 1 remove \r from source text and separate in substrings */
+ /* STEP 1: Remove \r from source text and separate in substrings. */
Vector<String> substrings = p_text.replace("\r", "").split("\n");
- /* STEP 2 fire breakpoint_toggled signals */
+ /* STEP 2: Fire breakpoint_toggled signals. */
// Is this just a new empty line?
bool shift_first_line = p_char == 0 && p_text.replace("\r", "") == "\n";
@@ -3487,19 +3850,19 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
}
}
- /* STEP 3 add spaces if the char is greater than the end of the line */
+ /* STEP 3: Add spaces if the char is greater than the end of the line. */
while (p_char > text[p_line].length()) {
text.set(p_line, text[p_line] + String::chr(' '));
}
- /* STEP 4 separate dest string in pre and post text */
+ /* STEP 4: Separate dest string in pre and post text. */
String preinsert_text = text[p_line].substr(0, p_char);
String postinsert_text = text[p_line].substr(p_char, text[p_line].size());
for (int j = 0; j < substrings.size(); j++) {
- //insert the substrings
+ // Insert the substrings.
if (j == 0) {
@@ -3544,8 +3907,8 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, String());
ERR_FAIL_INDEX_V(p_to_line, text.size(), String());
ERR_FAIL_INDEX_V(p_to_column, text[p_to_line].length() + 1, String());
- ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // from > to
- ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // from > to
+ ERR_FAIL_COND_V(p_to_line < p_from_line, String()); // 'from > to'.
+ ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column < p_from_column, String()); // 'from > to'.
String ret;
@@ -3568,8 +3931,8 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
ERR_FAIL_INDEX(p_from_column, text[p_from_line].length() + 1);
ERR_FAIL_INDEX(p_to_line, text.size());
ERR_FAIL_INDEX(p_to_column, text[p_to_line].length() + 1);
- ERR_FAIL_COND(p_to_line < p_from_line); // from > to
- ERR_FAIL_COND(p_to_line == p_from_line && p_to_column < p_from_column); // from > to
+ ERR_FAIL_COND(p_to_line < p_from_line); // 'from > to'.
+ ERR_FAIL_COND(p_to_line == p_from_line && p_to_column < p_from_column); // 'from > to'.
String pre_text = text[p_from_line].substr(0, p_from_column);
String post_text = text[p_to_line].substr(p_to_column, text[p_to_line].length());
@@ -3631,22 +3994,22 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
op.chain_forward = false;
op.chain_backward = false;
- //see if it should just be set as current op
+ // See if it should just be set as current op.
if (current_op.type != op.type) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //see if it can be merged
+ // See if it can be merged.
if (current_op.to_line != p_line || current_op.to_column != p_char) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //merge current op
+ // Merge current op.
current_op.text += p_text;
current_op.to_column = retchar;
@@ -3670,7 +4033,7 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
if (!undo_enabled)
return;
- /* UNDO!! */
+ /* UNDO! */
TextOperation op;
op.type = TextOperation::TYPE_REMOVE;
op.from_line = p_from_line;
@@ -3682,27 +4045,20 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
op.chain_forward = false;
op.chain_backward = false;
- //see if it should just be set as current op
+ // See if it should just be set as current op.
if (current_op.type != op.type) {
op.prev_version = get_version();
_push_current_op();
current_op = op;
- return; //set as current op, return
+ return; // Set as current op, return.
}
- //see if it can be merged
+ // See if it can be merged.
if (current_op.from_line == p_to_line && current_op.from_column == p_to_column) {
- //basckace or similar
+ // Backspace or similar.
current_op.text = text + current_op.text;
current_op.from_line = p_from_line;
current_op.from_column = p_from_column;
- return; //update current op
- }
- if (current_op.from_line == p_from_line && current_op.from_column == p_from_column) {
-
- //current_op.text=text+current_op.text;
- //current_op.from_line=p_from_line;
- //current_op.from_column=p_from_column;
- //return; //update current op
+ return; // Update current op.
}
op.prev_version = get_version();
@@ -3725,6 +4081,15 @@ void TextEdit::_line_edited_from(int p_line) {
for (int i = p_line; i < cache_size; i++) {
color_region_cache.erase(i);
}
+
+ if (syntax_highlighting_cache.size() > 0) {
+ cache_size = syntax_highlighting_cache.back()->key();
+ for (int i = p_line - 1; i <= cache_size; i++) {
+ if (syntax_highlighting_cache.has(i)) {
+ syntax_highlighting_cache.erase(i);
+ }
+ }
+ }
}
int TextEdit::get_char_count() {
@@ -3734,11 +4099,11 @@ int TextEdit::get_char_count() {
for (int i = 0; i < text.size(); i++) {
if (i > 0)
- totalsize++; // incliude \n
+ totalsize++; // Include \n.
totalsize += text[i].length();
}
- return totalsize; // omit last \n
+ return totalsize; // Omit last \n.
}
Size2 TextEdit::get_minimum_size() const {
@@ -3746,19 +4111,45 @@ Size2 TextEdit::get_minimum_size() const {
return cache.style_normal->get_minimum_size();
}
+int TextEdit::_get_control_height() const {
+ int control_height = get_size().height;
+ control_height -= cache.style_normal->get_minimum_size().height;
+ if (h_scroll->is_visible_in_tree()) {
+ control_height -= h_scroll->get_size().height;
+ }
+ return control_height;
+}
+
+void TextEdit::_generate_context_menu() {
+ // Reorganize context menu.
+ menu->clear();
+ if (!readonly)
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ if (!readonly)
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_separator();
+ if (is_selecting_enabled())
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ if (!readonly) {
+ menu->add_item(RTR("Clear"), MENU_CLEAR);
+ menu->add_separator();
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ }
+}
+
int TextEdit::get_visible_rows() const {
+ return _get_control_height() / get_row_height();
+}
- int total = get_size().height;
- total -= cache.style_normal->get_minimum_size().height;
- if (h_scroll->is_visible_in_tree())
- total -= h_scroll->get_size().height;
- total /= get_row_height();
- return total;
+int TextEdit::_get_minimap_visible_rows() const {
+ return _get_control_height() / (minimap_char_size.y + minimap_line_spacing);
}
int TextEdit::get_total_visible_rows() const {
- // returns the total amount of rows we need in the editor.
+ // Returns the total amount of rows we need in the editor.
// This skips hidden lines and counts each wrapping of a line.
if (!is_hiding_enabled() && !is_wrap_enabled())
return text.size();
@@ -3775,12 +4166,12 @@ int TextEdit::get_total_visible_rows() const {
void TextEdit::_update_wrap_at() {
- wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - wrap_right_offset;
+ wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width - wrap_right_offset;
update_cursor_wrap_offset();
text.clear_wrap_cache();
for (int i = 0; i < text.size(); i++) {
- // update all values that wrap
+ // Update all values that wrap.
if (!line_wraps(i))
continue;
Vector<String> rows = get_wrap_rows_text(i);
@@ -3790,8 +4181,9 @@ void TextEdit::_update_wrap_at() {
void TextEdit::adjust_viewport_to_cursor() {
- // make sure cursor is visible on the screen
+ // Make sure cursor is visible on the screen.
scrolling = false;
+ minimap_clicked = false;
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
@@ -3802,20 +4194,20 @@ void TextEdit::adjust_viewport_to_cursor() {
int last_vis_wrap = get_last_visible_line_wrap_index();
if (cur_line < first_vis_line || (cur_line == first_vis_line && cur_wrap < first_vis_wrap)) {
- // cursor is above screen
+ // Cursor is above screen.
set_line_as_first_visible(cur_line, cur_wrap);
} else if (cur_line > last_vis_line || (cur_line == last_vis_line && cur_wrap > last_vis_wrap)) {
- // cursor is below screen
+ // Cursor is below screen.
set_line_as_last_visible(cur_line, cur_wrap);
}
- int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width;
+ int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
if (v_scroll->is_visible_in_tree())
visible_width -= v_scroll->get_combined_minimum_size().width;
- visible_width -= 20; // give it a little more space
+ visible_width -= 20; // Give it a little more space.
if (!is_wrap_enabled()) {
- // adjust x offset
+ // Adjust x offset.
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
if (cursor_x > (cursor.x_ofs + visible_width))
@@ -3833,20 +4225,21 @@ void TextEdit::adjust_viewport_to_cursor() {
void TextEdit::center_viewport_to_cursor() {
- // move viewport so the cursor is in the center of the screen
+ // Move viewport so the cursor is in the center of the screen.
scrolling = false;
+ minimap_clicked = false;
if (is_line_hidden(cursor.line))
unfold_line(cursor.line);
set_line_as_center_visible(cursor.line, get_cursor_wrap_index());
- int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width;
+ int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
if (v_scroll->is_visible_in_tree())
visible_width -= v_scroll->get_combined_minimum_size().width;
- visible_width -= 20; // give it a little more space
+ visible_width -= 20; // Give it a little more space.
if (is_wrap_enabled()) {
- // center x offset
+ // Center x offset.
int cursor_x = get_column_x_offset_for_line(cursor.column, cursor.line);
if (cursor_x > (cursor.x_ofs + visible_width))
@@ -3888,7 +4281,7 @@ int TextEdit::times_line_wraps(int line) const {
int wrap_amount = text.get_line_wrap_amount(line);
if (wrap_amount == -1) {
- // update the value
+ // Update the value.
Vector<String> rows = get_wrap_rows_text(line);
wrap_amount = rows.size() - 1;
text.set_line_wrap_amount(line, wrap_amount);
@@ -3928,7 +4321,7 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
int indent_ofs = (cur_wrap_index != 0 ? tab_offset_px : 0);
if (indent_ofs + word_px + w > wrap_at) {
- // not enough space to add this char; start next line
+ // Not enough space to add this char; start next line.
wrap_substring += word_str;
lines.push_back(wrap_substring);
cur_wrap_index++;
@@ -3942,7 +4335,7 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
word_str += c;
word_px += w;
if (c == ' ') {
- // end of a word; add this word to the substring
+ // End of a word; add this word to the substring.
wrap_substring += word_str;
px += word_px;
word_str = "";
@@ -3950,9 +4343,9 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
if (indent_ofs + px + word_px > wrap_at) {
- // this word will be moved to the next line
+ // This word will be moved to the next line.
lines.push_back(wrap_substring);
- // reset for next wrap
+ // Reset for next wrap.
cur_wrap_index++;
wrap_substring = "";
px = 0;
@@ -3960,11 +4353,11 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
col++;
}
- // line ends before hit wrap_at; add this word to the substring
+ // Line ends before hit wrap_at; add this word to the substring.
wrap_substring += word_str;
lines.push_back(wrap_substring);
- // update cache
+ // Update cache.
text.set_line_wrap_amount(p_line, lines.size() - 1);
return lines;
@@ -3982,7 +4375,7 @@ int TextEdit::get_line_wrap_index_at_col(int p_line, int p_column) const {
if (!line_wraps(p_line))
return 0;
- // loop through wraps in the line text until we get to the column
+ // Loop through wraps in the line text until we get to the column.
int wrap_index = 0;
int col = 0;
Vector<String> rows = get_wrap_rows_text(p_line);
@@ -4087,11 +4480,14 @@ bool TextEdit::cursor_get_blink_enabled() const {
void TextEdit::cursor_set_blink_enabled(const bool p_enabled) {
caret_blink_enabled = p_enabled;
- if (p_enabled) {
- caret_blink_timer->start();
- } else {
- caret_blink_timer->stop();
+ if (has_focus()) {
+ if (p_enabled) {
+ caret_blink_timer->start();
+ } else {
+ caret_blink_timer->stop();
+ }
}
+
draw_caret = true;
}
@@ -4123,6 +4519,7 @@ bool TextEdit::is_right_click_moving_caret() const {
void TextEdit::_v_scroll_input() {
scrolling = false;
+ minimap_clicked = false;
}
void TextEdit::_scroll_moved(double p_to_val) {
@@ -4134,7 +4531,7 @@ void TextEdit::_scroll_moved(double p_to_val) {
cursor.x_ofs = h_scroll->get_value();
if (v_scroll->is_visible_in_tree()) {
- // set line ofs and wrap ofs
+ // Set line ofs and wrap ofs.
int v_scroll_i = floor(get_v_scroll());
int sc = 0;
int n_line;
@@ -4289,12 +4686,12 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
_get_mouse_pos(p_pos, row, col);
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
- // breakpoint icon
+ // Breakpoint icon.
if (draw_breakpoint_gutter && p_pos.x > left_margin - 6 && p_pos.x <= left_margin + cache.breakpoint_gutter_width - 3) {
return CURSOR_POINTING_HAND;
}
- // info icons
+ // Info icons.
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.info_gutter_width;
if (draw_info_gutter && p_pos.x > left_margin + cache.breakpoint_gutter_width - 6 && p_pos.x <= gutter_left - 3) {
if (text.has_info_icon(row)) {
@@ -4303,7 +4700,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
}
- // fold icon
+ // Fold icon.
if (draw_fold_gutter && p_pos.x > gutter_left + cache.line_number_w - 6 && p_pos.x <= gutter_left + cache.line_number_w + cache.fold_gutter_width - 3) {
if (is_folded(row) || can_fold(row))
return CURSOR_POINTING_HAND;
@@ -4313,9 +4710,14 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
} else {
+ int xmargin_end = get_size().width - cache.style_normal->get_margin(MARGIN_RIGHT);
+ if (draw_minimap && p_pos.x > xmargin_end - minimap_width && p_pos.x <= xmargin_end) {
+ return CURSOR_ARROW;
+ }
+
int row, col;
_get_mouse_pos(p_pos, row, col);
- // eol fold icon
+ // EOL fold icon.
if (is_folded(row)) {
int line_width = text.get_line_width(row);
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width - cursor.x_ofs;
@@ -4349,8 +4751,6 @@ void TextEdit::set_text(String p_text) {
update();
setting_text = false;
-
- //get_range()->set(0);
};
String TextEdit::get_text() {
@@ -4377,7 +4777,7 @@ String TextEdit::get_text_for_lookup_completion() {
if (i == row) {
longthing += text[i].substr(0, col);
- longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(col, text[i].size());
} else {
@@ -4399,7 +4799,7 @@ String TextEdit::get_text_for_completion() {
if (i == cursor.line) {
longthing += text[i].substr(0, cursor.column);
- longthing += String::chr(0xFFFF); //not unicode, represents the cursor
+ longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(cursor.column, text[i].size());
} else {
@@ -4447,21 +4847,32 @@ void TextEdit::set_readonly(bool p_readonly) {
return;
readonly = p_readonly;
+ _generate_context_menu();
// Reorganize context menu.
menu->clear();
- if (!readonly)
+
+ if (!readonly) {
+ menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
+ }
+
+ if (!readonly) {
+ menu->add_separator();
menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
+ }
+
menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
- if (!readonly)
+
+ if (!readonly) {
menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
+ }
+
menu->add_separator();
menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
+
if (!readonly) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
- menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
}
update();
@@ -4494,10 +4905,12 @@ int TextEdit::get_max_chars() const {
void TextEdit::_reset_caret_blink_timer() {
if (caret_blink_enabled) {
- caret_blink_timer->stop();
- caret_blink_timer->start();
draw_caret = true;
- update();
+ if (has_focus()) {
+ caret_blink_timer->stop();
+ caret_blink_timer->start();
+ update();
+ }
}
}
@@ -4572,17 +4985,18 @@ void TextEdit::_set_syntax_highlighting(SyntaxHighlighter *p_syntax_highlighter)
syntax_highlighter->set_text_editor(this);
syntax_highlighter->_update_cache();
}
+ syntax_highlighting_cache.clear();
update();
}
int TextEdit::_is_line_in_region(int p_line) {
- // do we have in cache?
+ // Do we have in cache?
if (color_region_cache.has(p_line)) {
return color_region_cache[p_line];
}
- // if not find the closest line we have
+ // If not find the closest line we have.
int previous_line = p_line - 1;
for (; previous_line > -1; previous_line--) {
if (color_region_cache.has(p_line)) {
@@ -4590,7 +5004,7 @@ int TextEdit::_is_line_in_region(int p_line) {
}
}
- // calculate up to line we need and update the cache along the way.
+ // Calculate up to line we need and update the cache along the way.
int in_region = color_region_cache[previous_line];
if (previous_line == -1) {
in_region = -1;
@@ -4638,6 +5052,7 @@ void TextEdit::clear_colors() {
keywords.clear();
color_regions.clear();
color_region_cache.clear();
+ syntax_highlighting_cache.clear();
text.clear_width_cache();
}
@@ -4718,7 +5133,7 @@ void TextEdit::cut() {
OS::get_singleton()->set_clipboard(clipboard);
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line); // set afterwards else it causes the view to be offset
+ cursor_set_line(selection.from_line); // Set afterwards else it causes the view to be offset.
cursor_set_column(selection.from_column);
selection.active = false;
@@ -4772,6 +5187,8 @@ void TextEdit::paste() {
}
void TextEdit::select_all() {
+ if (!selecting_enabled)
+ return;
if (text.size() == 1 && text[0].length() == 0)
return;
@@ -4796,6 +5213,8 @@ void TextEdit::deselect() {
}
void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
+ if (!selecting_enabled)
+ return;
if (p_from_line < 0)
p_from_line = 0;
@@ -4947,7 +5366,7 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
col = p_search.findn(p_key, p_from_column);
}
- // whole words only
+ // Whole words only.
if (col != -1 && p_search_flags & SEARCH_WHOLE_WORDS) {
p_from_column = col;
@@ -4987,14 +5406,12 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
ERR_FAIL_INDEX_V(p_from_line, text.size(), false);
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, false);
- //search through the whole document, but start by current line
+ // Search through the whole document, but start by current line.
int line = p_from_line;
int pos = -1;
for (int i = 0; i < text.size() + 1; i++) {
- //backwards is broken...
- //int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
if (line < 0) {
line = text.size() - 1;
@@ -5008,7 +5425,7 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
if (line == p_from_line) {
if (i == text.size()) {
- //wrapped
+ // Wrapped.
if (p_search_flags & SEARCH_BACKWARDS) {
from_column = text_line.length();
@@ -5042,6 +5459,9 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
break;
}
pos_from = last_pos - p_key.length();
+ if (pos_from < 0) {
+ break;
+ }
}
} else {
while ((last_pos = (p_search_flags & SEARCH_MATCH_CASE) ? text_line.find(p_key, pos_from) : text_line.findn(p_key, pos_from)) != -1) {
@@ -5056,7 +5476,7 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
bool is_match = true;
if (pos != -1 && (p_search_flags & SEARCH_WHOLE_WORDS)) {
- //validate for whole words
+ // Validate for whole words.
if (pos > 0 && _is_text_char(text_line[pos - 1]))
is_match = false;
else if (pos + p_key.length() < text_line.length() && _is_text_char(text_line[pos + p_key.length()]))
@@ -5254,7 +5674,7 @@ void TextEdit::unhide_all_lines() {
int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
- // returns the number of lines (hidden and unhidden) from p_line_from to (p_line_from + visible_amount of unhidden lines)
+ // Returns the number of lines (hidden and unhidden) from p_line_from to (p_line_from + visible_amount of unhidden lines).
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
if (!is_hiding_enabled())
@@ -5287,8 +5707,8 @@ int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int visible_amount, int &wrap_index) const {
- // returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows)
- // wrap index is set to the wrap index of the last line
+ // Returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows).
+ // Wrap index is set to the wrap index of the last line.
wrap_index = 0;
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
@@ -5334,7 +5754,7 @@ int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int vi
int TextEdit::get_last_unhidden_line() const {
- // returns the last line in the text that is not hidden
+ // Returns the last line in the text that is not hidden.
if (!is_hiding_enabled())
return text.size() - 1;
@@ -5351,7 +5771,7 @@ int TextEdit::get_indent_level(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
- // counts number of tabs and spaces before line starts
+ // Counts number of tabs and spaces before line starts.
int tab_count = 0;
int whitespace_count = 0;
int line_length = text[p_line].size();
@@ -5369,7 +5789,7 @@ int TextEdit::get_indent_level(int p_line) const {
bool TextEdit::is_line_comment(int p_line) const {
- // checks to see if this line is the start of a comment
+ // Checks to see if this line is the start of a comment.
ERR_FAIL_INDEX_V(p_line, text.size(), false);
const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(p_line);
@@ -5449,7 +5869,7 @@ void TextEdit::fold_line(int p_line) {
if (!can_fold(p_line))
return;
- // hide lines below this one
+ // Hide lines below this one.
int start_indent = get_indent_level(p_line);
int last_line = start_indent;
for (int i = p_line + 1; i < text.size(); i++) {
@@ -5467,7 +5887,7 @@ void TextEdit::fold_line(int p_line) {
set_line_as_hidden(i, true);
}
- // fix selection
+ // Fix selection.
if (is_selection_active()) {
if (is_line_hidden(selection.from_line) && is_line_hidden(selection.to_line)) {
deselect();
@@ -5478,7 +5898,7 @@ void TextEdit::fold_line(int p_line) {
}
}
- // reset cursor
+ // Reset cursor.
if (is_line_hidden(cursor.line)) {
cursor_set_line(p_line, false, false);
cursor_set_column(get_line(p_line).length(), false);
@@ -5539,8 +5959,8 @@ void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
int check_line;
int check_column;
_base_insert_text(p_op.from_line, p_op.from_column, p_op.text, check_line, check_column);
- ERR_FAIL_COND(check_line != p_op.to_line); // BUG
- ERR_FAIL_COND(check_column != p_op.to_column); // BUG
+ ERR_FAIL_COND(check_line != p_op.to_line); // BUG.
+ ERR_FAIL_COND(check_column != p_op.to_column); // BUG.
} else {
_base_remove_text(p_op.from_line, p_op.from_column, p_op.to_line, p_op.to_column);
@@ -5550,7 +5970,7 @@ void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
void TextEdit::_clear_redo() {
if (undo_stack_pos == NULL)
- return; //nothing to clear
+ return; // Nothing to clear.
_push_current_op();
@@ -5568,12 +5988,12 @@ void TextEdit::undo() {
if (undo_stack_pos == NULL) {
if (!undo_stack.size())
- return; //nothing to undo
+ return; // Nothing to undo.
undo_stack_pos = undo_stack.back();
} else if (undo_stack_pos == undo_stack.front())
- return; // at the bottom of the undo stack
+ return; // At the bottom of the undo stack.
else
undo_stack_pos = undo_stack_pos->prev();
@@ -5614,7 +6034,7 @@ void TextEdit::redo() {
_push_current_op();
if (undo_stack_pos == NULL)
- return; //nothing to do.
+ return; // Nothing to do.
deselect();
@@ -5668,7 +6088,7 @@ void TextEdit::end_complex_operation() {
void TextEdit::_push_current_op() {
if (current_op.type == TextOperation::TYPE_NONE)
- return; // do nothing
+ return; // Nothing to do.
if (next_operation_is_complex) {
current_op.chain_forward = true;
@@ -5768,7 +6188,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
if (!is_wrap_enabled() && !is_hiding_enabled())
return p_line;
- // count the number of visible lines up to this line
+ // Count the number of visible lines up to this line.
double new_line_scroll_pos = 0;
int to = CLAMP(p_line, 0, text.size() - 1);
for (int i = 0; i < to; i++) {
@@ -5828,10 +6248,7 @@ int TextEdit::get_last_visible_line_wrap_index() const {
double TextEdit::get_visible_rows_offset() const {
- double total = get_size().height;
- total -= cache.style_normal->get_minimum_size().height;
- if (h_scroll->is_visible_in_tree())
- total -= h_scroll->get_size().height;
+ double total = _get_control_height();
total /= (double)get_row_height();
total = total - floor(total);
total = -CLAMP(total, 0.001, 1) + 1;
@@ -5913,7 +6330,7 @@ void TextEdit::_confirm_completion() {
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);
+ _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
if (last_completion_char == '(') {
@@ -5969,7 +6386,7 @@ void TextEdit::_update_completion_candidates() {
String s;
- //look for keywords first
+ // Look for keywords first.
bool inquote = false;
int first_quote = -1;
@@ -5994,7 +6411,7 @@ void TextEdit::_update_completion_candidates() {
bool cancel = false;
if (!inquote && first_quote == cofs - 1) {
- //no completion here
+ // No completion here.
cancel = true;
} else if (inquote && first_quote != -1) {
@@ -6032,11 +6449,12 @@ void TextEdit::_update_completion_candidates() {
bool prev_is_prefix = false;
if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1])))
prev_is_prefix = true;
- if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2]))) //check with one space before prefix, to allow indent
+ // Check with one space before prefix, to allow indent.
+ if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2])))
prev_is_prefix = true;
if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !prev_is_prefix))) {
- //none to complete, cancel
+ // None to complete, cancel.
_cancel_completion();
return;
}
@@ -6086,18 +6504,18 @@ void TextEdit::_update_completion_candidates() {
}
if (completion_options.size() == 0) {
- //no options to complete, cancel
+ // No options to complete, cancel.
_cancel_completion();
return;
}
if (completion_options.size() == 1 && s == completion_options[0].display) {
- // A perfect match, stop completion
+ // A perfect match, stop completion.
_cancel_completion();
return;
}
- // The top of the list is the best match
+ // The top of the list is the best match.
completion_current = completion_options[0];
completion_enabled = true;
}
@@ -6116,10 +6534,30 @@ void TextEdit::query_code_comple() {
c--;
}
- if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1]))))
- emit_signal("request_completion");
- else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) //make it work with a space too, it's good enough
- emit_signal("request_completion");
+ bool ignored = completion_active && !completion_options.empty();
+ if (ignored) {
+ ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_PLAIN_TEXT;
+ const ScriptCodeCompletionOption *previous_option = NULL;
+ for (int i = 0; i < completion_options.size(); i++) {
+ const ScriptCodeCompletionOption &current_option = completion_options[i];
+ if (!previous_option) {
+ previous_option = &current_option;
+ kind = current_option.kind;
+ }
+ if (previous_option->kind != current_option.kind) {
+ ignored = false;
+ break;
+ }
+ }
+ ignored = ignored && (kind == ScriptCodeCompletionOption::KIND_FILE_PATH || kind == ScriptCodeCompletionOption::KIND_NODE_PATH || kind == ScriptCodeCompletionOption::KIND_SIGNAL);
+ }
+
+ if (!ignored) {
+ if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1]))))
+ emit_signal("request_completion");
+ else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) // Make it work with a space too, it's good enough.
+ emit_signal("request_completion");
+ }
}
void TextEdit::set_code_hint(const String &p_hint) {
@@ -6220,9 +6658,21 @@ void TextEdit::set_line(int line, String new_text) {
}
void TextEdit::insert_at(const String &p_text, int at) {
- cursor_set_column(0);
- cursor_set_line(at, false, true);
_insert_text(at, 0, p_text + "\n");
+ if (cursor.line >= at) {
+ // offset cursor when located after inserted line
+ ++cursor.line;
+ }
+ if (is_selection_active()) {
+ if (selection.from_line >= at) {
+ // offset selection when located after inserted line
+ ++selection.from_line;
+ ++selection.to_line;
+ } else if (selection.to_line >= at) {
+ // extend selection that includes inserted line
+ ++selection.to_line;
+ }
+ }
}
void TextEdit::set_show_line_numbers(bool p_show) {
@@ -6314,6 +6764,24 @@ int TextEdit::get_info_gutter_width() const {
return info_gutter_width;
}
+void TextEdit::set_draw_minimap(bool p_draw) {
+ draw_minimap = p_draw;
+ update();
+}
+
+bool TextEdit::is_drawing_minimap() const {
+ return draw_minimap;
+}
+
+void TextEdit::set_minimap_width(int p_minimap_width) {
+ minimap_width = p_minimap_width;
+ update();
+}
+
+int TextEdit::get_minimap_width() const {
+ return minimap_width;
+}
+
void TextEdit::set_hiding_enabled(bool p_enabled) {
if (!p_enabled)
unhide_all_lines();
@@ -6390,6 +6858,29 @@ bool TextEdit::is_context_menu_enabled() {
return context_menu_enabled;
}
+void TextEdit::set_shortcut_keys_enabled(bool p_enabled) {
+ shortcut_keys_enabled = p_enabled;
+
+ _generate_context_menu();
+}
+
+void TextEdit::set_selecting_enabled(bool p_enabled) {
+ selecting_enabled = p_enabled;
+
+ if (!selecting_enabled)
+ deselect();
+
+ _generate_context_menu();
+}
+
+bool TextEdit::is_selecting_enabled() const {
+ return selecting_enabled;
+}
+
+bool TextEdit::is_shortcut_keys_enabled() const {
+ return shortcut_keys_enabled;
+}
+
PopupMenu *TextEdit::get_menu() const {
return menu;
}
@@ -6443,10 +6934,12 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_wrap_enabled", "enable"), &TextEdit::set_wrap_enabled);
ClassDB::bind_method(D_METHOD("is_wrap_enabled"), &TextEdit::is_wrap_enabled);
- // ClassDB::bind_method(D_METHOD("set_max_chars", "amount"), &TextEdit::set_max_chars);
- // ClassDB::bind_method(D_METHOD("get_max_char"), &TextEdit::get_max_chars);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &TextEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &TextEdit::is_context_menu_enabled);
+ ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &TextEdit::set_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &TextEdit::is_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &TextEdit::set_selecting_enabled);
+ ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &TextEdit::is_selecting_enabled);
ClassDB::bind_method(D_METHOD("cut"), &TextEdit::cut);
ClassDB::bind_method(D_METHOD("copy"), &TextEdit::copy);
@@ -6520,6 +7013,11 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_breakpoints"), &TextEdit::get_breakpoints_array);
ClassDB::bind_method(D_METHOD("remove_breakpoints"), &TextEdit::remove_breakpoints);
+ ClassDB::bind_method(D_METHOD("draw_minimap", "draw"), &TextEdit::set_draw_minimap);
+ ClassDB::bind_method(D_METHOD("is_drawing_minimap"), &TextEdit::is_drawing_minimap);
+ ClassDB::bind_method(D_METHOD("set_minimap_width", "width"), &TextEdit::set_minimap_width);
+ ClassDB::bind_method(D_METHOD("get_minimap_width"), &TextEdit::get_minimap_width);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
@@ -6532,11 +7030,16 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled");
- // ADD_PROPERTY(PropertyInfo(Variant::BOOL, "max_chars"), "set_max_chars", "get_max_chars");
+
+ ADD_GROUP("Minimap", "minimap_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_draw"), "draw_minimap", "is_drawing_minimap");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "minimap_width"), "set_minimap_width", "get_minimap_width");
ADD_GROUP("Caret", "caret_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode");
@@ -6561,7 +7064,7 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_MAX);
GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers.
}
TextEdit::TextEdit() {
@@ -6592,8 +7095,6 @@ TextEdit::TextEdit() {
indent_size = 4;
text.set_indent_size(indent_size);
text.clear();
- //text.insert(1,"Mongolia...");
- //text.insert(2,"PAIS GENEROSO!!");
text.set_color_regions(&color_regions);
h_scroll = memnew(HScrollBar);
@@ -6676,13 +7177,25 @@ TextEdit::TextEdit() {
select_identifiers_enabled = false;
smooth_scroll_enabled = false;
scrolling = false;
+ minimap_clicked = false;
+ dragging_minimap = false;
+ can_drag_minimap = false;
+ minimap_scroll_ratio = 0;
+ minimap_scroll_click_pos = 0;
+ dragging_selection = false;
target_v_scroll = 0;
v_scroll_speed = 80;
+ draw_minimap = false;
+ minimap_width = 80;
+ minimap_char_size = Point2(1, 2);
+ minimap_line_spacing = 1;
+ selecting_enabled = true;
context_menu_enabled = true;
+ shortcut_keys_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
- readonly = true; // initialise to opposite first, so we get past the early-out in set_readonly
+ readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
set_readonly(false);
menu->connect("id_pressed", this, "menu_option");
first_draw = true;
@@ -6696,8 +7209,14 @@ TextEdit::~TextEdit() {
///////////////////////////////////////////////////////////////////////////////
Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int p_line) {
+ if (syntax_highlighting_cache.has(p_line)) {
+ return syntax_highlighting_cache[p_line];
+ }
+
if (syntax_highlighter != NULL) {
- return syntax_highlighter->_get_line_syntax_highlighting(p_line);
+ Map<int, HighlighterInfo> color_map = syntax_highlighter->_get_line_syntax_highlighting(p_line);
+ syntax_highlighting_cache[p_line] = color_map;
+ return color_map;
}
Map<int, HighlighterInfo> color_map;
@@ -6743,14 +7262,14 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
bool is_symbol = _is_symbol(str[j]);
bool is_number = _is_number(str[j]);
- // allow ABCDEF in hex notation
+ // Allow ABCDEF in hex notation.
if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) {
is_number = true;
} else {
is_hex_notation = false;
}
- // check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation
+ // Check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation.
if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
@@ -6780,7 +7299,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
if (!cri.end) {
in_region = cri.region;
}
- } else if (in_region == cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
+ } else if (in_region == cri.region && !color_regions[cri.region].line_only) { // Ignore otherwise.
if (cri.end || color_regions[cri.region].eq) {
deregion = color_regions[cri.region].eq ? color_regions[cri.region].begin_key.length() : color_regions[cri.region].end_key.length();
}
@@ -6808,7 +7327,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
if (col) {
for (int k = j - 1; k >= 0; k--) {
if (str[k] == '.') {
- col = NULL; //member indexing not allowed
+ col = NULL; // Member indexing not allowed.
break;
} else if (str[k] > 32) {
break;
@@ -6830,7 +7349,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
k++;
}
- // check for space between name and bracket
+ // Check for space between name and bracket.
while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
k++;
}
@@ -6879,6 +7398,7 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
}
}
+ syntax_highlighting_cache[p_line] = color_map;
return color_map;
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index b47dac0902..e5d9b006fe 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -211,9 +211,11 @@ private:
int breakpoint_gutter_width;
int fold_gutter_width;
int info_gutter_width;
+ int minimap_width;
} cache;
Map<int, int> color_region_cache;
+ Map<int, Map<int, HighlighterInfo> > syntax_highlighting_cache;
struct TextOperation {
@@ -313,6 +315,10 @@ private:
bool hiding_enabled;
bool draw_info_gutter;
int info_gutter_width;
+ bool draw_minimap;
+ int minimap_width;
+ Point2 minimap_char_size;
+ int minimap_line_spacing;
bool highlight_all_occurrences;
bool scroll_past_end_of_file_enabled;
@@ -326,6 +332,12 @@ private:
bool smooth_scroll_enabled;
bool scrolling;
+ bool dragging_selection;
+ bool dragging_minimap;
+ bool can_drag_minimap;
+ bool minimap_clicked;
+ double minimap_scroll_ratio;
+ double minimap_scroll_click_pos;
float target_v_scroll;
float v_scroll_speed;
@@ -353,13 +365,20 @@ private:
int search_result_line;
int search_result_col;
+ bool selecting_enabled;
+
bool context_menu_enabled;
+ bool shortcut_keys_enabled;
int executing_line;
+ void _generate_context_menu();
+
int get_visible_rows() const;
int get_total_visible_rows() const;
+ int _get_minimap_visible_rows() const;
+
void update_cursor_wrap_offset();
void _update_wrap_at();
bool line_wraps(int line) const;
@@ -395,6 +414,8 @@ private:
void _update_selection_mode_word();
void _update_selection_mode_line();
+ void _update_minimap_click();
+ void _update_minimap_drag();
void _scroll_up(real_t p_delta);
void _scroll_down(real_t p_delta);
@@ -406,6 +427,7 @@ private:
//void mouse_motion(const Point& p_pos, const Point& p_rel, int p_button_mask);
Size2 get_minimum_size() const;
+ int _get_control_height() const;
int get_row_height() const;
@@ -484,6 +506,7 @@ public:
virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const;
void _get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const;
+ void _get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const;
//void delete_char();
//void delete_line();
@@ -564,6 +587,7 @@ public:
int cursor_get_column() const;
int cursor_get_line() const;
+ Vector2i _get_cursor_pixel_pos();
bool cursor_get_blink_enabled() const;
void cursor_set_blink_enabled(const bool p_enabled);
@@ -697,6 +721,12 @@ public:
void set_info_gutter_width(int p_gutter_width);
int get_info_gutter_width() const;
+ void set_draw_minimap(bool p_draw);
+ bool is_drawing_minimap() const;
+
+ void set_minimap_width(int p_minimap_width);
+ int get_minimap_width() const;
+
void set_hiding_enabled(bool p_enabled);
bool is_hiding_enabled() const;
@@ -713,6 +743,12 @@ public:
void set_context_menu_enabled(bool p_enable);
bool is_context_menu_enabled();
+ void set_selecting_enabled(bool p_enabled);
+ bool is_selecting_enabled() const;
+
+ void set_shortcut_keys_enabled(bool p_enabled);
+ bool is_shortcut_keys_enabled() const;
+
PopupMenu *get_menu() const;
String get_text_for_completion();
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index b5f949aeb7..e9b0bd8f38 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -205,24 +205,26 @@ void TextureButton::_notification(int p_what) {
case STRETCH_KEEP_ASPECT_COVERED: {
size = get_size();
Size2 tex_size = texdraw->get_size();
- Size2 scaleSize(size.width / tex_size.width, size.height / tex_size.height);
- float scale = scaleSize.width > scaleSize.height ? scaleSize.width : scaleSize.height;
- Size2 scaledTexSize = tex_size * scale;
- Point2 ofs2 = ((scaledTexSize - size) / scale).abs() / 2.0f;
+ Size2 scale_size(size.width / tex_size.width, size.height / tex_size.height);
+ float scale = scale_size.width > scale_size.height ? scale_size.width : scale_size.height;
+ Size2 scaled_tex_size = tex_size * scale;
+ Point2 ofs2 = ((scaled_tex_size - size) / scale).abs() / 2.0f;
_texture_region = Rect2(ofs2, size / scale);
} break;
}
}
+
_position_rect = Rect2(ofs, size);
- if (_tile)
+ if (_tile) {
draw_texture_rect(texdraw, _position_rect, _tile);
- else
+ } else {
draw_texture_rect_region(texdraw, _position_rect, _texture_region);
+ }
} else {
_position_rect = Rect2();
}
- if (has_focus() && focused.is_valid()) {
+ if (has_focus() && focused.is_valid()) {
draw_texture_rect(focused, _position_rect, false);
};
} break;
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index 3ab35324e5..1c5bd9d99c 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -32,9 +32,7 @@
#define TEXTURE_FRAME_H
#include "scene/gui/control.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class TextureRect : public Control {
GDCLASS(TextureRect, Control);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 4005505830..57663bbe82 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -224,14 +224,14 @@ Rect2 TreeItem::get_icon_region(int p_column) const {
return cells[p_column].icon_region;
}
-void TreeItem::set_icon_color(int p_column, const Color &p_icon_color) {
+void TreeItem::set_icon_modulate(int p_column, const Color &p_modulate) {
ERR_FAIL_INDEX(p_column, cells.size());
- cells.write[p_column].icon_color = p_icon_color;
+ cells.write[p_column].icon_color = p_modulate;
_changed_notify(p_column);
}
-Color TreeItem::get_icon_color(int p_column) const {
+Color TreeItem::get_icon_modulate(int p_column) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), Color());
return cells[p_column].icon_color;
@@ -328,7 +328,7 @@ void TreeItem::set_collapsed(bool p_collapsed) {
ci = ci->parent;
}
- if (ci) { // collapsing cursor/selectd, move it!
+ if (ci) { // collapsing cursor/selected, move it!
if (tree->select_mode == Tree::SELECT_MULTI) {
@@ -744,6 +744,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_icon_max_width", "column", "width"), &TreeItem::set_icon_max_width);
ClassDB::bind_method(D_METHOD("get_icon_max_width", "column"), &TreeItem::get_icon_max_width);
+ ClassDB::bind_method(D_METHOD("set_icon_modulate", "column", "modulate"), &TreeItem::set_icon_modulate);
+ ClassDB::bind_method(D_METHOD("get_icon_modulate", "column"), &TreeItem::get_icon_modulate);
+
ClassDB::bind_method(D_METHOD("set_range", "column", "value"), &TreeItem::set_range);
ClassDB::bind_method(D_METHOD("get_range", "column"), &TreeItem::get_range);
ClassDB::bind_method(D_METHOD("set_range_config", "column", "min", "max", "step", "expr"), &TreeItem::set_range_config, DEFVAL(false));
@@ -911,7 +914,6 @@ void Tree::update_cache() {
cache.arrow_collapsed = get_icon("arrow_collapsed");
cache.arrow = get_icon("arrow");
cache.select_arrow = get_icon("select_arrow");
- cache.select_option = get_icon("select_option");
cache.updown = get_icon("updown");
cache.custom_button = get_stylebox("custom_button");
@@ -927,7 +929,6 @@ void Tree::update_cache() {
cache.vseparation = get_constant("vseparation");
cache.item_margin = get_constant("item_margin");
cache.button_margin = get_constant("button_margin");
- cache.guide_width = get_constant("guide_width");
cache.draw_guides = get_constant("draw_guides");
cache.draw_relationship_lines = get_constant("draw_relationship_lines");
cache.relationship_line_color = get_color("relationship_line_color");
@@ -1181,23 +1182,22 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
}
- if (p_item->cells[i].selected && select_mode != SELECT_ROW) {
-
+ if (select_mode != SELECT_ROW && (p_item->cells[i].selected || selected_item == p_item)) {
Rect2i r(cell_rect.position, cell_rect.size);
+
if (p_item->cells[i].text.size() > 0) {
float icon_width = p_item->cells[i].get_icon_size().width;
r.position.x += icon_width;
r.size.x -= icon_width;
}
p_item->set_meta("__focus_rect", Rect2(r.position, r.size));
- if (has_focus()) {
- cache.selected_focus->draw(ci, r);
- } else {
- cache.selected->draw(ci, r);
- }
- if (text_editor->is_visible_in_tree()) {
- Vector2 ofs2(0, (text_editor->get_size().height - r.size.height) / 2);
- text_editor->set_position(get_global_position() + r.position - ofs2);
+
+ if (p_item->cells[i].selected) {
+ if (has_focus()) {
+ cache.selected_focus->draw(ci, r);
+ } else {
+ cache.selected->draw(ci, r);
+ }
}
}
@@ -1259,10 +1259,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2);
if (p_item->cells[i].checked) {
-
- checked->draw(ci, check_ofs, icon_col);
+ checked->draw(ci, check_ofs);
} else {
- unchecked->draw(ci, check_ofs, icon_col);
+ unchecked->draw(ci, check_ofs);
}
int check_w = checked->get_width() + cache.hseparation;
@@ -1274,8 +1273,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
draw_item_rect(p_item->cells[i], item_rect, col, icon_col);
- //font->draw( ci, text_pos, p_item->cells[i].text, col,item_rect.size.x-check_w );
-
} break;
case TreeItem::CELL_MODE_RANGE: {
if (p_item->cells[i].text != "") {
@@ -1305,18 +1302,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
font->draw(ci, text_pos, s, col, item_rect.size.x - downarrow->get_width());
- //?
Point2i arrow_pos = item_rect.position;
arrow_pos.x += item_rect.size.x - downarrow->get_width();
arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0);
- downarrow->draw(ci, arrow_pos, icon_col);
+ downarrow->draw(ci, arrow_pos);
} else {
Ref<Texture> updown = cache.updown;
- String valtext = String::num(p_item->cells[i].val, Math::step_decimals(p_item->cells[i].step));
- //String valtext = rtos( p_item->cells[i].val );
+ String valtext = String::num(p_item->cells[i].val, Math::range_step_decimals(p_item->cells[i].step));
if (p_item->cells[i].suffix != String())
valtext += " " + p_item->cells[i].suffix;
@@ -1330,7 +1325,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
updown_pos.x += item_rect.size.x - updown->get_width();
updown_pos.y += Math::floor(((item_rect.size.y - updown->get_height())) / 2.0);
- updown->draw(ci, updown_pos, icon_col);
+ updown->draw(ci, updown_pos);
}
} break;
@@ -1348,13 +1343,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
icon_ofs += item_rect.position;
draw_texture_rect(p_item->cells[i].icon, Rect2(icon_ofs, icon_size), false, icon_col);
- //p_item->cells[i].icon->draw(ci, icon_ofs);
} break;
case TreeItem::CELL_MODE_CUSTOM: {
- //int option = (int)p_item->cells[i].val;
-
if (p_item->cells[i].custom_draw_obj) {
Object *cdo = ObjectDB::get_instance(p_item->cells[i].custom_draw_obj);
@@ -1429,10 +1421,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
arrow->draw(ci, p_pos + p_draw_ofs + Point2i(0, (label_h - arrow->get_height()) / 2) - cache.offset);
}
- //separator
- //get_painter()->draw_fill_rect( Point2i(0,pos.y),Size2i(get_size().width,1),color( COLOR_TREE_GRID) );
-
- //pos=p_pos; //reset pos
}
Point2 children_pos = p_pos;
@@ -1926,7 +1914,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
} else {
- editor_text = String::num(p_item->cells[col].val, Math::step_decimals(p_item->cells[col].step));
+ editor_text = String::num(p_item->cells[col].val, Math::range_step_decimals(p_item->cells[col].step));
if (select_mode == SELECT_MULTI && get_tree()->get_event_count() == focus_in_id)
bring_up_editor = false;
}
@@ -2700,12 +2688,10 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
bool Tree::edit_selected() {
TreeItem *s = get_selected();
- ERR_EXPLAIN("No item selected!");
- ERR_FAIL_COND_V(!s, false);
+ ERR_FAIL_COND_V_MSG(!s, false, "No item selected.");
ensure_cursor_is_visible();
int col = get_selected_column();
- ERR_EXPLAIN("No item column selected!");
- ERR_FAIL_INDEX_V(col, columns.size(), false);
+ ERR_FAIL_INDEX_V_MSG(col, columns.size(), false, "No item column selected.");
if (!s->cells[col].editable)
return false;
@@ -2755,7 +2741,7 @@ bool Tree::edit_selected() {
text_editor->set_position(textedpos);
text_editor->set_size(rect.size);
text_editor->clear();
- text_editor->set_text(c.mode == TreeItem::CELL_MODE_STRING ? c.text : String::num(c.val, Math::step_decimals(c.step)));
+ text_editor->set_text(c.mode == TreeItem::CELL_MODE_STRING ? c.text : String::num(c.val, Math::range_step_decimals(c.step)));
text_editor->select_all();
if (c.mode == TreeItem::CELL_MODE_RANGE) {
@@ -2921,8 +2907,6 @@ void Tree::_notification(int p_what) {
drag_touching = false;
drag_touching_deaccel = false;
}
-
- } else {
}
}
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index b6cdab766f..f12d8fc4d2 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -37,10 +37,6 @@
#include "scene/gui/scroll_bar.h"
#include "scene/gui/slider.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Tree;
class TreeItem : public Object {
@@ -197,8 +193,8 @@ public:
void set_icon_region(int p_column, const Rect2 &p_icon_region);
Rect2 get_icon_region(int p_column) const;
- void set_icon_color(int p_column, const Color &p_icon_color);
- Color get_icon_color(int p_column) const;
+ void set_icon_modulate(int p_column, const Color &p_modulate);
+ Color get_icon_modulate(int p_column) const;
void set_icon_max_width(int p_column, int p_max);
int get_icon_max_width(int p_column) const;
@@ -420,7 +416,6 @@ private:
Ref<Texture> arrow_collapsed;
Ref<Texture> arrow;
Ref<Texture> select_arrow;
- Ref<Texture> select_option;
Ref<Texture> updown;
Color font_color;
@@ -433,7 +428,6 @@ private:
int hseparation;
int vseparation;
int item_margin;
- int guide_width;
int button_margin;
Point2 offset;
int draw_relationship_lines;
diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp
index 3f7a110c1b..35696a0459 100644
--- a/scene/gui/viewport_container.cpp
+++ b/scene/gui/viewport_container.cpp
@@ -211,4 +211,5 @@ ViewportContainer::ViewportContainer() {
stretch = false;
shrink = 1;
set_process_input(true);
+ set_process_unhandled_input(true);
}
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 05bd911014..6c922adbd2 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -60,14 +60,10 @@ Error HTTPRequest::_parse_url(const String &p_url) {
use_ssl = true;
port = 443;
} else {
- ERR_EXPLAIN("Malformed URL");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Malformed URL: " + url + ".");
}
- if (url.length() < 1) {
- ERR_EXPLAIN("URL too short");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- }
+ ERR_FAIL_COND_V_MSG(url.length() < 1, ERR_INVALID_PARAMETER, "URL too short: " + url + ".");
int slash_pos = url.find("/");
@@ -91,10 +87,7 @@ Error HTTPRequest::_parse_url(const String &p_url) {
Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const String &p_request_data) {
ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED);
- if (requesting) {
- ERR_EXPLAIN("HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one.");
- ERR_FAIL_V(ERR_BUSY);
- }
+ ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one.");
if (timeout > 0) {
timer->stop();
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index 71addd6fea..99ecc8bc37 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -92,6 +92,8 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
if (!ps.is_valid())
return NULL;
Node *scene = ps->instance();
+ if (!scene)
+ return NULL;
scene->set_name(get_name());
int pos = get_position_in_parent();
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index cf1bd96483..ba04cb69f2 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -210,7 +210,7 @@ void Node::_propagate_enter_tree() {
}
data.viewport = Object::cast_to<Viewport>(this);
- if (!data.viewport)
+ if (!data.viewport && data.parent)
data.viewport = data.parent->data.viewport;
data.inside_tree = true;
@@ -327,14 +327,9 @@ void Node::_propagate_exit_tree() {
void Node::move_child(Node *p_child, int p_pos) {
ERR_FAIL_NULL(p_child);
- ERR_EXPLAIN("Invalid new child position: " + itos(p_pos));
- ERR_FAIL_INDEX(p_pos, data.children.size() + 1);
- ERR_EXPLAIN("child is not a child of this node.");
- ERR_FAIL_COND(p_child->data.parent != this);
- if (data.blocked > 0) {
- ERR_EXPLAIN("Parent node is busy setting up children, move_child() failed. Consider using call_deferred(\"move_child\") instead (or \"popup\" if this is from a popup).");
- ERR_FAIL_COND(data.blocked > 0);
- }
+ ERR_FAIL_INDEX_MSG(p_pos, data.children.size() + 1, "Invalid new child position: " + itos(p_pos) + ".");
+ ERR_FAIL_COND_MSG(p_child->data.parent != this, "Child is not a child of this node.");
+ ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, move_child() failed. Consider using call_deferred(\"move_child\") instead (or \"popup\" if this is from a popup).");
// Specifying one place beyond the end
// means the same as moving to the last position
@@ -408,7 +403,6 @@ void Node::set_physics_process(bool p_process) {
else
remove_from_group("physics_process");
- data.physics_process = p_process;
_change_notify("physics_process");
}
@@ -429,7 +423,6 @@ void Node::set_physics_process_internal(bool p_process_internal) {
else
remove_from_group("physics_process_internal");
- data.physics_process_internal = p_process_internal;
_change_notify("physics_process_internal");
}
@@ -811,7 +804,6 @@ void Node::set_process(bool p_idle_process) {
else
remove_from_group("idle_process");
- data.idle_process = p_idle_process;
_change_notify("idle_process");
}
@@ -832,7 +824,6 @@ void Node::set_process_internal(bool p_idle_process_internal) {
else
remove_from_group("idle_process_internal");
- data.idle_process_internal = p_idle_process_internal;
_change_notify("idle_process_internal");
}
@@ -1021,7 +1012,7 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
if (!unique) {
- node_hrcr_count.ref();
+ ERR_FAIL_COND(!node_hrcr_count.ref());
String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get());
p_child->data.name = name;
}
@@ -1169,25 +1160,9 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) {
void Node::add_child(Node *p_child, bool p_legible_unique_name) {
ERR_FAIL_NULL(p_child);
-
- if (p_child == this) {
- ERR_EXPLAIN("Can't add child '" + p_child->get_name() + "' to itself.");
- ERR_FAIL_COND(p_child == this); // adding to itself!
- }
-
- /* Fail if node has a parent */
- if (p_child->data.parent) {
- ERR_EXPLAIN("Can't add child '" + p_child->get_name() + "' to '" + get_name() + "', already has a parent '" + p_child->data.parent->get_name() + "'.");
- ERR_FAIL_COND(p_child->data.parent);
- }
-
- if (data.blocked > 0) {
- ERR_EXPLAIN("Parent node is busy setting up children, add_node() failed. Consider using call_deferred(\"add_child\", child) instead.");
- ERR_FAIL_COND(data.blocked > 0);
- }
-
- ERR_EXPLAIN("Can't add child while a notification is happening.");
- ERR_FAIL_COND(data.blocked > 0);
+ ERR_FAIL_COND_MSG(p_child == this, "Can't add child '" + p_child->get_name() + "' to itself."); // adding to itself!
+ ERR_FAIL_COND_MSG(p_child->data.parent, "Can't add child '" + p_child->get_name() + "' to '" + get_name() + "', already has a parent '" + p_child->data.parent->get_name() + "'."); //Fail if node has a parent
+ ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, add_node() failed. Consider using call_deferred(\"add_child\", child) instead.");
/* Validate name */
_validate_child_name(p_child, p_legible_unique_name);
@@ -1243,10 +1218,7 @@ void Node::_propagate_validate_owner() {
void Node::remove_child(Node *p_child) {
ERR_FAIL_NULL(p_child);
- if (data.blocked > 0) {
- ERR_EXPLAIN("Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\",child) instead.");
- ERR_FAIL_COND(data.blocked > 0);
- }
+ ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead.");
int child_count = data.children.size();
Node **children = data.children.ptrw();
@@ -1269,7 +1241,7 @@ void Node::remove_child(Node *p_child) {
}
}
- ERR_FAIL_COND(idx == -1);
+ ERR_FAIL_COND_MSG(idx == -1, "Cannot remove child node " + p_child->get_name() + " as it is not a child of this node.");
//ERR_FAIL_COND( p_child->data.blocked > 0 );
//if (data.scene) { does not matter
@@ -1333,10 +1305,7 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
return NULL;
}
- if (!data.inside_tree && p_path.is_absolute()) {
- ERR_EXPLAIN("Can't use get_node() with absolute paths from outside the active scene tree.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!data.inside_tree && p_path.is_absolute(), NULL, "Can't use get_node() with absolute paths from outside the active scene tree.");
Node *current = NULL;
Node *root = NULL;
@@ -1397,10 +1366,7 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
Node *Node::get_node(const NodePath &p_path) const {
Node *node = get_node_or_null(p_path);
- if (!node) {
- ERR_EXPLAIN("Node not found: " + p_path);
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!node, NULL, "Node not found: " + p_path + ".");
return node;
}
@@ -1668,7 +1634,7 @@ NodePath Node::get_path_to(const Node *p_node) const {
NodePath Node::get_path() const {
- ERR_FAIL_COND_V(!is_inside_tree(), NodePath());
+ ERR_FAIL_COND_V_MSG(!is_inside_tree(), NodePath(), "Cannot get path of node as it is not in a scene tree.");
if (data.path_cache)
return *data.path_cache;
@@ -1750,14 +1716,17 @@ void Node::get_groups(List<GroupInfo> *p_groups) const {
}
}
-bool Node::has_persistent_groups() const {
+int Node::get_persistent_group_count() const {
+
+ int count = 0;
for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
- if (E->get().persistent)
- return true;
+ if (E->get().persistent) {
+ count += 1;
+ }
}
- return false;
+ return count;
}
void Node::_print_tree_pretty(const String &prefix, const bool last) {
@@ -1906,6 +1875,19 @@ String Node::get_filename() const {
return data.filename;
}
+void Node::set_editor_description(const String &p_editor_description) {
+
+ set_meta("_editor_description_", p_editor_description);
+}
+String Node::get_editor_description() const {
+
+ if (has_meta("_editor_description_")) {
+ return get_meta("_editor_description_");
+ } else {
+ return "";
+ }
+}
+
void Node::set_editable_instance(Node *p_node, bool p_editable) {
ERR_FAIL_NULL(p_node);
@@ -2195,11 +2177,12 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
} else {
Object *obj = ClassDB::instance(get_class());
- ERR_EXPLAIN("Node: Could not duplicate: " + String(get_class()));
- ERR_FAIL_COND(!obj);
+ ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + ".");
node = Object::cast_to<Node>(obj);
- if (!node)
+ if (!node) {
memdelete(obj);
+ ERR_FAIL_MSG("Node: Could not duplicate: " + String(get_class()) + ".");
+ }
}
List<PropertyInfo> plist;
@@ -2295,16 +2278,14 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
ERR_FAIL_COND_V(get_filename() != "", NULL);
- Node *node = NULL;
-
Object *obj = ClassDB::instance(get_class());
- ERR_EXPLAIN("Node: Could not duplicate: " + String(get_class()));
- ERR_FAIL_COND_V(!obj, NULL);
- node = Object::cast_to<Node>(obj);
- if (!node)
- memdelete(obj);
- ERR_FAIL_COND_V(!node, NULL);
+ ERR_FAIL_COND_V_MSG(!obj, NULL, "Node: Could not duplicate: " + String(get_class()) + ".");
+ Node *node = Object::cast_to<Node>(obj);
+ if (!node) {
+ memdelete(obj);
+ ERR_FAIL_V_MSG(NULL, "Node: Could not duplicate: " + String(get_class()) + ".");
+ }
node->set_name(get_name());
List<PropertyInfo> plist;
@@ -2440,8 +2421,7 @@ void Node::_replace_connections_target(Node *p_new_target) {
if (c.flags & CONNECT_PERSIST) {
c.source->disconnect(c.signal, this, c.method);
bool valid = p_new_target->has_method(c.method) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.method);
- ERR_EXPLAIN("Attempt to connect signal \'" + c.source->get_class() + "." + c.signal + "\' to nonexistent method \'" + c.target->get_class() + "." + c.method + "\'");
- ERR_CONTINUE(!valid);
+ ERR_CONTINUE_MSG(!valid, "Attempt to connect signal '" + c.source->get_class() + "." + c.signal + "' to nonexistent method '" + c.target->get_class() + "." + c.method + "'.");
c.source->connect(c.signal, p_new_target, c.method, c.binds, c.flags);
}
}
@@ -2487,7 +2467,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 +2505,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;
}
@@ -2815,6 +2801,10 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config);
ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config);
+ ClassDB::bind_method(D_METHOD("_set_editor_description", "editor_description"), &Node::set_editor_description);
+ ClassDB::bind_method(D_METHOD("_get_editor_description"), &Node::get_editor_description);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_editor_description", "_get_editor_description");
+
ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path);
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
@@ -2871,6 +2861,8 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
BIND_CONSTANT(NOTIFICATION_CRASH);
BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
+ BIND_CONSTANT(NOTIFICATION_APP_RESUMED);
+ BIND_CONSTANT(NOTIFICATION_APP_PAUSED);
BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT);
BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
@@ -2887,10 +2879,6 @@ void Node::_bind_methods() {
ADD_SIGNAL(MethodInfo("tree_exiting"));
ADD_SIGNAL(MethodInfo("tree_exited"));
- //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/process" ),"set_process","is_processing") ;
- //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/physics_process" ), "set_physics_process","is_physics_processing") ;
- //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/input" ), "set_process_input","is_processing_input" ) ;
- //ADD_PROPERTY( PropertyInfo( Variant::BOOL, "process/unhandled_input" ), "set_process_unhandled_input","is_processing_unhandled_input" ) ;
ADD_GROUP("Pause", "pause_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");
@@ -2914,9 +2902,6 @@ void Node::_bind_methods() {
BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEventKey")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_configuration_warning"));
-
- //ClassDB::bind_method(D_METHOD("get_child",&Node::get_child,PH("index")));
- //ClassDB::bind_method(D_METHOD("get_node",&Node::get_node,PH("path")));
}
String Node::_get_name_num_separator() {
diff --git a/scene/main/node.h b/scene/main/node.h
index 982bfcd620..a8bcd2f273 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -250,7 +250,9 @@ public:
NOTIFICATION_TRANSLATION_CHANGED = MainLoop::NOTIFICATION_TRANSLATION_CHANGED,
NOTIFICATION_WM_ABOUT = MainLoop::NOTIFICATION_WM_ABOUT,
NOTIFICATION_CRASH = MainLoop::NOTIFICATION_CRASH,
- NOTIFICATION_OS_IME_UPDATE = MainLoop::NOTIFICATION_OS_IME_UPDATE
+ NOTIFICATION_OS_IME_UPDATE = MainLoop::NOTIFICATION_OS_IME_UPDATE,
+ NOTIFICATION_APP_RESUMED = MainLoop::NOTIFICATION_APP_RESUMED,
+ NOTIFICATION_APP_PAUSED = MainLoop::NOTIFICATION_APP_PAUSED
};
@@ -300,7 +302,7 @@ public:
};
void get_groups(List<GroupInfo> *p_groups) const;
- bool has_persistent_groups() const;
+ int get_persistent_group_count() const;
void move_child(Node *p_child, int p_pos);
void raise();
@@ -318,6 +320,9 @@ public:
void set_filename(const String &p_filename);
String get_filename() const;
+ void set_editor_description(const String &p_editor_description);
+ String get_editor_description() const;
+
void set_editable_instance(Node *p_node, bool p_editable);
bool is_editable_instance(const Node *p_node) const;
void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances);
@@ -363,8 +368,6 @@ public:
Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const;
#endif
- //Node *clone_tree() const;
-
// used by editors, to save what has changed only
void set_scene_instance_state(const Ref<SceneState> &p_state);
Ref<SceneState> get_scene_instance_state() const;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 5eeaff6411..0465c9305b 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -33,11 +33,11 @@
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
#include "core/message_queue.h"
+#include "core/os/dir_access.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/print_string.h"
#include "core/project_settings.h"
-#include "editor/editor_node.h"
#include "main/input_default.h"
#include "node.h"
#include "scene/resources/dynamic_font.h"
@@ -117,10 +117,7 @@ SceneTree::Group *SceneTree::add_to_group(const StringName &p_group, Node *p_nod
E = group_map.insert(p_group, Group());
}
- if (E->get().nodes.find(p_node) != -1) {
- ERR_EXPLAIN("Already in group: " + p_group);
- ERR_FAIL_V(&E->get());
- }
+ ERR_FAIL_COND_V_MSG(E->get().nodes.find(p_node) != -1, &E->get(), "Already in group: " + p_group + ".");
E->get().nodes.push_back(p_node);
//E->get().last_tree_version=0;
E->get().changed = true;
@@ -633,6 +630,7 @@ void SceneTree::_notification(int p_notification) {
break;
}
} break;
+
case NOTIFICATION_WM_GO_BACK_REQUEST: {
get_root()->propagate_notification(p_notification);
@@ -642,27 +640,23 @@ void SceneTree::_notification(int p_notification) {
break;
}
} break;
- case NOTIFICATION_OS_MEMORY_WARNING:
- case NOTIFICATION_OS_IME_UPDATE:
- case NOTIFICATION_WM_MOUSE_ENTER:
- case NOTIFICATION_WM_MOUSE_EXIT:
- case NOTIFICATION_WM_FOCUS_IN:
- case NOTIFICATION_WM_FOCUS_OUT: {
- if (p_notification == NOTIFICATION_WM_FOCUS_IN) {
- InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
- if (id) {
- id->ensure_touch_mouse_raised();
- }
+ case NOTIFICATION_WM_FOCUS_IN: {
+
+ InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
+ if (id) {
+ id->ensure_touch_mouse_raised();
}
get_root()->propagate_notification(p_notification);
} break;
+
case NOTIFICATION_TRANSLATION_CHANGED: {
if (!Engine::get_singleton()->is_editor_hint()) {
get_root()->propagate_notification(p_notification);
}
} break;
+
case NOTIFICATION_WM_UNFOCUS_REQUEST: {
notify_group_flags(GROUP_CALL_REALTIME | GROUP_CALL_MULTILEVEL, "input", NOTIFICATION_WM_UNFOCUS_REQUEST);
@@ -671,20 +665,15 @@ void SceneTree::_notification(int p_notification) {
} break;
- case NOTIFICATION_WM_ABOUT: {
-
-#ifdef TOOLS_ENABLED
- if (EditorNode::get_singleton()) {
- EditorNode::get_singleton()->show_about();
- } else {
-#endif
- get_root()->propagate_notification(p_notification);
-#ifdef TOOLS_ENABLED
- }
-#endif
- } break;
-
- case NOTIFICATION_CRASH: {
+ case NOTIFICATION_OS_MEMORY_WARNING:
+ case NOTIFICATION_OS_IME_UPDATE:
+ case NOTIFICATION_WM_MOUSE_ENTER:
+ case NOTIFICATION_WM_MOUSE_EXIT:
+ case NOTIFICATION_WM_FOCUS_OUT:
+ case NOTIFICATION_WM_ABOUT:
+ case NOTIFICATION_CRASH:
+ case NOTIFICATION_APP_RESUMED:
+ case NOTIFICATION_APP_PAUSED: {
get_root()->propagate_notification(p_notification);
} break;
@@ -1089,7 +1078,7 @@ void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_li
static void _fill_array(Node *p_node, Array &array, int p_level) {
- array.push_back(p_level);
+ array.push_back(p_node->get_child_count());
array.push_back(p_node->get_name());
array.push_back(p_node->get_class());
array.push_back(p_node->get_instance_id());
@@ -1507,8 +1496,11 @@ void SceneTree::_live_edit_instance_node_func(const NodePath &p_parent, const St
Node *n2 = n->get_node(p_parent);
Node *no = ps->instance();
- no->set_name(p_name);
+ if (!no) {
+ continue;
+ }
+ no->set_name(p_name);
n2->add_child(no);
}
}
@@ -1686,6 +1678,12 @@ void SceneTree::drop_files(const Vector<String> &p_files, int p_from_screen) {
MainLoop::drop_files(p_files, p_from_screen);
}
+void SceneTree::global_menu_action(const Variant &p_id, const Variant &p_meta) {
+
+ emit_signal("global_menu_action", p_id, p_meta);
+ MainLoop::global_menu_action(p_id, p_meta);
+}
+
Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_pause) {
Ref<SceneTreeTimer> stt;
@@ -1907,6 +1905,7 @@ void SceneTree::_bind_methods() {
ADD_SIGNAL(MethodInfo("physics_frame"));
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "screen")));
+ ADD_SIGNAL(MethodInfo("global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta")));
ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("connected_to_server"));
@@ -1959,6 +1958,38 @@ bool SceneTree::is_using_font_oversampling() const {
return use_font_oversampling;
}
+void SceneTree::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+
+ if (p_function == "change_scene") {
+ DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ List<String> directories;
+ directories.push_back(dir_access->get_current_dir());
+
+ while (!directories.empty()) {
+ dir_access->change_dir(directories.back()->get());
+ directories.pop_back();
+
+ dir_access->list_dir_begin();
+ String filename = dir_access->get_next();
+
+ while (filename != "") {
+ if (filename == "." || filename == "..") {
+ filename = dir_access->get_next();
+ continue;
+ }
+
+ if (dir_access->dir_exists(filename)) {
+ directories.push_back(dir_access->get_current_dir().plus_file(filename));
+ } else if (filename.ends_with(".tscn") || filename.ends_with(".scn")) {
+ r_options->push_back("\"" + dir_access->get_current_dir().plus_file(filename) + "\"");
+ }
+
+ filename = dir_access->get_next();
+ }
+ }
+ }
+}
+
SceneTree::SceneTree() {
if (singleton == NULL) singleton = this;
@@ -2069,6 +2100,7 @@ SceneTree::SceneTree() {
if (ScriptDebugger::get_singleton()) {
ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree, this);
+ ScriptDebugger::get_singleton()->set_multiplayer(multiplayer);
}
root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true));
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 98f2fe5e35..d387886d61 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -39,10 +39,6 @@
#include "scene/resources/world.h"
#include "scene/resources/world_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class PackedScene;
class Node;
class Viewport;
@@ -411,6 +407,8 @@ public:
static SceneTree *get_singleton() { return singleton; }
void drop_files(const Vector<String> &p_files, int p_from_screen = 0);
+ void global_menu_action(const Variant &p_id, const Variant &p_meta);
+ void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
//network API
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 2ae950dad5..14cc705edb 100755
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -80,8 +80,7 @@ void Timer::_notification(int p_what) {
}
void Timer::set_wait_time(float p_time) {
- ERR_EXPLAIN("time should be greater than zero.");
- ERR_FAIL_COND(p_time <= 0);
+ ERR_FAIL_COND_MSG(p_time <= 0, "Time should be greater than zero.");
wait_time = p_time;
}
float Timer::get_wait_time() const {
@@ -108,6 +107,9 @@ bool Timer::has_autostart() const {
}
void Timer::start(float p_time) {
+
+ ERR_FAIL_COND_MSG(!is_inside_tree(), "Timer was not added to the SceneTree!");
+
if (p_time > 0) {
set_wait_time(p_time);
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 24c8ee31b2..b5c82ce4e3 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -65,13 +65,11 @@ void ViewportTexture::setup_local_to_scene() {
}
Node *vpn = local_scene->get_node(path);
- ERR_EXPLAIN("ViewportTexture: Path to node is invalid");
- ERR_FAIL_COND(!vpn);
+ ERR_FAIL_COND_MSG(!vpn, "ViewportTexture: Path to node is invalid.");
vp = Object::cast_to<Viewport>(vpn);
- ERR_EXPLAIN("ViewportTexture: Path to node does not point to a viewport");
- ERR_FAIL_COND(!vp);
+ ERR_FAIL_COND_MSG(!vp, "ViewportTexture: Path to node does not point to a viewport.");
vp->viewport_textures.insert(this);
@@ -581,7 +579,7 @@ void Viewport::_notification(int p_what) {
if (physics_object_capture != 0) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture));
- if (co) {
+ if (co && camera) {
_collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
captured = true;
if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
@@ -2291,32 +2289,34 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (from && p_event->is_pressed()) {
Control *next = NULL;
- if (p_event->is_action_pressed("ui_focus_next")) {
+ Input *input = Input::get_singleton();
+
+ if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
next = from->find_next_valid_focus();
}
- if (p_event->is_action_pressed("ui_focus_prev")) {
+ if (p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) {
next = from->find_prev_valid_focus();
}
- if (!mods && p_event->is_action_pressed("ui_up")) {
+ if (!mods && p_event->is_action_pressed("ui_up") && input->is_action_just_pressed("ui_up")) {
next = from->_get_focus_neighbour(MARGIN_TOP);
}
- if (!mods && p_event->is_action_pressed("ui_left")) {
+ if (!mods && p_event->is_action_pressed("ui_left") && input->is_action_just_pressed("ui_left")) {
next = from->_get_focus_neighbour(MARGIN_LEFT);
}
- if (!mods && p_event->is_action_pressed("ui_right")) {
+ if (!mods && p_event->is_action_pressed("ui_right") && input->is_action_just_pressed("ui_right")) {
next = from->_get_focus_neighbour(MARGIN_RIGHT);
}
- if (!mods && p_event->is_action_pressed("ui_down")) {
+ if (!mods && p_event->is_action_pressed("ui_down") && input->is_action_just_pressed("ui_down")) {
next = from->_get_focus_neighbour(MARGIN_BOTTOM);
}
@@ -2393,8 +2393,7 @@ void Viewport::_gui_remove_from_modal_stack(List<Control *>::Element *MI, Object
void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control) {
- ERR_EXPLAIN("Drag data must be a value");
- ERR_FAIL_COND(p_data.get_type() == Variant::NIL);
+ ERR_FAIL_COND_MSG(p_data.get_type() == Variant::NIL, "Drag data must be a value.");
gui.dragging = true;
gui.drag_data = p_data;
@@ -2579,7 +2578,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
@@ -2590,7 +2589,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() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index b7160d5139..6393785b22 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -36,9 +36,6 @@
#include "scene/resources/texture.h"
#include "scene/resources/world_2d.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Camera;
class Camera2D;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 0423fcb5f0..418ee6af0e 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -101,6 +101,7 @@
#include "scene/gui/popup_menu.h"
#include "scene/gui/progress_bar.h"
#include "scene/gui/reference_rect.h"
+#include "scene/gui/rich_text_effect.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/scroll_bar.h"
#include "scene/gui/scroll_container.h"
@@ -304,6 +305,7 @@ void register_scene_types() {
ClassDB::register_class<TextureRect>();
ClassDB::register_class<ColorRect>();
ClassDB::register_class<NinePatchRect>();
+ ClassDB::register_class<ReferenceRect>();
ClassDB::register_class<TabContainer>();
ClassDB::register_class<Tabs>();
ClassDB::register_virtual_class<Separator>();
@@ -339,10 +341,11 @@ void register_scene_types() {
ClassDB::register_virtual_class<TreeItem>();
ClassDB::register_class<OptionButton>();
ClassDB::register_class<SpinBox>();
- ClassDB::register_class<ReferenceRect>();
ClassDB::register_class<ColorPicker>();
ClassDB::register_class<ColorPickerButton>();
ClassDB::register_class<RichTextLabel>();
+ ClassDB::register_class<RichTextEffect>();
+ ClassDB::register_class<CharFXTransform>();
ClassDB::register_class<PopupDialog>();
ClassDB::register_class<WindowDialog>();
ClassDB::register_class<AcceptDialog>();
@@ -361,6 +364,9 @@ void register_scene_types() {
/* REGISTER 3D */
+ ClassDB::register_class<Skin>();
+ ClassDB::register_virtual_class<SkinReference>();
+
ClassDB::register_class<Spatial>();
ClassDB::register_virtual_class<SpatialGizmo>();
ClassDB::register_class<Skeleton>();
@@ -475,6 +481,7 @@ void register_scene_types() {
ClassDB::register_class<Shader>();
ClassDB::register_class<VisualShader>();
ClassDB::register_virtual_class<VisualShaderNode>();
+ ClassDB::register_class<VisualShaderNodeCustom>();
ClassDB::register_class<VisualShaderNodeInput>();
ClassDB::register_virtual_class<VisualShaderNodeOutput>();
ClassDB::register_class<VisualShaderNodeGroupBase>();
@@ -509,6 +516,7 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeVectorRefract>();
ClassDB::register_class<VisualShaderNodeScalarInterp>();
ClassDB::register_class<VisualShaderNodeVectorInterp>();
+ ClassDB::register_class<VisualShaderNodeVectorScalarMix>();
ClassDB::register_class<VisualShaderNodeVectorCompose>();
ClassDB::register_class<VisualShaderNodeTransformCompose>();
ClassDB::register_class<VisualShaderNodeVectorDecompose>();
@@ -522,11 +530,16 @@ 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<VisualShaderNodeScalarSwitch>();
ClassDB::register_class<VisualShaderNodeFresnel>();
ClassDB::register_class<VisualShaderNodeExpression>();
+ ClassDB::register_class<VisualShaderNodeGlobalExpression>();
+ ClassDB::register_class<VisualShaderNodeIs>();
+ ClassDB::register_class<VisualShaderNodeCompare>();
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
@@ -604,6 +617,7 @@ void register_scene_types() {
ClassDB::register_class<PrismMesh>();
ClassDB::register_class<QuadMesh>();
ClassDB::register_class<SphereMesh>();
+ ClassDB::register_class<PointMesh>();
ClassDB::register_virtual_class<Material>();
ClassDB::register_class<SpatialMaterial>();
SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
@@ -748,7 +762,7 @@ void register_scene_types() {
if (theme_path != String()) {
Ref<Theme> theme = ResourceLoader::load(theme_path);
if (theme.is_valid()) {
- Theme::set_default(theme);
+ Theme::set_project_default(theme);
if (font.is_valid()) {
Theme::set_default_font(font);
}
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index 3645f88807..b551ad2ac4 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -31,10 +31,6 @@
#ifndef REGISTER_SCENE_TYPES_H
#define REGISTER_SCENE_TYPES_H
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
void register_scene_types();
void unregister_scene_types();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 64051fe304..985b38f913 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -1667,8 +1667,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
Vector2 pb = p_post_b;
return a.cubic_interpolate(b, pa, pb, p_c);
-
- } break;
+ }
case Variant::RECT2: {
Rect2 a = p_a;
@@ -1679,8 +1678,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return Rect2(
a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
-
- } break;
+ }
case Variant::VECTOR3: {
Vector3 a = p_a;
@@ -1689,8 +1687,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
Vector3 pb = p_post_b;
return a.cubic_interpolate(b, pa, pb, p_c);
-
- } break;
+ }
case Variant::QUAT: {
Quat a = p_a;
@@ -1699,8 +1696,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
Quat pb = p_post_b;
return a.cubic_slerp(b, pa, pb, p_c);
-
- } break;
+ }
case Variant::AABB: {
AABB a = p_a;
@@ -1711,14 +1707,12 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return AABB(
a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
- } break;
+ }
default: {
return _interpolate(p_a, p_b, p_c);
}
}
-
- return Variant();
}
float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
@@ -2876,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.loc;
const Vector3 &v2 = t2.value.loc;
- if (Math::is_zero_approx(v0.distance_to(v2))) {
+ if (v0 == v2) {
//0 and 2 are close, let's see if 1 is close
- if (!Math::is_zero_approx(v0.distance_to(v1))) {
+ if (v0 != v1) {
//not close, not optimizable
return false;
}
@@ -2965,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.scale;
const Vector3 &v2 = t2.value.scale;
- if (Math::is_zero_approx(v0.distance_to(v2))) {
+ if (v0 == v2) {
//0 and 2 are close, let's see if 1 is close
- if (!Math::is_zero_approx(v0.distance_to(v1))) {
+ if (v0 != v1) {
//not close, not optimizable
return false;
}
@@ -3028,7 +3022,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
//this could be done as a second pass and would be
//able to optimize more
erase = false;
- } else {
}
}
}
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6fff77d746..d59dfab2c8 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -32,9 +32,7 @@
#define ANIMATION_H
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Animation : public Resource {
GDCLASS(Animation, Resource);
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/curve.cpp b/scene/resources/curve.cpp
index cb710dde43..bb14cf3ab1 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -765,10 +765,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve2D.");
- ERR_FAIL_V(Vector2());
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
if (pc == 1)
return baked_point_cache.get(0);
@@ -831,10 +828,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve2D.");
- ERR_FAIL_V(Vector2());
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
if (pc == 1)
return baked_point_cache.get(0);
@@ -870,10 +864,7 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve2D.");
- ERR_FAIL_V(0.0f);
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve2D.");
if (pc == 1)
return 0.0f;
@@ -1336,10 +1327,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve3D.");
- ERR_FAIL_V(Vector3());
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
if (pc == 1)
return baked_point_cache.get(0);
@@ -1381,10 +1369,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
//validate//
int pc = baked_tilt_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No tilts in Curve3D.");
- ERR_FAIL_V(0);
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, 0, "No tilts in Curve3D.");
if (pc == 1)
return baked_tilt_cache.get(0);
@@ -1420,10 +1405,7 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
//validate//
// curve may not have baked up vectors
int count = baked_up_vector_cache.size();
- if (count == 0) {
- ERR_EXPLAIN("No up vectors in Curve3D.");
- ERR_FAIL_V(Vector3(0, 1, 0));
- }
+ ERR_FAIL_COND_V_MSG(count == 0, Vector3(0, 1, 0), "No up vectors in Curve3D.");
if (count == 1)
return baked_up_vector_cache.get(0);
@@ -1491,10 +1473,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve3D.");
- ERR_FAIL_V(Vector3());
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
if (pc == 1)
return baked_point_cache.get(0);
@@ -1530,10 +1509,7 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
//validate//
int pc = baked_point_cache.size();
- if (pc == 0) {
- ERR_EXPLAIN("No points in Curve3D.");
- ERR_FAIL_V(0.0f);
- }
+ ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve3D.");
if (pc == 1)
return 0.0f;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index fb0fb4f8e3..f68dc9af38 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -611,6 +611,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("title_font", "GraphNode", default_font);
theme->set_color("title_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_color("close_color", "GraphNode", Color(0, 0, 0, 1));
+ theme->set_color("resizer_color", "GraphNode", Color(0, 0, 0, 1));
theme->set_constant("title_offset", "GraphNode", 20 * scale);
theme->set_constant("close_offset", "GraphNode", 18 * scale);
theme->set_constant("port_offset", "GraphNode", 3 * scale);
@@ -656,7 +657,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("hseparation", "Tree", 4 * scale);
theme->set_constant("vseparation", "Tree", 4 * scale);
- theme->set_constant("guide_width", "Tree", 2 * scale);
theme->set_constant("item_margin", "Tree", 12 * scale);
theme->set_constant("button_margin", "Tree", 4 * scale);
theme->set_constant("draw_relationship_lines", "Tree", 0);
@@ -760,6 +760,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// FileDialog
theme->set_icon("folder", "FileDialog", make_icon(icon_folder_png));
+ theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1));
theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7));
// colorPicker
@@ -892,8 +893,9 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
void clear_default_theme() {
- Theme::set_default(Ref<Theme>());
- Theme::set_default_icon(Ref<Texture>());
- Theme::set_default_style(Ref<StyleBox>());
- Theme::set_default_font(Ref<Font>());
+ Theme::set_project_default(NULL);
+ Theme::set_default(NULL);
+ Theme::set_default_icon(NULL);
+ Theme::set_default_style(NULL);
+ Theme::set_default_font(NULL);
}
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index cbf0cc1b79..e7d80ffb3d 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -32,9 +32,6 @@
#define DEFAULT_THEME_H
#include "scene/resources/theme.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
diff --git a/scene/resources/default_theme/make_header.py b/scene/resources/default_theme/make_header.py
index bd5a723b23..cf0ccf1c3a 100755
--- a/scene/resources/default_theme/make_header.py
+++ b/scene/resources/default_theme/make_header.py
@@ -1,9 +1,14 @@
#!/usr/bin/env python
import glob
+import os
enc = "utf-8"
+# Change to the directory where the script is located,
+# so that the script can be run from any location
+os.chdir(os.path.dirname(os.path.realpath(__file__)))
+
# Generate include files
f = open("theme_data.h", "wb")
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index cf37c57407..11904b7aff 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -339,7 +339,7 @@ static const unsigned char toggle_off_png[] = {
};
static const unsigned char toggle_off_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x4e, 0xe8, 0x1b, 0x92, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x6, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x58, 0x47, 0xed, 0x59, 0x4b, 0x6f, 0x1b, 0x55, 0x14, 0x3e, 0xb6, 0xc7, 0x8e, 0xed, 0xf1, 0x2b, 0x7e, 0x84, 0xb8, 0x49, 0x8a, 0x48, 0x36, 0x55, 0x37, 0x48, 0x5d, 0x64, 0xc1, 0x3a, 0x42, 0x82, 0x14, 0x89, 0x56, 0x14, 0x16, 0x48, 0xfc, 0x1, 0xca, 0x1f, 0x40, 0x20, 0x81, 0x90, 0xf8, 0x1, 0xd0, 0x25, 0x8b, 0x8a, 0x25, 0xa0, 0x82, 0x8a, 0x10, 0x12, 0x42, 0x8, 0x29, 0x5d, 0x15, 0xa9, 0x12, 0x8b, 0x4a, 0x20, 0x51, 0x50, 0x1b, 0xcb, 0x79, 0xf8, 0xed, 0x8c, 0xdf, 0xe3, 0x31, 0xe7, 0xbb, 0x99, 0xeb, 0x4c, 0x26, 0x33, 0xb6, 0x13, 0xbb, 0xb4, 0x42, 0xbd, 0xd2, 0xc9, 0x24, 0x77, 0xee, 0x39, 0x73, 0xbf, 0x7b, 0x1e, 0xf7, 0x9c, 0x13, 0xa2, 0x67, 0xe3, 0xd9, 0x9, 0xfc, 0xaf, 0x4e, 0xc0, 0x33, 0x21, 0x1a, 0xac, 0x93, 0x4, 0x96, 0x49, 0xf9, 0x26, 0x14, 0x7f, 0xe6, 0x65, 0x3, 0x93, 0x13, 0x4f, 0x49, 0x23, 0x85, 0x8d, 0xdb, 0xb8, 0x97, 0xb9, 0x41, 0x7e, 0xb, 0xf9, 0xcc, 0xb9, 0x71, 0xbc, 0x67, 0x46, 0x31, 0x21, 0x23, 0x0, 0x1a, 0x4c, 0x7d, 0xa6, 0x9e, 0x85, 0x30, 0x7, 0x72, 0x1c, 0x6e, 0x9b, 0xc6, 0x3c, 0x80, 0x5, 0x98, 0x22, 0x4c, 0x9, 0x93, 0x62, 0xfc, 0xc, 0x99, 0xe0, 0x71, 0x10, 0x4f, 0xa, 0xb4, 0x4, 0xb, 0xa0, 0x2d, 0xa6, 0x3a, 0x53, 0xd5, 0x24, 0x8d, 0x9f, 0x5d, 0xf3, 0x20, 0xa4, 0x5, 0xc, 0xc1, 0x3b, 0x6d, 0x18, 0x40, 0x14, 0x13, 0x68, 0x86, 0x9f, 0xcb, 0xe9, 0xf4, 0x73, 0xd7, 0x22, 0x91, 0xd8, 0x6b, 0x8a, 0xe2, 0xe3, 0xbf, 0x3d, 0x78, 0xe7, 0xe1, 0x31, 0xa1, 0x22, 0x1e, 0xcf, 0xb2, 0xc1, 0x40, 0x60, 0xe1, 0x1f, 0x3, 0x5d, 0xd7, 0xfb, 0x5, 0x4d, 0xab, 0x7f, 0x5f, 0x2c, 0xee, 0x7d, 0xcd, 0x73, 0x39, 0xa6, 0x2, 0x13, 0x80, 0xeb, 0x76, 0x6d, 0xdb, 0x77, 0xd, 0xb0, 0xd0, 0x6a, 0x9c, 0xe9, 0x7c, 0x22, 0x91, 0xba, 0x92, 0x4c, 0xa6, 0xdf, 0xf3, 0x7a, 0x3d, 0x91, 0x23, 0x7c, 0x56, 0x16, 0x37, 0xd0, 0x27, 0xe, 0xf6, 0x70, 0x6f, 0xc2, 0x20, 0x60, 0x6d, 0xb3, 0x37, 0xe, 0x1c, 0x80, 0x61, 0x18, 0x5a, 0xb9, 0x5c, 0xfc, 0xbc, 0x5a, 0x2d, 0x7d, 0xcb, 0x1f, 0x79, 0xc4, 0x54, 0x33, 0xb5, 0x3d, 0x34, 0x71, 0xfb, 0xee, 0x1, 0x76, 0x9e, 0x69, 0x35, 0x9b, 0x5d, 0x7e, 0x5f, 0x55, 0x23, 0x9b, 0x0, 0xea, 0xf7, 0x7b, 0x29, 0x99, 0x4c, 0x52, 0x34, 0x1a, 0xa5, 0xb9, 0xb9, 0x39, 0xf2, 0x7a, 0xb1, 0x61, 0xe7, 0xc1, 0xc7, 0x4d, 0xb5, 0x5a, 0x8d, 0xa, 0x85, 0x2, 0xf5, 0x60, 0x70, 0xc3, 0x21, 0xf, 0x1, 0xdf, 0xc6, 0x67, 0xdd, 0x65, 0x4c, 0x63, 0x13, 0x0, 0xde, 0x68, 0x1c, 0xfc, 0xb0, 0xb3, 0x93, 0xfb, 0x94, 0xe5, 0xfc, 0xcd, 0x54, 0x31, 0x41, 0x8b, 0xd, 0x48, 0xc0, 0xd2, 0x67, 0xa1, 0xd9, 0xb5, 0x73, 0xe7, 0x56, 0x3e, 0x9, 0x87, 0xd5, 0x97, 0x61, 0xb6, 0xe9, 0x74, 0x42, 0x80, 0x5, 0x88, 0x6a, 0xb5, 0x4a, 0xdd, 0x8e, 0x21, 0x74, 0x65, 0x1f, 0x10, 0xa0, 0x70, 0x68, 0xb, 0x6, 0x83, 0xe2, 0x60, 0x40, 0xa5, 0x52, 0x89, 0xca, 0xc5, 0x9a, 0x43, 0x4, 0x91, 0xda, 0x9e, 0x6, 0x9a, 0x3b, 0x2f, 0x40, 0x37, 0x9b, 0xda, 0x4f, 0xf9, 0xfc, 0xf6, 0x87, 0xbc, 0xea, 0x81, 0xa9, 0x69, 0x4, 0xb7, 0x1, 0x2, 0x13, 0x6, 0x8e, 0x3b, 0xc8, 0x94, 0x9d, 0x9f, 0x4f, 0xbf, 0x1d, 0x8f, 0x27, 0xde, 0x1, 0xd8, 0x6c, 0x36, 0x43, 0xaa, 0xaa, 0x52, 0x3e, 0x9f, 0x67, 0xb0, 0xd, 0xea, 0xf7, 0x9d, 0xa0, 0x1e, 0x7d, 0xd8, 0x60, 0xe5, 0x75, 0xbb, 0x3a, 0x1d, 0x1c, 0x34, 0xa9, 0xdd, 0x6e, 0x88, 0x83, 0xa, 0x86, 0x2, 0xd4, 0xd4, 0x9a, 0xb6, 0x43, 0x7a, 0xbc, 0xfe, 0x8f, 0xbd, 0xfb, 0xfd, 0x81, 0x35, 0x0, 0x6d, 0xb5, 0x9a, 0x7f, 0xf2, 0xb3, 0xc1, 0x4, 0x7f, 0x1e, 0x48, 0xbb, 0xc2, 0x13, 0xd1, 0x78, 0x39, 0x99, 0x4c, 0x5d, 0x87, 0x19, 0x27, 0x93, 0x31, 0xa, 0x85, 0x42, 0x94, 0xcb, 0xe5, 0xa8, 0xd5, 0xc2, 0xda, 0xd3, 0x8d, 0x46, 0xa3, 0x2b, 0x78, 0x21, 0x23, 0x91, 0x8c, 0xfe, 0xe7, 0xe1, 0x1c, 0xa0, 0xe7, 0xe7, 0x53, 0xef, 0xf2, 0xae, 0x57, 0x4c, 0x6c, 0x50, 0xae, 0x47, 0x46, 0xf, 0xdc, 0xb3, 0xf1, 0x4c, 0x66, 0xf1, 0x2d, 0xe, 0x50, 0xa1, 0x0, 0x7, 0xe2, 0x54, 0x2a, 0x45, 0x3b, 0x3b, 0x3b, 0x36, 0x3f, 0x3c, 0x1d, 0x68, 0xf8, 0xf0, 0xee, 0xee, 0xae, 0x90, 0xe5, 0x53, 0x46, 0x5b, 0xc7, 0xe9, 0x24, 0x4f, 0xb6, 0xda, 0xeb, 0xf5, 0x85, 0x18, 0xd3, 0x9b, 0xc0, 0x6, 0x8f, 0x3, 0x97, 0xb8, 0x62, 0x98, 0x0, 0x38, 0xa1, 0xaa, 0xd1, 0x4d, 0x4c, 0x46, 0x93, 0x11, 0x76, 0xfc, 0xc6, 0x99, 0x34, 0x6b, 0xdf, 0x4a, 0xb3, 0xd9, 0x63, 0x7f, 0x6a, 0x52, 0x3c, 0x1e, 0x67, 0x9f, 0xc6, 0x75, 0xe9, 0x3c, 0x7a, 0xbd, 0x36, 0xad, 0xaf, 0xaf, 0xd3, 0xc5, 0x8b, 0x17, 0xa8, 0xd3, 0xe9, 0xd0, 0xd6, 0xd6, 0x1d, 0xda, 0xdb, 0x2b, 0xb1, 0x85, 0x4, 0xe8, 0xea, 0xd5, 0xd7, 0x8f, 0x31, 0xdd, 0xba, 0xf5, 0xdd, 0x89, 0xb9, 0xdb, 0xb7, 0x7f, 0x64, 0x57, 0x3a, 0x38, 0x21, 0x1c, 0x81, 0x97, 0xe3, 0xe7, 0x17, 0xfc, 0x62, 0x8f, 0xa9, 0x63, 0x5, 0x1c, 0xe3, 0x7b, 0x36, 0xd, 0xfc, 0xb1, 0x58, 0x8c, 0xca, 0xe5, 0xf2, 0x64, 0xc7, 0x38, 0xc1, 0x2a, 0x4d, 0xd3, 0x84, 0x3f, 0x8f, 0x2, 0xbc, 0xb1, 0xb1, 0x21, 0x80, 0xde, 0xbc, 0xf9, 0x25, 0x7, 0xca, 0x34, 0x5d, 0xbe, 0xfc, 0xaa, 0xf8, 0x1d, 0x80, 0x31, 0xac, 0x80, 0x9c, 0xe6, 0xdc, 0xb6, 0xa1, 0x28, 0xa, 0x72, 0x9, 0x24, 0x4c, 0x2, 0xab, 0xf4, 0x61, 0xd8, 0x37, 0x82, 0x96, 0x50, 0x7b, 0x20, 0xc0, 0x81, 0x86, 0xb5, 0x32, 0xab, 0x1, 0x59, 0x90, 0x39, 0x4a, 0xbb, 0xcb, 0xcb, 0xe7, 0xe8, 0xfe, 0xfd, 0x3f, 0x38, 0xd8, 0x4, 0xf9, 0x46, 0xd0, 0xe8, 0xc1, 0x83, 0x7f, 0x68, 0x75, 0x75, 0x55, 0xb0, 0xec, 0xef, 0x97, 0x4e, 0xb0, 0x3a, 0xcd, 0x39, 0xcb, 0x17, 0x89, 0x12, 0xb2, 0x43, 0xe1, 0xc3, 0x2, 0x20, 0x7e, 0x91, 0x13, 0xf8, 0x83, 0x4f, 0x85, 0xf4, 0x63, 0x77, 0xe8, 0x74, 0xd0, 0x21, 0xb, 0x32, 0xdd, 0x6, 0x2c, 0xa, 0x0, 0xac, 0x26, 0x59, 0x2c, 0x16, 0x84, 0xa6, 0x8b, 0xc5, 0x22, 0x47, 0xfe, 0xe, 0x5d, 0xba, 0xf4, 0xa2, 0x60, 0xbf, 0x77, 0xef, 0x77, 0xd2, 0xf5, 0xce, 0x89, 0x39, 0x27, 0x73, 0x16, 0xc0, 0xe, 0x33, 0xa6, 0x61, 0xa6, 0x23, 0x77, 0x21, 0x73, 0x53, 0x21, 0x14, 0xc9, 0x3, 0xee, 0xd4, 0xe3, 0x89, 0xc3, 0xd9, 0x41, 0x43, 0x16, 0x64, 0xba, 0xd, 0x45, 0x99, 0xa3, 0x85, 0x85, 0x94, 0xb8, 0xbb, 0xe5, 0xc6, 0xa3, 0xd1, 0x98, 0x0, 0x25, 0x7, 0x80, 0xca, 0x77, 0xd2, 0xa4, 0xad, 0x73, 0x6e, 0xb2, 0xcd, 0x14, 0x14, 0xd9, 0x8e, 0x88, 0x9a, 0xd2, 0xa4, 0x71, 0x29, 0x73, 0x12, 0x3e, 0xe0, 0x5d, 0xd, 0xf8, 0x43, 0x5d, 0xa, 0x87, 0xc3, 0x67, 0x47, 0x68, 0xe3, 0x84, 0x2c, 0xc8, 0x74, 0x1b, 0x0, 0x2, 0xd, 0x27, 0x12, 0x51, 0xb1, 0x4, 0xc0, 0xd7, 0xd6, 0x5e, 0x10, 0xda, 0x9d, 0x7e, 0x0, 0x93, 0x28, 0x30, 0x44, 0xe2, 0x1, 0xd, 0x3, 0x39, 0xc, 0xf8, 0x40, 0xd7, 0x8d, 0x82, 0xdf, 0xef, 0xcb, 0xd6, 0xeb, 0x75, 0x91, 0x70, 0xd4, 0x6a, 0xb3, 0xf1, 0xe3, 0x48, 0x24, 0x42, 0x90, 0x39, 0x6a, 0xdc, 0xb9, 0xb3, 0x45, 0x9b, 0x9b, 0xaf, 0xd0, 0x85, 0xb, 0x1a, 0x47, 0xf4, 0x88, 0xf0, 0x61, 0x19, 0xa5, 0xa7, 0x1, 0xcd, 0x96, 0x85, 0x42, 0x2, 0x1f, 0x17, 0x89, 0x87, 0x35, 0xd3, 0xa, 0x70, 0x76, 0xb2, 0xc0, 0xa9, 0xe1, 0xa5, 0x7e, 0x5b, 0xa7, 0xcc, 0x62, 0x86, 0xaf, 0x25, 0x8d, 0x4d, 0xd1, 0xb5, 0xb4, 0x9c, 0x68, 0x1f, 0xe1, 0xb0, 0x5f, 0xdc, 0xc3, 0xb8, 0x8f, 0xd, 0xc3, 0x3d, 0xc3, 0xe2, 0x8a, 0x87, 0xb6, 0xb7, 0xf3, 0xc4, 0x55, 0xf, 0xdd, 0xbd, 0xfb, 0x1b, 0xe7, 0x0, 0xfb, 0x42, 0x7e, 0xab, 0xd5, 0x10, 0xa6, 0xdd, 0xeb, 0xf5, 0x87, 0x56, 0xe2, 0x34, 0xe7, 0x6e, 0x3d, 0xb5, 0xaf, 0x38, 0xcd, 0xfc, 0x85, 0xdf, 0xe3, 0xda, 0xd1, 0x25, 0x60, 0x61, 0xde, 0xfc, 0xa2, 0xc0, 0xa9, 0xe5, 0x35, 0xc3, 0x33, 0x60, 0xaf, 0x33, 0x28, 0x93, 0xc9, 0x88, 0xd, 0x20, 0x65, 0x3c, 0xcb, 0xf0, 0xb3, 0x94, 0xa5, 0xa5, 0x25, 0xaa, 0x54, 0x2a, 0xd4, 0xe4, 0xcc, 0x6b, 0xdc, 0x80, 0xd9, 0xd7, 0xeb, 0x7, 0x34, 0x18, 0x1c, 0x1d, 0x8c, 0xcf, 0xa7, 0x70, 0x4e, 0xd0, 0x3a, 0xe6, 0x12, 0x4e, 0x73, 0x4e, 0xb2, 0xd, 0xa3, 0xdf, 0xca, 0xe5, 0x1e, 0x7e, 0xc0, 0xef, 0x1e, 0x32, 0x21, 0xbd, 0x34, 0xac, 0x80, 0x45, 0x46, 0xcf, 0x41, 0x4d, 0xf, 0x85, 0xc2, 0x2f, 0xb5, 0xdb, 0x5d, 0x2e, 0x4, 0x2, 0xe2, 0xfe, 0xec, 0x74, 0x9a, 0xa7, 0xd6, 0xb4, 0xaa, 0x6, 0x38, 0x17, 0xcf, 0x72, 0x4e, 0xdd, 0xa6, 0x52, 0xa1, 0xea, 0x58, 0x70, 0x8c, 0x3b, 0x80, 0x69, 0xde, 0x23, 0x58, 0x55, 0x2a, 0xc5, 0xcf, 0x38, 0x97, 0xfe, 0x95, 0xe5, 0x20, 0x18, 0xe0, 0xc4, 0x87, 0x26, 0xd, 0xd9, 0xa2, 0x5d, 0xc2, 0xb, 0x76, 0x82, 0xc1, 0xd0, 0xf3, 0x7e, 0xbf, 0x7f, 0x4d, 0xe3, 0xa4, 0x5f, 0x51, 0xbc, 0xb4, 0xb8, 0xb8, 0x28, 0x9e, 0xb8, 0xe, 0xc, 0x97, 0x2, 0x42, 0xa4, 0x6b, 0xac, 0x51, 0x55, 0xd, 0xf2, 0x75, 0x32, 0x2f, 0xac, 0x43, 0x94, 0x89, 0x7b, 0x65, 0xf7, 0x7e, 0xcb, 0x34, 0x88, 0x46, 0xf0, 0xca, 0x6a, 0x69, 0x7f, 0x7f, 0xf7, 0x6, 0x2f, 0x43, 0x43, 0x40, 0x68, 0x17, 0x2c, 0x6e, 0xf5, 0x30, 0x97, 0x88, 0xe7, 0x3f, 0xe2, 0xe8, 0xba, 0x81, 0x6b, 0x4c, 0x51, 0x3c, 0xc2, 0xf, 0xa7, 0xab, 0x87, 0x1f, 0x13, 0x3a, 0x9b, 0xd8, 0x43, 0xb0, 0x8d, 0x9f, 0xf3, 0xf9, 0x47, 0x1f, 0xf3, 0xab, 0xbf, 0x98, 0x1c, 0xeb, 0x61, 0xc9, 0x26, 0x3b, 0x1e, 0xe8, 0x61, 0x9d, 0xe7, 0x6a, 0xe3, 0xa, 0xd3, 0x75, 0x9f, 0xcf, 0xcb, 0x95, 0x94, 0xac, 0x61, 0xad, 0x25, 0xb4, 0xf5, 0x6b, 0xe3, 0x8a, 0x3, 0xc9, 0x6f, 0x97, 0x33, 0xbb, 0x83, 0xe8, 0xf7, 0xfb, 0x1a, 0x9b, 0xf1, 0x8d, 0x4a, 0x65, 0xd8, 0xf1, 0x40, 0x9f, 0xb, 0xa6, 0xec, 0xd8, 0xf1, 0xb0, 0x82, 0x46, 0x31, 0x81, 0x72, 0x91, 0x73, 0x6b, 0x5a, 0xe1, 0x9e, 0xd6, 0x1b, 0x66, 0x4f, 0x6b, 0x1, 0xd9, 0xd9, 0x93, 0xee, 0x67, 0xc9, 0x8d, 0x1e, 0x26, 0x15, 0xa2, 0xa7, 0xb5, 0x6f, 0xf6, 0xb4, 0xbe, 0xe1, 0x89, 0x6d, 0xd3, 0x67, 0xd1, 0xd3, 0xc2, 0x75, 0x7b, 0x2c, 0xe4, 0x8e, 0xeb, 0x5a, 0xce, 0x31, 0x83, 0xca, 0x4, 0x8d, 0xa3, 0xf5, 0x63, 0xef, 0x5a, 0xce, 0x4e, 0x3d, 0xa7, 0x97, 0x4, 0x20, 0xd6, 0xae, 0x25, 0x4c, 0x17, 0x1a, 0x85, 0xbf, 0x22, 0x45, 0x13, 0x89, 0x86, 0x5d, 0xec, 0xa8, 0xd6, 0x3, 0xde, 0xc9, 0x1c, 0x1b, 0x9, 0xa, 0xb2, 0x7f, 0x68, 0x5e, 0x24, 0xe1, 0x26, 0x9d, 0x7e, 0x9b, 0xb3, 0xe3, 0x90, 0x8d, 0x77, 0xd9, 0x97, 0x86, 0xe9, 0x22, 0xb9, 0x90, 0x40, 0x1d, 0x7d, 0x6c, 0xd2, 0x5e, 0x8b, 0x4, 0xf8, 0x34, 0x0, 0xb5, 0x1f, 0x99, 0xf5, 0xbf, 0xe, 0xe3, 0x2, 0xc9, 0xec, 0x8e, 0xfb, 0x99, 0xa4, 0xa7, 0xf4, 0x4, 0xfe, 0x5, 0x72, 0xf1, 0x9c, 0xca, 0xa6, 0xf4, 0x2a, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 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, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0xfc, 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, 0x14, 0x14, 0x17, 0x20, 0x20, 0x25, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x13, 0x22, 0x22, 0x27, 0x24, 0x24, 0x28, 0x25, 0x25, 0x28, 0x25, 0x25, 0x29, 0x25, 0x25, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x19, 0x1c, 0x2b, 0x26, 0x2c, 0x40, 0x40, 0x44, 0x4e, 0x4e, 0x52, 0x1a, 0x1a, 0x1d, 0x32, 0x32, 0x37, 0x2c, 0x26, 0x2c, 0x26, 0x25, 0x2a, 0x27, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x2f, 0x26, 0x2d, 0x12, 0x12, 0x14, 0x23, 0x23, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x15, 0x18, 0x20, 0x20, 0x25, 0x20, 0x20, 0x24, 0x5b, 0x5b, 0x5f, 0x84, 0x84, 0x87, 0x77, 0x77, 0x7a, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, 0x69, 0x6c, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x27, 0x15, 0x15, 0x18, 0x23, 0x23, 0x28, 0x12, 0x12, 0x14, 0x0, 0x0, 0x0, 0x1a, 0x1a, 0x1e, 0x0, 0x0, 0x0, 0x11, 0x11, 0x13, 0x22, 0x22, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0xb, 0x1b, 0xbb, 0x0, 0x0, 0x0, 0x54, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x98, 0xe5, 0xfa, 0xfe, 0xff, 0xff, 0x8, 0x17, 0x35, 0x86, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x7, 0x3a, 0xb4, 0xff, 0xff, 0xff, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xb, 0x28, 0x8a, 0xff, 0x8b, 0xf6, 0x45, 0x5, 0x9b, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x37, 0xf, 0xff, 0xfb, 0x4c, 0xfe, 0x4e, 0x4f, 0x50, 0xfb, 0x9c, 0xf6, 0x8c, 0x3b, 0xbb, 0x3c, 0x87, 0xf3, 0x53, 0x14, 0xd4, 0x6d, 0x6c, 0xf9, 0x0, 0x0, 0x2, 0x3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xdd, 0x55, 0x85, 0x9a, 0xe2, 0x30, 0x18, 0xbc, 0x7a, 0x8b, 0xbb, 0x7b, 0x2, 0xbb, 0x4d, 0x36, 0xb8, 0x3b, 0xeb, 0xae, 0xef, 0xff, 0x2e, 0x47, 0x48, 0x3f, 0xa0, 0x7a, 0xae, 0x83, 0x56, 0xfe, 0xe9, 0xfc, 0xfe, 0xe9, 0x6f, 0x2, 0xc7, 0xb, 0x82, 0xf8, 0x45, 0x8, 0x2, 0xcf, 0x39, 0x9a, 0xf3, 0xa2, 0x24, 0x2b, 0xaa, 0xe6, 0xfb, 0x2, 0x34, 0x55, 0x91, 0x25, 0x91, 0xb7, 0x3f, 0x5d, 0xf4, 0xab, 0x81, 0x60, 0x28, 0x1c, 0x89, 0xc6, 0x3c, 0x11, 0x8d, 0x84, 0x43, 0xc1, 0x80, 0xea, 0x17, 0x2d, 0x2a, 0xf8, 0x78, 0x22, 0x99, 0x4a, 0x67, 0xb2, 0xb9, 0x7c, 0xe1, 0xb, 0xc8, 0xe7, 0xb2, 0x99, 0x74, 0x2a, 0x99, 0x88, 0xf3, 0x26, 0xfb, 0x62, 0xa9, 0x5c, 0xa9, 0xd6, 0x0, 0x80, 0x10, 0xb2, 0xfb, 0x20, 0x5, 0x80, 0x75, 0xe8, 0x48, 0x52, 0xad, 0x94, 0x4b, 0xc5, 0x23, 0x6, 0xae, 0xa1, 0x9d, 0x9c, 0xd6, 0x80, 0x8e, 0xf0, 0x1e, 0x48, 0xdf, 0xb1, 0xd4, 0x81, 0x8b, 0x8e, 0xd3, 0x13, 0xad, 0xc1, 0x1d, 0xfc, 0x57, 0x82, 0x67, 0x35, 0x48, 0x30, 0x6a, 0xb6, 0x76, 0x97, 0x5b, 0x3a, 0x41, 0x98, 0xb4, 0x77, 0x4a, 0xdc, 0x3c, 0x39, 0xb, 0x2a, 0xfb, 0x38, 0xf0, 0x9d, 0x6e, 0xaf, 0x6, 0x11, 0xea, 0x1f, 0xdf, 0x41, 0x10, 0x6a, 0x7b, 0xc6, 0x62, 0xd0, 0xed, 0xf0, 0x6, 0x81, 0x58, 0xa, 0xd, 0x1, 0xa1, 0xa2, 0x8f, 0xa1, 0x23, 0xd2, 0xf2, 0x62, 0x18, 0x8e, 0x4a, 0x63, 0x26, 0x81, 0x93, 0x2, 0x13, 0xa0, 0xe3, 0xbe, 0xf5, 0xe, 0x82, 0x3d, 0x25, 0x14, 0x26, 0x1, 0x89, 0x11, 0xf0, 0x72, 0x70, 0xba, 0x15, 0x60, 0xbf, 0x3, 0x11, 0xe3, 0xcf, 0x6c, 0xbe, 0x58, 0xa2, 0x42, 0x7f, 0xb1, 0xc5, 0xee, 0x8b, 0x9d, 0x5f, 0xad, 0x37, 0xcc, 0x7, 0x41, 0x9, 0x65, 0x21, 0xbd, 0xd9, 0x8a, 0x3d, 0xe9, 0xf9, 0x7c, 0x46, 0x16, 0xb3, 0x3e, 0x35, 0xa4, 0x5f, 0x6, 0x2e, 0x46, 0x8a, 0xc0, 0x8, 0xd4, 0xcb, 0x2b, 0x88, 0x75, 0x3b, 0x81, 0x8e, 0xd, 0x1, 0xd4, 0x68, 0x8e, 0xfa, 0xe7, 0x94, 0xe0, 0x7c, 0x4f, 0x90, 0xbf, 0x56, 0x45, 0x46, 0x50, 0xba, 0xa9, 0x41, 0xec, 0x10, 0xb0, 0x96, 0x41, 0xd0, 0x3f, 0xdf, 0x7e, 0xe1, 0x79, 0xff, 0xfc, 0xfc, 0x9c, 0x6c, 0xbf, 0xf6, 0x14, 0xb7, 0x25, 0x83, 0x40, 0xd, 0xd7, 0x3c, 0x15, 0x90, 0x9d, 0x2, 0xec, 0xae, 0x40, 0x9, 0xdd, 0x1, 0xef, 0x18, 0xa0, 0x2, 0x59, 0xda, 0x5c, 0xd8, 0xc7, 0x80, 0x97, 0xd7, 0x5f, 0xc8, 0x42, 0x7f, 0x79, 0xbe, 0x9c, 0x17, 0x2c, 0x4, 0xfb, 0x2c, 0xd0, 0x3a, 0xb8, 0xff, 0x42, 0x1d, 0x10, 0x5a, 0x95, 0x33, 0x44, 0xd8, 0x97, 0x81, 0xfb, 0xa4, 0xc4, 0xed, 0x2b, 0xf1, 0x1, 0xfe, 0x40, 0x25, 0xd2, 0x5e, 0x18, 0x7c, 0x7b, 0x2f, 0x3c, 0xd2, 0x5e, 0xf8, 0x72, 0x37, 0x16, 0xbe, 0xdc, 0x8d, 0x6c, 0x1e, 0x3c, 0x3d, 0xd7, 0x40, 0xdb, 0x32, 0xf, 0xbc, 0xec, 0x9f, 0x5f, 0xf6, 0xf3, 0x80, 0x4d, 0x24, 0x2d, 0xf8, 0xfa, 0x6, 0xea, 0x80, 0xd, 0x24, 0x68, 0x0, 0x6c, 0x5f, 0x8e, 0xf6, 0xd5, 0xd7, 0xa0, 0x56, 0x34, 0xcf, 0xb4, 0x86, 0x92, 0xc, 0xa5, 0x33, 0x17, 0xf9, 0xc2, 0x17, 0x91, 0xbf, 0xc8, 0xa4, 0x43, 0x49, 0xa5, 0xc1, 0x5b, 0xa7, 0x72, 0x47, 0xd, 0xac, 0x47, 0xd7, 0xef, 0xb1, 0x2f, 0xe0, 0xfd, 0x7a, 0xb4, 0xe, 0xa8, 0x1d, 0x91, 0xb3, 0x6f, 0x95, 0xb1, 0xb4, 0xf9, 0x28, 0x7d, 0x79, 0x2f, 0x94, 0x3e, 0x36, 0xd2, 0x98, 0xe7, 0x5c, 0x36, 0x93, 0xf8, 0x15, 0xa0, 0x9b, 0xe9, 0xff, 0xc2, 0x67, 0x14, 0xf4, 0xa5, 0xb3, 0x35, 0x5e, 0x63, 0x97, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char toggle_on_png[] = {
@@ -347,7 +347,7 @@ static const unsigned char toggle_on_png[] = {
};
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
+ 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, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x1, 0x53, 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, 0xd, 0xd, 0xf, 0x1a, 0x1a, 0x1e, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0xc, 0x1d, 0x1d, 0x21, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x23, 0x23, 0x28, 0x2e, 0x2e, 0x2e, 0x46, 0x46, 0x46, 0x57, 0x57, 0x57, 0x60, 0x60, 0x60, 0x62, 0x62, 0x62, 0x5e, 0x5e, 0x5e, 0x4a, 0x4a, 0x4a, 0x12, 0x12, 0x15, 0x25, 0x27, 0x2d, 0x42, 0x42, 0x42, 0x59, 0x59, 0x59, 0x32, 0x32, 0x32, 0x25, 0x26, 0x2d, 0x25, 0x25, 0x2b, 0x25, 0x26, 0x2c, 0x39, 0x39, 0x39, 0x49, 0x49, 0x49, 0x5a, 0x5a, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb, 0xd, 0x23, 0x23, 0x28, 0x48, 0x48, 0x48, 0x54, 0x54, 0x54, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0xb, 0xb, 0xd, 0x1e, 0x1e, 0x22, 0x25, 0x26, 0x2b, 0x3f, 0x3f, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0x2c, 0x2c, 0x2c, 0x58, 0x58, 0x58, 0x1a, 0x1a, 0x1e, 0x40, 0x40, 0x44, 0x56, 0x56, 0x58, 0x80, 0x80, 0x80, 0x79, 0x79, 0x79, 0x3c, 0x3c, 0x3d, 0x2e, 0x2e, 0x30, 0x27, 0x27, 0x29, 0x64, 0x64, 0x66, 0x41, 0x41, 0x41, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x5d, 0x5f, 0x34, 0x34, 0x36, 0x52, 0x52, 0x52, 0x3a, 0x3a, 0x3a, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x32, 0x32, 0x37, 0x42, 0x42, 0x44, 0x6a, 0x6a, 0x6d, 0x5b, 0x5b, 0x5b, 0x2f, 0x2f, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x49, 0x4a, 0x0, 0x0, 0x0, 0x50, 0x50, 0x51, 0x70, 0x70, 0x74, 0xe, 0xe, 0x10, 0xb, 0xb, 0xd, 0x0, 0x0, 0x0, 0x13, 0x13, 0x15, 0x0, 0x0, 0x0, 0xb, 0xb, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbd, 0xb, 0x85, 0x35, 0x0, 0x0, 0x0, 0x71, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x80, 0xc5, 0xe7, 0xf5, 0xfe, 0xff, 0x8, 0x17, 0x35, 0x73, 0xd9, 0xff, 0x7, 0x3a, 0x96, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0x28, 0x76, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x77, 0xde, 0xff, 0xff, 0x45, 0x5, 0x82, 0xff, 0xff, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc6, 0x37, 0xf, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x4c, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4e, 0x4f, 0xff, 0x50, 0xff, 0xff, 0x83, 0x78, 0x3b, 0x9c, 0x3c, 0x74, 0xda, 0x53, 0x14, 0x49, 0x96, 0x6e, 0xf, 0x0, 0x0, 0x1, 0xfa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x18, 0x5e, 0x0, 0xd0, 0x5c, 0x39, 0x28, 0x49, 0x12, 0xc0, 0x60, 0xb8, 0xda, 0xdd, 0xcb, 0x31, 0x33, 0xb6, 0x6d, 0xdb, 0x5e, 0xdb, 0xd6, 0xfb, 0x17, 0x4e, 0x7d, 0x37, 0xe6, 0xf9, 0x2b, 0x23, 0x7f, 0x9c, 0x20, 0x28, 0x86, 0xe1, 0xb, 0xc1, 0x30, 0x14, 0x99, 0x6a, 0x8e, 0xe2, 0x4, 0x49, 0xd1, 0xcc, 0xda, 0x2, 0x18, 0x9a, 0x22, 0x9, 0x1c, 0x9d, 0xf4, 0x8e, 0xaf, 0xd3, 0x1b, 0x9b, 0x5b, 0xdb, 0x1c, 0x2e, 0x6f, 0x2e, 0x5c, 0xce, 0xf6, 0xd6, 0xe6, 0x6, 0xbd, 0x8e, 0x8f, 0x45, 0x81, 0xf2, 0x5, 0x42, 0x91, 0x58, 0x22, 0x95, 0xc9, 0x61, 0x1, 0x72, 0x99, 0x54, 0x22, 0x16, 0x9, 0x5, 0x7c, 0x74, 0xc4, 0x5e, 0xa1, 0x54, 0xa9, 0x35, 0x5a, 0x58, 0x12, 0xad, 0x46, 0xad, 0x52, 0x2a, 0x86, 0x14, 0x10, 0x1d, 0xa3, 0x37, 0x18, 0x61, 0x1e, 0x26, 0xb3, 0xc5, 0x6a, 0x63, 0xb1, 0x3b, 0x4c, 0x60, 0x34, 0xe8, 0x19, 0x1d, 0x32, 0xc8, 0x9f, 0xda, 0x74, 0xce, 0x8d, 0xdd, 0xe5, 0xf6, 0x98, 0xbd, 0x3e, 0xff, 0x57, 0x2, 0xa6, 0x60, 0x28, 0xec, 0x76, 0xc9, 0x9d, 0x9b, 0x54, 0xbf, 0xe, 0x68, 0x24, 0x1a, 0x8b, 0xcf, 0xb5, 0x4f, 0x24, 0x53, 0x30, 0x44, 0x3a, 0x99, 0x70, 0xc5, 0x33, 0xd1, 0xc8, 0x8f, 0x24, 0x70, 0xe5, 0x56, 0x16, 0xe6, 0x90, 0xcb, 0x27, 0x4d, 0x63, 0x9, 0x25, 0xf3, 0xb9, 0x6c, 0x41, 0x59, 0x64, 0x43, 0x40, 0x88, 0x8d, 0x12, 0xcc, 0xa3, 0x5c, 0x49, 0xc3, 0x18, 0x69, 0x4f, 0x19, 0x4a, 0x1b, 0x4, 0x2b, 0x80, 0x92, 0x9b, 0x55, 0xe8, 0x53, 0xab, 0x37, 0x9a, 0x2d, 0x68, 0x37, 0x3a, 0xd0, 0xee, 0x2, 0x4b, 0xcf, 0x1, 0x13, 0x38, 0x7a, 0xb0, 0xb3, 0xbb, 0xc7, 0xe6, 0x80, 0x51, 0x5b, 0x52, 0xe8, 0xd3, 0xdd, 0xaf, 0x1d, 0x34, 0x6a, 0xed, 0x46, 0x77, 0x20, 0x70, 0x78, 0x4, 0x13, 0x1c, 0x1d, 0xc2, 0x71, 0x81, 0xc2, 0x58, 0x1, 0xfa, 0x44, 0x36, 0x8, 0xa0, 0x71, 0xa, 0xb0, 0x7f, 0xd6, 0x3e, 0x6f, 0xb6, 0xfb, 0x2, 0x17, 0x97, 0x30, 0xc1, 0xe5, 0x5, 0x18, 0xaf, 0x68, 0x9c, 0x15, 0x50, 0x5e, 0xf, 0x7a, 0xd8, 0x3e, 0x7, 0x80, 0x9b, 0x7a, 0xbb, 0x7b, 0x73, 0xde, 0x17, 0xb0, 0xfa, 0x60, 0x2, 0x9f, 0x15, 0xe0, 0x56, 0xf9, 0x5d, 0x80, 0xde, 0x1e, 0xc, 0xd1, 0xe9, 0xd7, 0x8, 0xea, 0x77, 0xed, 0x2e, 0xdc, 0xd7, 0x97, 0x8e, 0x80, 0xda, 0x3a, 0x86, 0x3e, 0xe7, 0x67, 0x70, 0xda, 0x6c, 0xb5, 0xbb, 0xd0, 0x6a, 0x2c, 0x5b, 0x3, 0x94, 0xdc, 0xad, 0x42, 0x9f, 0x76, 0xf3, 0xbc, 0x59, 0x87, 0xaf, 0xe1, 0x9f, 0x2f, 0xd5, 0x5, 0x76, 0xe, 0x1e, 0x60, 0xc0, 0xe9, 0x59, 0x7, 0xa0, 0xd6, 0x2, 0xe8, 0xb4, 0xe6, 0xcf, 0xc1, 0x83, 0x90, 0x40, 0x7e, 0x79, 0x12, 0xfb, 0xbb, 0x90, 0x59, 0x7d, 0x17, 0x1e, 0xd9, 0x5d, 0xf8, 0xd5, 0x6d, 0xec, 0xdf, 0x83, 0xa7, 0xe7, 0xf8, 0x2a, 0xf7, 0x20, 0xfe, 0xfc, 0xc2, 0xde, 0x83, 0xfe, 0x45, 0x62, 0x36, 0x5f, 0xdf, 0x60, 0x69, 0xde, 0x5e, 0x37, 0x19, 0xc5, 0xe8, 0x4d, 0xd3, 0x51, 0xc2, 0x2d, 0xb1, 0xe4, 0xd8, 0x8, 0xb, 0x31, 0x1e, 0x4b, 0xc4, 0x5b, 0x42, 0x4a, 0x87, 0x8e, 0x5f, 0xe5, 0x8, 0xbd, 0xb1, 0x5b, 0xb8, 0x7a, 0xe7, 0x2d, 0xe0, 0xfd, 0xaa, 0xb0, 0xbb, 0x41, 0x47, 0x70, 0x64, 0xf2, 0xab, 0x14, 0x89, 0xbd, 0xf, 0xe5, 0xe2, 0xbf, 0xa0, 0xfc, 0xd8, 0x23, 0x8a, 0x28, 0x32, 0xe3, 0x33, 0xe1, 0x4b, 0xc0, 0x7e, 0xa6, 0xff, 0x87, 0xcf, 0xb, 0x94, 0xb9, 0x37, 0x3c, 0xc6, 0xd8, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tooltip_bg_png[] = {
diff --git a/scene/resources/default_theme/toggle_off_disabled.png b/scene/resources/default_theme/toggle_off_disabled.png
index d65a9d8e64..250cd29b66 100644
--- a/scene/resources/default_theme/toggle_off_disabled.png
+++ b/scene/resources/default_theme/toggle_off_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/toggle_on_disabled.png b/scene/resources/default_theme/toggle_on_disabled.png
index ca4dbe211f..b1dacbaf32 100644
--- a/scene/resources/default_theme/toggle_on_disabled.png
+++ b/scene/resources/default_theme/toggle_on_disabled.png
Binary files differ
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 8ee9879055..2364a4a8a3 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -118,8 +118,7 @@ Error DynamicFontAtSize::_load() {
int error = FT_Init_FreeType(&library);
- ERR_EXPLAIN(TTR("Error initializing FreeType."));
- ERR_FAIL_COND_V(error != 0, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType.");
// FT_OPEN_STREAM is extremely slow only on Android.
if (OS::get_singleton()->get_name() == "Android" && font->font_mem == NULL && font->font_path != String()) {
@@ -177,32 +176,23 @@ Error DynamicFontAtSize::_load() {
error = FT_Open_Face(library, &fargs, 0, &face);
} else {
- ERR_EXPLAIN("DynamicFont uninitialized");
- ERR_FAIL_V(ERR_UNCONFIGURED);
+ ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "DynamicFont uninitialized.");
}
//error = FT_New_Face( library, src_path.utf8().get_data(),0,&face );
if (error == FT_Err_Unknown_File_Format) {
- ERR_EXPLAIN(TTR("Unknown font format."));
+ ERR_EXPLAIN("Unknown font format.");
FT_Done_FreeType(library);
} else if (error) {
- ERR_EXPLAIN(TTR("Error loading font."));
+ ERR_EXPLAIN("Error loading font.");
FT_Done_FreeType(library);
}
ERR_FAIL_COND_V(error, ERR_FILE_CANT_OPEN);
- /*error = FT_Set_Char_Size(face,0,64*size,512,512);
-
- if ( error ) {
- FT_Done_FreeType( library );
- ERR_EXPLAIN(TTR("Invalid font size."));
- ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER );
- }*/
-
if (FT_HAS_COLOR(face)) {
int best_match = 0;
int diff = ABS(id.size - ((int64_t)face->available_sizes[0].width));
@@ -494,7 +484,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
int byte = i * bitmap.pitch + (j >> 3);
int bit = 1 << (7 - (j % 8));
wr[ofs + 0] = 255; //grayscale as 1
- wr[ofs + 1] = bitmap.buffer[byte] & bit ? 255 : 0;
+ wr[ofs + 1] = (bitmap.buffer[byte] & bit) ? 255 : 0;
} break;
case FT_PIXEL_MODE_GRAY:
wr[ofs + 0] = 255; //grayscale as 1
@@ -509,8 +499,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
} break;
// TODO: FT_PIXEL_MODE_LCD
default:
- ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(bitmap.pixel_mode));
- ERR_FAIL_V(Character::not_found());
+ ERR_FAIL_V_MSG(Character::not_found(), "Font uses unsupported pixel format: " + itos(bitmap.pixel_mode) + ".");
break;
}
}
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 7c3867beaa..afb7f1102b 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1047,8 +1047,8 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_min", "get_fog_height_min");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_max", "get_fog_height_max");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve");
ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
@@ -1399,15 +1399,15 @@ Environment::Environment() :
fog_depth_enabled = true;
fog_depth_begin = 10;
- fog_depth_end = 0;
+ fog_depth_end = 100;
fog_depth_curve = 1;
fog_transmit_enabled = false;
fog_transmit_curve = 1;
fog_height_enabled = false;
- fog_height_min = 0;
- fog_height_max = 100;
+ fog_height_min = 10;
+ fog_height_max = 0;
fog_height_curve = 1;
set_fog_color(Color(0.5, 0.6, 0.7));
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 627397f0ab..cff77acdd7 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -133,6 +133,7 @@ PoolVector<int> BitmapFont::_get_chars() const {
while ((key = char_map.next(key))) {
const Character *c = char_map.getptr(*key);
+ ERR_FAIL_COND_V(!c, PoolVector<int>());
chars.push_back(*key);
chars.push_back(c->texture_idx);
chars.push_back(c->rect.position.x);
@@ -201,10 +202,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
FileAccess *f = FileAccess::open(p_file, FileAccess::READ);
- if (!f) {
- ERR_EXPLAIN("Can't open font: " + p_file);
- ERR_FAIL_V(ERR_FILE_NOT_FOUND);
- }
+ ERR_FAIL_COND_V_MSG(!f, ERR_FILE_NOT_FOUND, "Can't open font: " + p_file + ".");
clear();
@@ -531,10 +529,7 @@ Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) cons
void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) {
for (Ref<BitmapFont> fallback_child = p_fallback; fallback_child != NULL; fallback_child = fallback_child->get_fallback()) {
- if (fallback_child == this) {
- ERR_EXPLAIN("Can't set as fallback one of its parents to prevent crashes due to recursive loop.");
- ERR_FAIL_COND(fallback_child == this);
- }
+ ERR_FAIL_COND_MSG(fallback_child == this, "Can't set as fallback one of its parents to prevent crashes due to recursive loop.");
}
fallback = p_fallback;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 436ed43c42..9b99b85d22 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -34,9 +34,6 @@
#include "core/map.h"
#include "core/resource.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Font : public Resource {
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 197ff14b38..0de462d616 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -39,10 +39,7 @@
void Material::set_next_pass(const Ref<Material> &p_pass) {
for (Ref<Material> pass_child = p_pass; pass_child != NULL; pass_child = pass_child->get_next_pass()) {
- if (pass_child == this) {
- ERR_EXPLAIN("Can't set as next_pass one of its parents to prevent crashes due to recursive loop.");
- ERR_FAIL_COND(pass_child == this);
- }
+ ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop.");
}
if (next_pass == p_pass)
@@ -691,9 +688,9 @@ void SpatialMaterial::_update_shader() {
code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n";
code += "\tTANGENT = normalize(TANGENT);\n";
- code += "\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n";
- code += "\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n";
- code += "\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n";
+ code += "\tBINORMAL = vec3(0.0,-1.0,0.0) * abs(NORMAL.x);\n";
+ code += "\tBINORMAL+= vec3(0.0,0.0,1.0) * abs(NORMAL.y);\n";
+ code += "\tBINORMAL+= vec3(0.0,-1.0,0.0) * abs(NORMAL.z);\n";
code += "\tBINORMAL = normalize(BINORMAL);\n";
}
@@ -1775,7 +1772,7 @@ SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel(
return refraction_texture_channel;
}
-RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass) {
+RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
int version = 0;
if (p_shaded)
@@ -1788,6 +1785,10 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
version |= 8;
if (p_double_sided)
version |= 16;
+ if (p_billboard)
+ version |= 32;
+ if (p_billboard_y)
+ version |= 64;
if (materials_for_2d[version].is_valid()) {
return materials_for_2d[version]->get_rid();
@@ -1803,6 +1804,11 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent,
material->set_flag(FLAG_SRGB_VERTEX_COLOR, true);
material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha);
+ if (p_billboard) {
+ material->set_billboard_mode(BILLBOARD_ENABLED);
+ } else if (p_billboard_y) {
+ material->set_billboard_mode(BILLBOARD_FIXED_Y);
+ }
materials_for_2d[version] = material;
@@ -2353,8 +2359,8 @@ SpatialMaterial::SpatialMaterial() :
set_ao_light_affect(0.0);
- set_metallic_texture_channel(TEXTURE_CHANNEL_BLUE);
- set_roughness_texture_channel(TEXTURE_CHANNEL_GREEN);
+ set_metallic_texture_channel(TEXTURE_CHANNEL_RED);
+ set_roughness_texture_channel(TEXTURE_CHANNEL_RED);
set_ao_texture_channel(TEXTURE_CHANNEL_RED);
set_refraction_texture_channel(TEXTURE_CHANNEL_RED);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 17e52527b3..2423d6d48b 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -37,9 +37,6 @@
#include "scene/resources/texture.h"
#include "servers/visual/shader_language.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Material : public Resource {
@@ -440,9 +437,7 @@ private:
_FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const;
- enum {
- MAX_MATERIALS_FOR_2D = 32
- };
+ static const int MAX_MATERIALS_FOR_2D = 128;
static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff
@@ -629,7 +624,7 @@ public:
static void finish_shaders();
static void flush_changes();
- static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass);
+ static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false);
RID get_shader_rid() const;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index aff274cd21..4afb07cb6f 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -883,10 +883,7 @@ int ArrayMesh::get_surface_count() const {
void ArrayMesh::add_blend_shape(const StringName &p_name) {
- if (surfaces.size()) {
- ERR_EXPLAIN("Can't add a shape key count if surfaces are already created.");
- ERR_FAIL_COND(surfaces.size());
- }
+ ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created.");
StringName name = p_name;
@@ -914,10 +911,7 @@ StringName ArrayMesh::get_blend_shape_name(int p_index) const {
}
void ArrayMesh::clear_blend_shapes() {
- if (surfaces.size()) {
- ERR_EXPLAIN("Can't set shape key count if surfaces are already created.");
- ERR_FAIL_COND(surfaces.size());
- }
+ ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
blend_shapes.clear();
}
@@ -1109,8 +1103,7 @@ struct ArrayMeshLightmapSurface {
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
- ERR_EXPLAIN("Can't unwrap mesh with blend shapes");
- ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes.");
Vector<float> vertices;
Vector<float> normals;
@@ -1124,15 +1117,9 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
ArrayMeshLightmapSurface s;
s.primitive = surface_get_primitive_type(i);
- if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) {
- ERR_EXPLAIN("Only triangles are supported for lightmap unwrap");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(s.primitive != Mesh::PRIMITIVE_TRIANGLES, ERR_UNAVAILABLE, "Only triangles are supported for lightmap unwrap.");
s.format = surface_get_format(i);
- if (!(s.format & ARRAY_FORMAT_NORMAL)) {
- ERR_EXPLAIN("Normals are required for lightmap unwrap");
- ERR_FAIL_V(ERR_UNAVAILABLE);
- }
+ ERR_FAIL_COND_V_MSG(!(s.format & ARRAY_FORMAT_NORMAL), ERR_UNAVAILABLE, "Normals are required for lightmap unwrap.");
Array arrays = surface_get_arrays(i);
s.material = surface_get_material(i);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b38791b9a6..6b6ee8a209 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -37,9 +37,6 @@
#include "scene/resources/material.h"
#include "scene/resources/shape.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Mesh : public Resource {
GDCLASS(Mesh, Resource);
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 7cd765fb5d..0c39c3cbb1 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -165,11 +165,12 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
e.vertex[0] = edge.x;
e.vertex[1] = edge.y;
edges.push_back(e);
+ v[j]->edges.push_back(face.edges[j]);
+ v[(j + 1) % 3]->edges.push_back(face.edges[j]);
}
edges.write[face.edges[j]].faces.push_back(fidx);
v[j]->faces.push_back(fidx);
- v[j]->edges.push_back(face.edges[j]);
}
faces.push_back(face);
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 99286668ce..7d62873bbd 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -92,8 +92,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (i > 0) {
- ERR_EXPLAIN(vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name]));
- ERR_FAIL_COND_V(n.parent == -1, NULL);
+ ERR_FAIL_COND_V_MSG(n.parent == -1, NULL, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name]));
NODE_FROM_ID(nparent, n.parent);
#ifdef DEBUG_ENABLED
if (!nparent && (n.parent & FLAG_ID_IS_PATH)) {
@@ -1093,10 +1092,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
if (p_dictionary.has("version"))
version = p_dictionary["version"];
- if (version > PACK_VERSION) {
- ERR_EXPLAIN("Save format version too new!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(version > PACK_VERSION, "Save format version too new.");
PoolVector<String> snames = p_dictionary["names"];
if (snames.size()) {
@@ -1690,10 +1686,7 @@ bool PackedScene::can_instance() const {
Node *PackedScene::instance(GenEditState p_edit_state) const {
#ifndef TOOLS_ENABLED
- if (p_edit_state != GEN_EDIT_STATE_DISABLED) {
- ERR_EXPLAIN("Edit state is only for editors, does not work without tools compiled");
- ERR_FAIL_COND_V(p_edit_state != GEN_EDIT_STATE_DISABLED, NULL);
- }
+ ERR_FAIL_COND_V_MSG(p_edit_state != GEN_EDIT_STATE_DISABLED, NULL, "Edit state is only for editors, does not work without tools compiled.");
#endif
Node *s = state->instance((SceneState::GenEditState)p_edit_state);
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index b4818755b4..dc6ef2b49c 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -101,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() {
@@ -173,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: {
@@ -285,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";
@@ -325,6 +332,7 @@ void ParticlesMaterial::_update_shader() {
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) {
@@ -576,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";
@@ -1014,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());
@@ -1118,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");
@@ -1240,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 7f11bd794b..6fe381db0a 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -185,6 +185,8 @@ private:
StringName trail_color_modifier;
StringName gravity;
+
+ StringName lifetime_randomness;
};
static ShaderNames *shader_names;
@@ -225,6 +227,8 @@ private:
Vector3 gravity;
+ float lifetime_randomness;
+
//do not save emission points here
protected:
@@ -287,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/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 74a493d3b5..24fdaafbe1 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -1572,3 +1572,19 @@ SphereMesh::SphereMesh() {
rings = 32;
is_hemisphere = false;
}
+
+/**
+ PointMesh
+*/
+
+void PointMesh::_create_mesh_array(Array &p_arr) const {
+ PoolVector<Vector3> faces;
+ faces.resize(1);
+ faces.set(0, Vector3(0.0, 0.0, 0.0));
+
+ p_arr[VS::ARRAY_VERTEX] = faces;
+}
+
+PointMesh::PointMesh() {
+ primitive_type = PRIMITIVE_POINTS;
+}
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 312899c028..fad49f9642 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -322,4 +322,19 @@ public:
SphereMesh();
};
+/**
+ A single point for use in particle systems
+*/
+
+class PointMesh : public PrimitiveMesh {
+
+ GDCLASS(PointMesh, PrimitiveMesh)
+
+protected:
+ virtual void _create_mesh_array(Array &p_arr) const;
+
+public:
+ PointMesh();
+};
+
#endif
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 12bf007bb1..1c41f30a94 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -1366,13 +1366,10 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
String path = relative_paths ? local_path.path_to_file(res->get_path()) : res->get_path();
return "Resource( \"" + path + "\" )";
} else {
- ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
- ERR_FAIL_V("null");
+ ERR_FAIL_V_MSG("null", "Resource was not pre cached for the resource section, bug?");
//internal resource
}
}
-
- return "null";
}
void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, bool p_main) {
@@ -1514,8 +1511,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
}
- ERR_FAIL_COND_V(err != OK, err);
-
{
String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource ";
if (packed_scene.is_null())
@@ -1718,6 +1713,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
if (groups.size()) {
+ groups.sort_custom<StringName::AlphCompare>();
String sgroups = " groups=[\n";
for (int j = 0; j < groups.size(); j++) {
sgroups += "\"" + String(groups[j]).c_escape() + "\",\n";
diff --git a/scene/resources/room.h b/scene/resources/room.h
index 8990056f46..2c53ea1aed 100644
--- a/scene/resources/room.h
+++ b/scene/resources/room.h
@@ -33,9 +33,6 @@
#include "core/math/bsp_tree.h"
#include "core/resource.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
// FIXME: left for reference but will be removed when portals are reimplemented using Area
#if 0
diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp
new file mode 100644
index 0000000000..8446e2f249
--- /dev/null
+++ b/scene/resources/skin.cpp
@@ -0,0 +1,102 @@
+#include "skin.h"
+
+void Skin::set_bind_count(int p_size) {
+ ERR_FAIL_COND(p_size < 0);
+ binds.resize(p_size);
+ binds_ptr = binds.ptrw();
+ bind_count = p_size;
+ emit_changed();
+}
+
+void Skin::add_bind(int p_bone, const Transform &p_pose) {
+ uint32_t index = bind_count;
+ set_bind_count(bind_count + 1);
+ set_bind_bone(index, p_bone);
+ set_bind_pose(index, p_pose);
+}
+
+void Skin::set_bind_bone(int p_index, int p_bone) {
+ ERR_FAIL_INDEX(p_index, bind_count);
+ binds_ptr[p_index].bone = p_bone;
+ emit_changed();
+}
+
+void Skin::set_bind_pose(int p_index, const Transform &p_pose) {
+ ERR_FAIL_INDEX(p_index, bind_count);
+ binds_ptr[p_index].pose = p_pose;
+ emit_changed();
+}
+
+void Skin::clear_binds() {
+ binds.clear();
+ binds_ptr = nullptr;
+ bind_count = 0;
+ emit_changed();
+}
+
+bool Skin::_set(const StringName &p_name, const Variant &p_value) {
+ String name = p_name;
+ if (name == "bind_count") {
+ set_bind_count(p_value);
+ return true;
+ } else if (name.begins_with("bind/")) {
+ int index = name.get_slicec('/', 1).to_int();
+ String what = name.get_slicec('/', 2);
+ if (what == "bone") {
+ set_bind_bone(index, p_value);
+ return true;
+ } else if (what == "pose") {
+ set_bind_pose(index, p_value);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
+
+ String name = p_name;
+ if (name == "bind_count") {
+ r_ret = get_bind_count();
+ return true;
+ } else if (name.begins_with("bind/")) {
+ int index = name.get_slicec('/', 1).to_int();
+ String what = name.get_slicec('/', 2);
+ if (what == "bone") {
+ r_ret = get_bind_bone(index);
+ return true;
+ } else if (what == "pose") {
+ r_ret = get_bind_pose(index);
+ return true;
+ }
+ }
+ return false;
+}
+void Skin::_get_property_list(List<PropertyInfo> *p_list) const {
+ p_list->push_back(PropertyInfo(Variant::INT, "bind_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"));
+ for (int i = 0; i < get_bind_count(); i++) {
+ p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"));
+ p_list->push_back(PropertyInfo(Variant::TRANSFORM, "bind/" + itos(i) + "/pose"));
+ }
+}
+
+void Skin::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_bind_count", "bind_count"), &Skin::set_bind_count);
+ ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count);
+
+ ClassDB::bind_method(D_METHOD("add_bind", "bone", "pose"), &Skin::add_bind);
+
+ ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose);
+ ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose);
+
+ ClassDB::bind_method(D_METHOD("set_bind_bone", "bind_index", "bone"), &Skin::set_bind_bone);
+ ClassDB::bind_method(D_METHOD("get_bind_bone", "bind_index"), &Skin::get_bind_bone);
+
+ ClassDB::bind_method(D_METHOD("clear_binds"), &Skin::clear_binds);
+}
+
+Skin::Skin() {
+ bind_count = 0;
+ binds_ptr = nullptr;
+}
diff --git a/scene/resources/skin.h b/scene/resources/skin.h
new file mode 100644
index 0000000000..a7e55bfa89
--- /dev/null
+++ b/scene/resources/skin.h
@@ -0,0 +1,54 @@
+#ifndef SKIN_H
+#define SKIN_H
+
+#include "core/resource.h"
+
+class Skin : public Resource {
+ GDCLASS(Skin, Resource)
+
+ struct Bind {
+ int bone;
+ Transform pose;
+ };
+
+ Vector<Bind> binds;
+
+ Bind *binds_ptr;
+ int bind_count;
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ static void _bind_methods();
+
+public:
+ void set_bind_count(int p_size);
+ inline int get_bind_count() const { return bind_count; }
+
+ void add_bind(int p_bone, const Transform &p_pose);
+
+ void set_bind_bone(int p_index, int p_bone);
+ void set_bind_pose(int p_index, const Transform &p_pose);
+
+ inline int get_bind_bone(int p_index) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(p_index, bind_count, -1);
+#endif
+ return binds_ptr[p_index].bone;
+ }
+
+ inline Transform get_bind_pose(int p_index) const {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(p_index, bind_count, Transform());
+#endif
+ return binds_ptr[p_index].pose;
+ }
+
+ void clear_binds();
+
+ Skin();
+};
+
+#endif // SKIN_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 5dd429fa75..4453032f67 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -713,6 +713,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
Vector<Point2> verts;
Vector<int> indices;
Vector<Color> colors;
+ Vector<Point2> uvs;
//DRAW SHADOW
if (draw_shadow) {
@@ -799,9 +800,17 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
}
}
+ //COMPUTE UV COORDINATES
+ Rect2 uv_rect = style_rect.grow(aa_on ? aa_size : 0);
+ uvs.resize(verts.size());
+ for (int i = 0; i < verts.size(); i++) {
+ uvs.write[i].x = (verts[i].x - uv_rect.position.x) / uv_rect.size.width;
+ uvs.write[i].y = (verts[i].y - uv_rect.position.y) / uv_rect.size.height;
+ }
+
//DRAWING
VisualServer *vs = VisualServer::get_singleton();
- vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors);
+ vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors, uvs);
}
float StyleBoxFlat::get_style_margin(Margin p_margin) const {
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index c3965fe076..d02e107480 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -34,9 +34,7 @@
#include "core/resource.h"
#include "scene/resources/texture.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class CanvasItem;
class StyleBox : public Resource {
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index 37bdd691b4..b84f3f1f9e 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -67,10 +67,7 @@ Error TextFile::load_text(const String &p_path) {
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w.ptr())) {
- ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
- ERR_FAIL_V(ERR_INVALID_DATA);
- }
+ ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w.ptr()), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
text = s;
path = p_path;
return OK;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index a5e9351753..e44b17584b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2351,8 +2351,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
texarr.instance();
lt = texarr;
} else {
- ERR_EXPLAIN("Unrecognized layered texture extension");
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension.");
}
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
@@ -2373,8 +2372,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String
}
} else {
- ERR_EXPLAIN("Unrecognized layered texture file format: " + String((const char *)header));
- ERR_FAIL_V(RES());
+ ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture file format: " + String((const char *)header) + ".");
}
int tw = f->get_32();
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index eb7a9ff25c..e535f7544a 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -42,10 +42,6 @@
#include "servers/camera_server.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class Texture : public Resource {
GDCLASS(Texture, Resource);
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 69258bc834..ae18be1695 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -32,8 +32,6 @@
#include "core/os/file_access.h"
#include "core/print_string.h"
-Ref<Theme> Theme::default_theme;
-
void Theme::_emit_theme_changed() {
emit_changed();
@@ -186,11 +184,6 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-Ref<Theme> Theme::get_default() {
-
- return default_theme;
-}
-
void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
if (default_theme_font == p_default_font)
@@ -215,14 +208,31 @@ Ref<Font> Theme::get_default_theme_font() const {
return default_theme_font;
}
+Ref<Theme> Theme::project_default_theme;
+Ref<Theme> Theme::default_theme;
+Ref<Texture> Theme::default_icon;
+Ref<StyleBox> Theme::default_style;
+Ref<Font> Theme::default_font;
+
+Ref<Theme> Theme::get_default() {
+
+ return default_theme;
+}
+
void Theme::set_default(const Ref<Theme> &p_default) {
default_theme = p_default;
}
-Ref<Texture> Theme::default_icon;
-Ref<StyleBox> Theme::default_style;
-Ref<Font> Theme::default_font;
+Ref<Theme> Theme::get_project_default() {
+
+ return project_default_theme;
+}
+
+void Theme::set_project_default(const Ref<Theme> &p_project_default) {
+
+ project_default_theme = p_project_default;
+}
void Theme::set_default_icon(const Ref<Texture> &p_icon) {
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index fb59073cbe..187694de65 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -38,15 +38,11 @@
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Theme : public Resource {
GDCLASS(Theme, Resource);
RES_BASE_EXTENSION("theme");
- static Ref<Theme> default_theme;
void _emit_theme_changed();
HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
@@ -61,6 +57,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ static Ref<Theme> project_default_theme;
+ static Ref<Theme> default_theme;
static Ref<Texture> default_icon;
static Ref<StyleBox> default_style;
static Ref<Font> default_font;
@@ -137,6 +135,9 @@ public:
static Ref<Theme> get_default();
static void set_default(const Ref<Theme> &p_default);
+ static Ref<Theme> get_project_default();
+ static void set_project_default(const Ref<Theme> &p_project_default);
+
static void set_default_icon(const Ref<Texture> &p_icon);
static void set_default_style(const Ref<StyleBox> &p_style);
static void set_default_font(const Ref<Font> &p_font);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index bd5ce91e77..24122a8d99 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -148,15 +148,20 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
}
}
} else if (what == "shape")
- tile_set_shape(id, 0, p_value);
+ for (int i = 0; i < tile_get_shape_count(id); i++)
+ tile_set_shape(id, i, p_value);
else if (what == "shape_offset")
- tile_set_shape_offset(id, 0, p_value);
+ for (int i = 0; i < tile_get_shape_count(id); i++)
+ tile_set_shape_offset(id, i, p_value);
else if (what == "shape_transform")
- tile_set_shape_transform(id, 0, p_value);
+ for (int i = 0; i < tile_get_shape_count(id); i++)
+ tile_set_shape_transform(id, i, p_value);
else if (what == "shape_one_way")
- tile_set_shape_one_way(id, 0, p_value);
+ for (int i = 0; i < tile_get_shape_count(id); i++)
+ tile_set_shape_one_way(id, i, p_value);
else if (what == "shape_one_way_margin")
- tile_set_shape_one_way_margin(id, 0, p_value);
+ for (int i = 0; i < tile_get_shape_count(id); i++)
+ tile_set_shape_one_way_margin(id, i, p_value);
else if (what == "shapes")
_tile_set_shapes(id, p_value);
else if (what == "occluder")
@@ -1001,8 +1006,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
s.autotile_coord = default_autotile_coord;
} else {
- ERR_EXPLAIN("Expected an array of objects or dictionaries for tile_set_shapes");
- ERR_CONTINUE(true);
+ ERR_CONTINUE_MSG(true, "Expected an array of objects or dictionaries for tile_set_shapes.");
}
shapes_data.push_back(s);
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 7265c9b457..f5ea6adc85 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>();
}
@@ -109,6 +117,12 @@ void VisualShaderNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values");
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
+
+ BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN);
+ BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM);
+ BIND_ENUM_CONSTANT(PORT_TYPE_ICON_COLOR);
}
VisualShaderNode::VisualShaderNode() {
@@ -117,6 +131,147 @@ VisualShaderNode::VisualShaderNode() {
/////////////////////////////////////////////////////////
+void VisualShaderNodeCustom::update_ports() {
+ ERR_FAIL_COND(!get_script_instance());
+
+ input_ports.clear();
+ if (get_script_instance()->has_method("_get_input_port_count")) {
+ int input_port_count = (int)get_script_instance()->call("_get_input_port_count");
+ bool has_name = get_script_instance()->has_method("_get_input_port_name");
+ bool has_type = get_script_instance()->has_method("_get_input_port_type");
+ for (int i = 0; i < input_port_count; i++) {
+ Port port;
+ if (has_name) {
+ port.name = (String)get_script_instance()->call("_get_input_port_name", i);
+ } else {
+ port.name = "in" + itos(i);
+ }
+ if (has_type) {
+ port.type = (int)get_script_instance()->call("_get_input_port_type", i);
+ } else {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
+ input_ports.push_back(port);
+ }
+ }
+ output_ports.clear();
+ if (get_script_instance()->has_method("_get_output_port_count")) {
+ int output_port_count = (int)get_script_instance()->call("_get_output_port_count");
+ bool has_name = get_script_instance()->has_method("_get_output_port_name");
+ bool has_type = get_script_instance()->has_method("_get_output_port_type");
+ for (int i = 0; i < output_port_count; i++) {
+ Port port;
+ if (has_name) {
+ port.name = (String)get_script_instance()->call("_get_output_port_name", i);
+ } else {
+ port.name = "out" + itos(i);
+ }
+ if (has_type) {
+ port.type = (int)get_script_instance()->call("_get_output_port_type", i);
+ } else {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
+ output_ports.push_back(port);
+ }
+ }
+}
+
+String VisualShaderNodeCustom::get_caption() const {
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ if (get_script_instance()->has_method("_get_name")) {
+ return (String)get_script_instance()->call("_get_name");
+ }
+ return "Unnamed";
+}
+
+int VisualShaderNodeCustom::get_input_port_count() const {
+ return input_ports.size();
+}
+
+VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_input_port_type(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, input_ports.size(), PORT_TYPE_SCALAR);
+ return (PortType)input_ports[p_port].type;
+}
+
+String VisualShaderNodeCustom::get_input_port_name(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, input_ports.size(), "");
+ return input_ports[p_port].name;
+}
+
+int VisualShaderNodeCustom::get_output_port_count() const {
+ return output_ports.size();
+}
+
+VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_output_port_type(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, output_ports.size(), PORT_TYPE_SCALAR);
+ return (PortType)output_ports[p_port].type;
+}
+
+String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
+ ERR_FAIL_INDEX_V(p_port, output_ports.size(), "");
+ return output_ports[p_port].name;
+}
+
+String VisualShaderNodeCustom::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 {
+
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), "");
+ Array input_vars;
+ for (int i = 0; i < get_input_port_count(); i++) {
+ input_vars.push_back(p_input_vars[i]);
+ }
+ Array output_vars;
+ for (int i = 0; i < get_output_port_count(); i++) {
+ output_vars.push_back(p_output_vars[i]);
+ }
+ String code = "\t{\n";
+ String _code = (String)get_script_instance()->call("_get_code", input_vars, output_vars, (int)p_mode, (int)p_type);
+ bool nend = _code.ends_with("\n");
+ _code = _code.insert(0, "\t\t");
+ _code = _code.replace("\n", "\n\t\t");
+ code += _code;
+ if (!nend) {
+ code += "\n\t}";
+ } else {
+ code.remove(code.size() - 1);
+ code += "}";
+ }
+ return code;
+}
+
+String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ ERR_FAIL_COND_V(!get_script_instance(), "");
+ if (get_script_instance()->has_method("_get_global_code")) {
+ String code = "// " + get_caption() + "\n";
+ code += (String)get_script_instance()->call("_get_global_code", (int)p_mode);
+ code += "\n";
+ return code;
+ }
+ return "";
+}
+
+void VisualShaderNodeCustom::_bind_methods() {
+
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count"));
+ BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
+}
+
+VisualShaderNodeCustom::VisualShaderNodeCustom() {
+}
+
+/////////////////////////////////////////////////////////
+
void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) {
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_id < 2);
@@ -142,6 +297,11 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co
n.node->connect("changed", this, "_queue_update");
+ Ref<VisualShaderNodeCustom> custom = n.node;
+ if (custom.is_valid()) {
+ custom->update_ports();
+ }
+
g->nodes[p_id] = n;
_queue_update();
@@ -299,11 +459,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
- if (!is_port_types_compatible(from_port_type, to_port_type)) {
- ERR_EXPLAIN("Incompatible port types (scalar/vec/bool) with transform");
- ERR_FAIL_V(ERR_INVALID_PARAMETER);
- return ERR_INVALID_PARAMETER;
- }
+ ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform.");
for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
@@ -449,10 +605,32 @@ 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";
+ String global_expressions;
+ for (int i = 0, index = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
+ if (global_expression.is_valid()) {
+
+ String expr = "";
+ expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
+ expr += global_expression->generate_global(get_mode(), Type(i), -1);
+ expr = expr.replace("\n", "\n\t");
+ expr += "\n";
+ global_expressions += expr;
+ }
+ }
+ }
+
+ global_code += "\n";
+ global_code += global_expressions;
+
//make it faster to go around through shader
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
@@ -474,7 +652,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 +667,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 +1012,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 +1029,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;
}
@@ -904,7 +1083,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
} else if (defval.get_type() == Variant::BOOL) {
bool val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
- code += "\nbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
+ code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
} else if (defval.get_type() == Variant::VECTOR3) {
Vector3 val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
@@ -957,10 +1136,18 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
bool skip_global = input.is_valid() && for_preview;
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
code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview);
code += "\n"; //
@@ -976,8 +1163,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";
@@ -1033,6 +1224,22 @@ void VisualShader::_update_shader() const {
static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" };
+ String global_expressions;
+ for (int i = 0, index = 0; i < TYPE_MAX; i++) {
+ for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
+ Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
+ if (global_expression.is_valid()) {
+
+ String expr = "";
+ expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
+ expr += global_expression->generate_global(get_mode(), Type(i), -1);
+ expr = expr.replace("\n", "\n\t");
+ expr += "\n";
+ global_expressions += expr;
+ }
+ }
+ }
+
for (int i = 0; i < TYPE_MAX; i++) {
//make it faster to go around through shader
@@ -1056,8 +1263,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,11 +1273,22 @@ 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;
+ final_code += global_expressions;
+ 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);
}
+ if (previous_code != final_code) {
+ const_cast<VisualShader *>(this)->emit_signal("changed");
+ }
+ previous_code = final_code;
}
void VisualShader::_queue_update() {
@@ -1180,6 +1399,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
// Spatial, Fragment
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
@@ -1204,6 +1424,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" },
// Spatial, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
@@ -1225,6 +1447,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
// Canvas Item, Vertex
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
@@ -2154,6 +2377,14 @@ void VisualShaderNodeGroupBase::_apply_port_changes() {
}
}
+void VisualShaderNodeGroupBase::set_editable(bool p_enabled) {
+ editable = p_enabled;
+}
+
+bool VisualShaderNodeGroupBase::is_editable() const {
+ return editable;
+}
+
void VisualShaderNodeGroupBase::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size);
@@ -2189,6 +2420,11 @@ void VisualShaderNodeGroupBase::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_control", "control", "index"), &VisualShaderNodeGroupBase::set_control);
ClassDB::bind_method(D_METHOD("get_control", "index"), &VisualShaderNodeGroupBase::get_control);
+
+ ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &VisualShaderNodeGroupBase::set_editable);
+ ClassDB::bind_method(D_METHOD("is_editable"), &VisualShaderNodeGroupBase::is_editable);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
}
String VisualShaderNodeGroupBase::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 {
@@ -2199,6 +2435,7 @@ VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() {
size = Size2(0, 0);
inputs = "";
outputs = "";
+ editable = false;
}
////////////// Expression
@@ -2229,8 +2466,11 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
static Vector<String> pre_symbols;
if (pre_symbols.empty()) {
pre_symbols.push_back("\t");
+ pre_symbols.push_back(",");
+ pre_symbols.push_back(";");
pre_symbols.push_back("{");
pre_symbols.push_back("[");
+ pre_symbols.push_back("]");
pre_symbols.push_back("(");
pre_symbols.push_back(" ");
pre_symbols.push_back("-");
@@ -2245,11 +2485,12 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
static Vector<String> post_symbols;
if (post_symbols.empty()) {
- post_symbols.push_back("\0");
post_symbols.push_back("\t");
post_symbols.push_back("\n");
+ post_symbols.push_back(",");
post_symbols.push_back(";");
post_symbols.push_back("}");
+ post_symbols.push_back("[");
post_symbols.push_back("]");
post_symbols.push_back(")");
post_symbols.push_back(" ");
@@ -2324,4 +2565,19 @@ void VisualShaderNodeExpression::_bind_methods() {
VisualShaderNodeExpression::VisualShaderNodeExpression() {
expression = "";
+ set_editable(true);
+}
+
+////////////// Global Expression
+
+String VisualShaderNodeGlobalExpression::get_caption() const {
+ return "GlobalExpression";
+}
+
+String VisualShaderNodeGlobalExpression::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return expression;
+}
+
+VisualShaderNodeGlobalExpression::VisualShaderNodeGlobalExpression() {
+ set_editable(false);
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 83db51b1b0..45beb8e6ca 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -73,6 +73,7 @@ private:
} graph[TYPE_MAX];
Shader::Mode shader_mode;
+ mutable String previous_code;
Array _get_node_connections(Type p_type) const;
@@ -103,7 +104,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);
@@ -183,7 +184,7 @@ public:
PORT_TYPE_VECTOR,
PORT_TYPE_BOOLEAN,
PORT_TYPE_TRANSFORM,
- PORT_TYPE_COLOR // just a hint for node tree icons, do not use it as actual port type !
+ PORT_TYPE_ICON_COLOR // just a hint for node tree icons, do not use it as actual port type !
};
virtual String get_caption() const = 0;
@@ -208,12 +209,52 @@ 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;
VisualShaderNode();
};
+
+VARIANT_ENUM_CAST(VisualShaderNode::PortType)
+
+class VisualShaderNodeCustom : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeCustom, VisualShaderNode);
+
+ struct Port {
+ String name;
+ int type;
+ };
+
+ List<Port> input_ports;
+ List<Port> output_ports;
+
+ friend class VisualShaderEditor;
+
+protected:
+ 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;
+
+protected:
+ 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;
+ virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+
+ static void _bind_methods();
+
+public:
+ VisualShaderNodeCustom();
+ void update_ports();
+};
+
/////
class VisualShaderNodeInput : public VisualShaderNode {
@@ -331,6 +372,7 @@ protected:
Vector2 size;
String inputs;
String outputs;
+ bool editable;
struct Port {
PortType type;
@@ -386,6 +428,9 @@ public:
void set_control(Control *p_control, int p_index);
Control *get_control(int p_index);
+ void set_editable(bool p_enabled);
+ bool is_editable() 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;
VisualShaderNodeGroupBase();
@@ -394,10 +439,9 @@ public:
class VisualShaderNodeExpression : public VisualShaderNodeGroupBase {
GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase);
-private:
+protected:
String expression;
-protected:
static void _bind_methods();
public:
@@ -413,4 +457,15 @@ public:
VisualShaderNodeExpression();
};
+class VisualShaderNodeGlobalExpression : public VisualShaderNodeExpression {
+ GDCLASS(VisualShaderNodeGlobalExpression, VisualShaderNodeExpression);
+
+public:
+ virtual String get_caption() const;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
+
+ VisualShaderNodeGlobalExpression();
+};
+
#endif // VISUAL_SHADER_H
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 746edc65b0..b7173b157e 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "visual_shader_nodes.h"
+
////////////// Scalar
String VisualShaderNodeScalarConstant::get_caption() const {
@@ -38,9 +39,11 @@ String VisualShaderNodeScalarConstant::get_caption() const {
int VisualShaderNodeScalarConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -48,9 +51,11 @@ String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarConstant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -158,9 +163,11 @@ String VisualShaderNodeColorConstant::get_caption() const {
int VisualShaderNodeColorConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -168,9 +175,11 @@ String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
int VisualShaderNodeColorConstant::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port
}
@@ -222,9 +231,11 @@ String VisualShaderNodeVec3Constant::get_caption() const {
int VisualShaderNodeVec3Constant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
return String();
}
@@ -232,9 +243,11 @@ String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
int VisualShaderNodeVec3Constant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -280,9 +293,11 @@ String VisualShaderNodeTransformConstant::get_caption() const {
int VisualShaderNodeTransformConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -290,9 +305,11 @@ String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const
int VisualShaderNodeTransformConstant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -346,9 +363,11 @@ String VisualShaderNodeTexture::get_caption() const {
int VisualShaderNodeTexture::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -356,11 +375,13 @@ String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
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";
@@ -632,9 +653,11 @@ String VisualShaderNodeCubeMap::get_caption() const {
int VisualShaderNodeCubeMap::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -642,9 +665,11 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
int VisualShaderNodeCubeMap::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
@@ -735,6 +760,7 @@ void VisualShaderNodeCubeMap::_bind_methods() {
VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
texture_type = TYPE_DATA;
}
+
////////////// Scalar Op
String VisualShaderNodeScalarOp::get_caption() const {
@@ -744,9 +770,11 @@ String VisualShaderNodeScalarOp::get_caption() const {
int VisualShaderNodeScalarOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -754,9 +782,11 @@ String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -832,9 +862,11 @@ String VisualShaderNodeVectorOp::get_caption() const {
int VisualShaderNodeVectorOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -842,9 +874,11 @@ String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -924,9 +958,11 @@ String VisualShaderNodeColorOp::get_caption() const {
int VisualShaderNodeColorOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -934,9 +970,11 @@ String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
int VisualShaderNodeColorOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -1072,9 +1110,11 @@ String VisualShaderNodeTransformMult::get_caption() const {
int VisualShaderNodeTransformMult::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1082,9 +1122,11 @@ String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformMult::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const {
return "mult"; //no output port means the editor will be used as port
}
@@ -1147,9 +1189,11 @@ String VisualShaderNodeTransformVecMult::get_caption() const {
int VisualShaderNodeTransformVecMult::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1157,9 +1201,11 @@ String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformVecMult::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1221,9 +1267,11 @@ String VisualShaderNodeScalarFunc::get_caption() const {
int VisualShaderNodeScalarFunc::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
return "";
}
@@ -1231,9 +1279,11 @@ String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarFunc::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1350,9 +1400,11 @@ String VisualShaderNodeVectorFunc::get_caption() const {
int VisualShaderNodeVectorFunc::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
return "";
}
@@ -1360,9 +1412,11 @@ String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorFunc::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1675,9 +1729,11 @@ String VisualShaderNodeDotProduct::get_caption() const {
int VisualShaderNodeDotProduct::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1685,9 +1741,11 @@ String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
int VisualShaderNodeDotProduct::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const {
return "dot";
}
@@ -1710,9 +1768,11 @@ String VisualShaderNodeVectorLen::get_caption() const {
int VisualShaderNodeVectorLen::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
return "";
}
@@ -1720,9 +1780,11 @@ String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorLen::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const {
return "length";
}
@@ -1745,7 +1807,7 @@ int VisualShaderNodeDeterminant::get_input_port_count() const {
return 1;
}
-VisualShaderNodeScalarClamp::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const {
+VisualShaderNodeDeterminant::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
@@ -1872,7 +1934,7 @@ int VisualShaderNodeVectorDerivativeFunc::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2078,7 +2140,7 @@ int VisualShaderNodeOuterProduct::get_input_port_count() const {
return 2;
}
-VisualShaderNodeFaceForward::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const {
+VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2106,7 +2168,7 @@ String VisualShaderNodeOuterProduct::get_output_port_name(int p_port) const {
}
String VisualShaderNodeOuterProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = outerProduct( " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n";
+ return "\t" + p_output_vars[0] + " = outerProduct( vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0) );\n";
}
VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() {
@@ -2143,7 +2205,7 @@ int VisualShaderNodeVectorScalarStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2234,7 +2296,7 @@ int VisualShaderNodeVectorSmoothStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2285,7 +2347,7 @@ int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2399,34 +2461,38 @@ VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() {
set_input_port_default_value(2, 0.0);
}
-////////////// Scalar Interp
+////////////// Scalar Mix
String VisualShaderNodeScalarInterp::get_caption() const {
- return "Mix";
+ return "ScalarMix";
}
int VisualShaderNodeScalarInterp::get_input_port_count() const {
return 3;
}
+
VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "a";
} else if (p_port == 1) {
return "b";
} else {
- return "c";
+ return "weight";
}
}
int VisualShaderNodeScalarInterp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const {
return "mix";
}
@@ -2437,38 +2503,42 @@ String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualSh
VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() {
set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 0.0);
+ set_input_port_default_value(1, 1.0);
+ set_input_port_default_value(2, 0.5);
}
-////////////// Vector Interp
+////////////// Vector Mix
String VisualShaderNodeVectorInterp::get_caption() const {
- return "Mix";
+ return "VectorMix";
}
int VisualShaderNodeVectorInterp::get_input_port_count() const {
return 3;
}
+
VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "a";
} else if (p_port == 1) {
return "b";
} else {
- return "c";
+ return "weight";
}
}
int VisualShaderNodeVectorInterp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const {
return "mix";
}
@@ -2478,12 +2548,61 @@ String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualSh
}
VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() {
- set_input_port_default_value(0, Vector3());
- set_input_port_default_value(1, Vector3());
- set_input_port_default_value(2, Vector3());
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
+ set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5));
+}
+
+////////////// Vector Mix (by scalar)
+
+String VisualShaderNodeVectorScalarMix::get_caption() const {
+ return "VectorScalarMix";
+}
+
+int VisualShaderNodeVectorScalarMix::get_input_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const {
+ if (p_port == 2)
+ return PORT_TYPE_SCALAR;
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeVectorScalarMix::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "a";
+ } else if (p_port == 1) {
+ return "b";
+ } else {
+ return "weight";
+ }
+}
+
+int VisualShaderNodeVectorScalarMix::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const {
+ return "mix";
+}
+
+String VisualShaderNodeVectorScalarMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n";
+}
+
+VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() {
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
+ set_input_port_default_value(2, 0.5);
}
////////////// Vector Compose
+
String VisualShaderNodeVectorCompose::get_caption() const {
return "VectorCompose";
}
@@ -2491,9 +2610,11 @@ String VisualShaderNodeVectorCompose::get_caption() const {
int VisualShaderNodeVectorCompose::get_input_port_count() const {
return 3;
}
+
VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2507,9 +2628,11 @@ String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorCompose::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
return "vec";
}
@@ -2534,9 +2657,11 @@ String VisualShaderNodeTransformCompose::get_caption() const {
int VisualShaderNodeTransformCompose::get_input_port_count() const {
return 4;
}
+
VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2552,9 +2677,11 @@ String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformCompose::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const {
return "xform";
}
@@ -2579,9 +2706,11 @@ String VisualShaderNodeVectorDecompose::get_caption() const {
int VisualShaderNodeVectorDecompose::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
return "vec";
}
@@ -2589,9 +2718,11 @@ String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorDecompose::get_output_port_count() const {
return 3;
}
+
VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2623,9 +2754,11 @@ String VisualShaderNodeTransformDecompose::get_caption() const {
int VisualShaderNodeTransformDecompose::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const {
return "xform";
}
@@ -2633,9 +2766,11 @@ String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const
int VisualShaderNodeTransformDecompose::get_output_port_count() const {
return 4;
}
+
VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2670,9 +2805,11 @@ String VisualShaderNodeScalarUniform::get_caption() const {
int VisualShaderNodeScalarUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2680,9 +2817,11 @@ String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarUniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -2690,6 +2829,7 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform float " + get_uniform_name() + ";\n";
}
+
String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
@@ -2747,9 +2887,11 @@ String VisualShaderNodeColorUniform::get_caption() const {
int VisualShaderNodeColorUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2757,9 +2899,11 @@ String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeColorUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "color" : "alpha"; //no output port means the editor will be used as port
}
@@ -2787,9 +2931,11 @@ String VisualShaderNodeVec3Uniform::get_caption() const {
int VisualShaderNodeVec3Uniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2797,12 +2943,15 @@ String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const {
int VisualShaderNodeVec3Uniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+
String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform vec3 " + get_uniform_name() + ";\n";
}
@@ -2823,9 +2972,11 @@ String VisualShaderNodeTransformUniform::get_caption() const {
int VisualShaderNodeTransformUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2833,12 +2984,15 @@ String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformUniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+
String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform mat4 " + get_uniform_name() + ";\n";
}
@@ -2859,9 +3013,11 @@ String VisualShaderNodeTextureUniform::get_caption() const {
int VisualShaderNodeTextureUniform::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -2869,9 +3025,11 @@ String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeTextureUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
@@ -2933,6 +3091,7 @@ void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_default) {
color_default = p_default;
emit_changed();
}
+
VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const {
return color_default;
}
@@ -2968,6 +3127,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 {
@@ -2977,9 +3228,11 @@ String VisualShaderNodeCubeMapUniform::get_caption() const {
int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
return p_port == 0 ? "normal" : "lod";
}
@@ -2987,9 +3240,11 @@ String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeCubeMapUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
@@ -3079,7 +3334,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() {
////////////// Switch
String VisualShaderNodeSwitch::get_caption() const {
- return "Switch";
+ return "VectorSwitch";
}
int VisualShaderNodeSwitch::get_input_port_count() const {
@@ -3134,10 +3389,33 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::
VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
set_input_port_default_value(0, false);
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
}
+////////////// Switch(scalar)
+
+String VisualShaderNodeScalarSwitch::get_caption() const {
+ return "ScalarSwitch";
+}
+
+VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_input_port_type(int p_port) const {
+ if (p_port == 0) {
+ return PORT_TYPE_BOOLEAN;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+VisualShaderNodeScalarSwitch::VisualShaderNodeScalarSwitch() {
+ set_input_port_default_value(0, false);
+ set_input_port_default_value(1, 1.0);
+ set_input_port_default_value(2, 0.0);
+}
+
////////////// Fresnel
String VisualShaderNodeFresnel::get_caption() const {
@@ -3200,3 +3478,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 comparison 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 235714f697..0c6e060353 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1171,6 +1171,27 @@ public:
};
///////////////////////////////////////
+
+class VisualShaderNodeVectorScalarMix : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode);
+
+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
+
+ VisualShaderNodeVectorScalarMix();
+};
+
+///////////////////////////////////////
/// COMPOSE
///////////////////////////////////////
@@ -1425,6 +1446,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);
@@ -1490,6 +1530,18 @@ public:
VisualShaderNodeSwitch();
};
+class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch {
+ GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch);
+
+public:
+ virtual String get_caption() const;
+
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual PortType get_output_port_type(int p_port) const;
+
+ VisualShaderNodeScalarSwitch();
+};
+
///////////////////////////////////////
/// FRESNEL
///////////////////////////////////////
@@ -1513,4 +1565,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_type);
+ ComparsionType get_comparsion_type() const;
+
+ void set_function(Function p_func);
+ Function get_function() const;
+
+ void set_condition(Condition p_cond);
+ 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_interface.h b/servers/arvr/arvr_interface.h
index ffafa4fcf5..85556b2757 100644
--- a/servers/arvr/arvr_interface.h
+++ b/servers/arvr/arvr_interface.h
@@ -39,7 +39,7 @@
/**
@author Bastiaan Olij <mux213@gmail.com>
- The ARVR interface is a template class ontop of which we build interface to differt AR, VR and tracking SDKs.
+ The ARVR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs.
The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface
when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server.
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 17f5e158a7..c651c177b5 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -134,31 +134,31 @@ AudioStreamMicrophone::AudioStreamMicrophone() {
void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
- AudioDriver::get_singleton()->lock();
+ AudioServer::get_singleton()->lock();
- Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
- unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
- int mix_rate = AudioDriver::get_singleton()->get_mix_rate();
- unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1);
+ PoolVector<int32_t> capture_buffer = AudioServer::get_singleton()->get_capture_buffer();
+ unsigned int capture_size = AudioServer::get_singleton()->get_capture_size();
+ int mix_rate = AudioServer::get_singleton()->get_mix_rate();
+ unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, capture_buffer.size() >> 1);
#ifdef DEBUG_ENABLED
- unsigned int input_position = AudioDriver::get_singleton()->get_input_position();
+ unsigned int capture_position = AudioServer::get_singleton()->get_capture_position();
#endif
- if (playback_delay > input_size) {
+ if (playback_delay > capture_size) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = AudioFrame(0.0f, 0.0f);
}
- input_ofs = 0;
+ capture_ofs = 0;
} else {
for (int i = 0; i < p_frames; i++) {
- if (input_size > input_ofs && (int)input_ofs < buf.size()) {
- float l = (buf[input_ofs++] >> 16) / 32768.f;
- if ((int)input_ofs >= buf.size()) {
- input_ofs = 0;
+ if (capture_size > capture_ofs && (int)capture_ofs < capture_buffer.size()) {
+ float l = (capture_buffer[capture_ofs++] >> 16) / 32768.f;
+ if ((int)capture_ofs >= capture_buffer.size()) {
+ capture_ofs = 0;
}
- float r = (buf[input_ofs++] >> 16) / 32768.f;
- if ((int)input_ofs >= buf.size()) {
- input_ofs = 0;
+ float r = (capture_buffer[capture_ofs++] >> 16) / 32768.f;
+ if ((int)capture_ofs >= capture_buffer.size()) {
+ capture_ofs = 0;
}
p_buffer[i] = AudioFrame(l, r);
@@ -169,12 +169,12 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
}
#ifdef DEBUG_ENABLED
- if (input_ofs > input_position && (int)(input_ofs - input_position) < (p_frames * 2)) {
- print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size));
+ if (capture_ofs > capture_position && (int)(capture_ofs - capture_position) < (p_frames * 2)) {
+ print_verbose(String(get_class_name()) + " buffer underrun: capture_position=" + itos(capture_position) + " capture_ofs=" + itos(capture_ofs) + " capture_size=" + itos(capture_size));
}
#endif
- AudioDriver::get_singleton()->unlock();
+ AudioServer::get_singleton()->unlock();
}
void AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
@@ -196,9 +196,9 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
return;
}
- input_ofs = 0;
+ capture_ofs = 0;
- if (AudioDriver::get_singleton()->capture_start() == OK) {
+ if (AudioServer::get_singleton()->capture_start() == OK) {
active = true;
_begin_resample();
}
@@ -206,7 +206,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
void AudioStreamPlaybackMicrophone::stop() {
if (active) {
- AudioDriver::get_singleton()->capture_stop();
+ AudioServer::get_singleton()->capture_stop();
active = false;
}
}
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index ef9f8ea92a..4548f8f036 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -123,7 +123,7 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
friend class AudioStreamMicrophone;
bool active;
- unsigned int input_ofs;
+ unsigned int capture_ofs;
Ref<AudioStreamMicrophone> microphone;
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/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index c250f2e2bd..ec3182685f 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -70,7 +70,7 @@
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice and this license appear in all source copies.
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
-* ANY KIND. See http://www.dspguru.com/wol.htm for more information.
+* ANY KIND. See https://dspguru.com/wide-open-license/ for more information.
*
*****************************************************************************/
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index acf27d2bbf..1390ab55c4 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -217,7 +217,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const {
PoolVector<uint8_t> dst_data;
ERR_FAIL_COND_V(current_instance.is_null(), NULL);
- ERR_FAIL_COND_V(current_instance->recording_data.size(), NULL);
+ ERR_FAIL_COND_V(current_instance->recording_data.size() == 0, NULL);
if (dst_format == AudioStreamSample::FORMAT_8_BITS) {
int data_size = current_instance->recording_data.size();
diff --git a/servers/audio/voice_rb_sw.h b/servers/audio/voice_rb_sw.h
index 0a39c536ae..1f0c88ed30 100644
--- a/servers/audio/voice_rb_sw.h
+++ b/servers/audio/voice_rb_sw.h
@@ -125,8 +125,7 @@ public:
if (full) {
#ifdef DEBUG_ENABLED
if (OS::get_singleton()->is_stdout_verbose()) {
- ERR_EXPLAIN("Audio Ring Buffer Full (too many commands");
- ERR_FAIL_COND(((write_pos + 1) % VOICE_RB_SIZE) == read_pos);
+ ERR_FAIL_COND_MSG(((write_pos + 1) % VOICE_RB_SIZE) == read_pos, "Audio ring buffer full (too many commands).");
}
#endif
return;
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index a6473d69c0..2cf6a67bef 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -85,26 +85,26 @@ double AudioDriver::get_time_to_next_mix() const {
return mix_buffer - total;
}
-void AudioDriver::input_buffer_init(int driver_buffer_frames) {
+void AudioDriver::capture_buffer_init(int driver_buffer_frames) {
- const int input_buffer_channels = 2;
- input_buffer.resize(driver_buffer_frames * input_buffer_channels * 4);
- input_position = 0;
- input_size = 0;
+ const int capture_buffer_channels = 2;
+ capture_buffer.resize(driver_buffer_frames * capture_buffer_channels * 4);
+ capture_position = 0;
+ capture_size = 0;
}
-void AudioDriver::input_buffer_write(int32_t sample) {
+void AudioDriver::capture_buffer_write(int32_t sample) {
- if ((int)input_position < input_buffer.size()) {
- input_buffer.write[input_position++] = sample;
- if ((int)input_position >= input_buffer.size()) {
- input_position = 0;
+ if ((int)capture_position < capture_buffer.size()) {
+ capture_buffer.write()[capture_position++] = sample;
+ if ((int)capture_position >= capture_buffer.size()) {
+ capture_position = 0;
}
- if ((int)input_size < input_buffer.size()) {
- input_size++;
+ if ((int)capture_size < capture_buffer.size()) {
+ capture_size++;
}
} else {
- WARN_PRINTS("input_buffer_write: Invalid input_position=" + itos(input_position) + " input_buffer.size()=" + itos(input_buffer.size()));
+ WARN_PRINTS("capture_buffer_write: Invalid capture_position=" + itos(capture_position) + " capture_buffer.size()=" + itos(capture_buffer.size()));
}
}
@@ -154,8 +154,8 @@ AudioDriver::AudioDriver() {
_last_mix_time = 0;
_last_mix_frames = 0;
- input_position = 0;
- input_size = 0;
+ capture_position = 0;
+ capture_size = 0;
#ifdef DEBUG_ENABLED
prof_time = 0;
@@ -338,6 +338,8 @@ void AudioServer::_mix_step() {
E->get().callback(E->get().userdata);
}
+ emit_signal("audio_mix_callback");
+
for (int i = buses.size() - 1; i >= 0; i--) {
//go bus by bus
Bus *bus = buses[i];
@@ -1057,6 +1059,8 @@ void AudioServer::update() {
E->get().callback(E->get().userdata);
}
+
+ emit_signal("audio_update_callback");
}
void AudioServer::load_default_bus_layout() {
@@ -1302,6 +1306,14 @@ void AudioServer::set_device(String device) {
AudioDriver::get_singleton()->set_device(device);
}
+Error AudioServer::capture_start() {
+ return AudioDriver::get_singleton()->capture_start();
+}
+
+Error AudioServer::capture_stop() {
+ return AudioDriver::get_singleton()->capture_stop();
+}
+
Array AudioServer::capture_get_device_list() {
return AudioDriver::get_singleton()->capture_get_device_list();
@@ -1317,6 +1329,18 @@ void AudioServer::capture_set_device(const String &p_name) {
AudioDriver::get_singleton()->capture_set_device(p_name);
}
+PoolVector<int32_t> AudioServer::get_capture_buffer() {
+ return AudioDriver::get_singleton()->get_capture_buffer();
+}
+
+unsigned int AudioServer::get_capture_position() {
+ return AudioDriver::get_singleton()->get_capture_position();
+}
+
+unsigned int AudioServer::get_capture_size() {
+ return AudioDriver::get_singleton()->get_capture_size();
+}
+
void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count);
@@ -1377,18 +1401,28 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_time_since_last_mix"), &AudioServer::get_time_since_last_mix);
ClassDB::bind_method(D_METHOD("get_output_latency"), &AudioServer::get_output_latency);
+ ClassDB::bind_method(D_METHOD("capture_start"), &AudioServer::capture_start);
+ ClassDB::bind_method(D_METHOD("capture_stop"), &AudioServer::capture_stop);
+
ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list);
ClassDB::bind_method(D_METHOD("capture_get_device"), &AudioServer::capture_get_device);
ClassDB::bind_method(D_METHOD("capture_set_device", "name"), &AudioServer::capture_set_device);
+ ClassDB::bind_method(D_METHOD("get_capture_buffer"), &AudioServer::get_capture_buffer);
+ ClassDB::bind_method(D_METHOD("get_capture_position"), &AudioServer::get_capture_position);
+ ClassDB::bind_method(D_METHOD("get_capture_size"), &AudioServer::get_capture_size);
+
ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout);
ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout);
ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "device"), "set_device", "get_device");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "capture_device"), "capture_set_device", "capture_get_device");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rate_scale"), "set_global_rate_scale", "get_global_rate_scale");
ADD_SIGNAL(MethodInfo("bus_layout_changed"));
+ ADD_SIGNAL(MethodInfo("audio_mix_callback"));
+ ADD_SIGNAL(MethodInfo("audio_update_callback"));
BIND_ENUM_CONSTANT(SPEAKER_MODE_STEREO);
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_31);
diff --git a/servers/audio_server.h b/servers/audio_server.h
index b0fff9d4b7..72bb6faf42 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -53,14 +53,14 @@ class AudioDriver {
#endif
protected:
- Vector<int32_t> input_buffer;
- unsigned int input_position;
- unsigned int input_size;
+ PoolVector<int32_t> capture_buffer;
+ unsigned int capture_position;
+ unsigned int capture_size;
void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true);
void update_mix_time(int p_frames);
- void input_buffer_init(int driver_buffer_frames);
- void input_buffer_write(int32_t sample);
+ void capture_buffer_init(int driver_buffer_frames);
+ void capture_buffer_write(int32_t sample);
#ifdef DEBUG_ENABLED
_FORCE_INLINE_ void start_counting_ticks() { prof_ticks = OS::get_singleton()->get_ticks_usec(); }
@@ -111,9 +111,9 @@ public:
SpeakerMode get_speaker_mode_by_total_channels(int p_channels) const;
int get_total_channels_by_speaker_mode(SpeakerMode) const;
- Vector<int32_t> get_input_buffer() { return input_buffer; }
- unsigned int get_input_position() { return input_position; }
- unsigned int get_input_size() { return input_size; }
+ PoolVector<int32_t> get_capture_buffer() { return capture_buffer; }
+ unsigned int get_capture_position() { return capture_position; }
+ unsigned int get_capture_size() { return capture_size; }
#ifdef DEBUG_ENABLED
uint64_t get_profiling_time() const { return prof_time; }
@@ -384,10 +384,17 @@ public:
String get_device();
void set_device(String device);
+ Error capture_start();
+ Error capture_stop();
+
Array capture_get_device_list();
String capture_get_device();
void capture_set_device(const String &p_name);
+ PoolVector<int32_t> get_capture_buffer();
+ unsigned int get_capture_position();
+ unsigned int get_capture_size();
+
AudioServer();
virtual ~AudioServer();
};
diff --git a/servers/camera_server.h b/servers/camera_server.h
index 5a62af3d60..c76d046e58 100644
--- a/servers/camera_server.h
+++ b/servers/camera_server.h
@@ -81,7 +81,7 @@ public:
void remove_feed(const Ref<CameraFeed> &p_feed);
// get our feeds
- Ref<CameraFeed> get_feed(int p_idx);
+ Ref<CameraFeed> get_feed(int p_index);
int get_feed_count();
Array get_feeds();
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 172a2a3429..a3bb581cb5 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -266,6 +266,7 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
_set_static(false);
+ angular_velocity = Vector3();
} break;
}
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 895eda8528..b9912f0ba2 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -86,13 +86,9 @@ protected:
void _unregister_shapes();
_FORCE_INLINE_ void _set_transform(const Transform &p_transform, bool p_update_shapes = true) {
-
#ifdef DEBUG_ENABLED
- if (p_transform.origin.length_squared() > MAX_OBJECT_DISTANCE_X2) {
- ERR_EXPLAIN("Object went too far away (more than " + itos(MAX_OBJECT_DISTANCE) + "mts from origin).");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(p_transform.origin.length_squared() > MAX_OBJECT_DISTANCE_X2, "Object went too far away (more than " + itos(MAX_OBJECT_DISTANCE) + " units from origin).");
#endif
transform = p_transform;
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 0d10dae8cc..d970dd39fb 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -233,8 +233,6 @@ bool CollisionSolverSW::solve_static(const ShapeSW *p_shape_A, const Transform &
return collision_solver(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, r_sep_axis, p_margin_A, p_margin_B);
}
-
- return false;
}
void CollisionSolverSW::concave_distance_callback(void *p_userdata, ShapeSW *p_convex) {
@@ -371,6 +369,4 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
return gjk_epa_calculate_distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, r_point_A, r_point_B); //should pass sepaxis..
}
-
- return false;
}
diff --git a/servers/physics/gjk_epa.h b/servers/physics/gjk_epa.h
index 0b7885c9a5..d3fa192804 100644
--- a/servers/physics/gjk_epa.h
+++ b/servers/physics/gjk_epa.h
@@ -31,11 +31,8 @@
#ifndef GJK_EPA_H
#define GJK_EPA_H
-#include "shape_sw.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
#include "collision_solver_sw.h"
+#include "shape_sw.h"
bool gjk_epa_calculate_penetration(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, CollisionSolverSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false);
bool gjk_epa_calculate_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B);
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index 1d1b30286e..209cddda5e 100644
--- a/servers/physics/joints/hinge_joint_sw.cpp
+++ b/servers/physics/joints/hinge_joint_sw.cpp
@@ -198,7 +198,6 @@ bool HingeJointSW::setup(real_t p_step) {
plane_space(m_rbAFrame.basis.get_axis(2), jointAxis0local, jointAxis1local);
- A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(2));
Vector3 jointAxis0 = A->get_transform().basis.xform(jointAxis0local);
Vector3 jointAxis1 = A->get_transform().basis.xform(jointAxis1local);
Vector3 hingeAxisWorld = A->get_transform().basis.xform(m_rbAFrame.basis.get_axis(2));
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 7b982e7015..09872977b6 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -40,11 +40,8 @@
#include "joints/pin_joint_sw.h"
#include "joints/slider_joint_sw.h"
-#define FLUSH_QUERY_CHECK(m_object) \
- if (m_object->get_space() && flushing_queries) { \
- ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead"); \
- ERR_FAIL(); \
- }
+#define FLUSH_QUERY_CHECK(m_object) \
+ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");
RID PhysicsServerSW::shape_create(ShapeType p_shape) {
@@ -73,8 +70,7 @@ RID PhysicsServerSW::shape_create(ShapeType p_shape) {
} break;
case SHAPE_CYLINDER: {
- ERR_EXPLAIN("CylinderShape is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
- ERR_FAIL_V(RID());
+ ERR_FAIL_V_MSG(RID(), "CylinderShape is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
} break;
case SHAPE_CONVEX_POLYGON: {
@@ -200,11 +196,7 @@ PhysicsDirectSpaceState *PhysicsServerSW::space_get_direct_state(RID p_space) {
SpaceSW *space = space_owner.get(p_space);
ERR_FAIL_COND_V(!space, NULL);
- if (!doing_sync || space->is_locked()) {
-
- ERR_EXPLAIN("Space state is inaccessible right now, wait for iteration or physics process notification.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!doing_sync || space->is_locked(), NULL, "Space state is inaccessible right now, wait for iteration or physics process notification.");
return space->get_direct_state();
}
@@ -987,12 +979,7 @@ PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, NULL);
-
- if (!doing_sync || body->get_space()->is_locked()) {
-
- ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(!doing_sync || body->get_space()->is_locked(), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification.");
direct_state->body = body;
return direct_state;
@@ -1410,8 +1397,7 @@ void PhysicsServerSW::free(RID p_rid) {
} else {
- ERR_EXPLAIN("Invalid ID");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid ID.");
}
};
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index 8a52f29729..f01caefdce 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -543,16 +543,6 @@ void CapsuleShapeSW::project_range(const Vector3 &p_normal, const Transform &p_t
r_max = p_normal.dot(p_transform.xform(n));
r_min = p_normal.dot(p_transform.xform(-n));
- return;
-
- n = p_transform.basis.xform(n);
-
- real_t distance = p_normal.dot(p_transform.origin);
- real_t length = Math::abs(p_normal.dot(n));
- r_min = distance - length;
- r_max = distance + length;
-
- ERR_FAIL_COND(r_max < r_min);
}
Vector3 CapsuleShapeSW::get_support(const Vector3 &p_normal) const {
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index f3a4cbed24..410b6e59a0 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -348,11 +348,9 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh
cbk.max = p_result_max;
cbk.amount = 0;
cbk.ptr = r_results;
- CollisionSolverSW::CallbackResult cbkres = NULL;
+ CollisionSolverSW::CallbackResult cbkres = PhysicsServerSW::_shape_col_cbk;
- PhysicsServerSW::CollCbkData *cbkptr = NULL;
- cbkptr = &cbk;
- cbkres = PhysicsServerSW::_shape_col_cbk;
+ PhysicsServerSW::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) {
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 60bbcef4b6..6ba159ca0a 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -47,8 +47,10 @@ void Body2DSW::update_inertias() {
case Physics2DServer::BODY_MODE_RIGID: {
- if (user_inertia) break;
-
+ if (user_inertia) {
+ _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
+ break;
+ }
//update tensor for allshapes, not the best way but should be somehow OK. (inspired from bullet)
real_t total_area = 0;
@@ -57,7 +59,7 @@ void Body2DSW::update_inertias() {
total_area += get_shape_aabb(i).get_area();
}
- real_t _inertia = 0;
+ inertia = 0;
for (int i = 0; i < get_shape_count(); i++) {
@@ -73,15 +75,10 @@ void Body2DSW::update_inertias() {
Transform2D mtx = get_shape_transform(i);
Vector2 scale = mtx.get_scale();
- _inertia += shape->get_moment_of_inertia(mass, scale) + mass * mtx.get_origin().length_squared();
- //Rect2 ab = get_shape_aabb(i);
- //_inertia+=mass*ab.size.dot(ab.size)/12.0f;
+ inertia += shape->get_moment_of_inertia(mass, scale) + mass * mtx.get_origin().length_squared();
}
- if (_inertia != 0)
- _inv_inertia = 1.0 / _inertia;
- else
- _inv_inertia = 0.0; //wathever
+ _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
if (mass)
_inv_mass = 1.0 / mass;
@@ -160,6 +157,7 @@ void Body2DSW::set_param(Physics2DServer::BodyParameter p_param, real_t p_value)
_update_inertia();
} else {
user_inertia = true;
+ inertia = p_value;
_inv_inertia = 1.0 / p_value;
}
} break;
@@ -185,28 +183,28 @@ real_t Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const {
case Physics2DServer::BODY_PARAM_BOUNCE: {
return bounce;
- } break;
+ }
case Physics2DServer::BODY_PARAM_FRICTION: {
return friction;
- } break;
+ }
case Physics2DServer::BODY_PARAM_MASS: {
return mass;
- } break;
+ }
case Physics2DServer::BODY_PARAM_INERTIA: {
- return _inv_inertia == 0 ? 0 : 1.0 / _inv_inertia;
- } break;
+ return inertia;
+ }
case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: {
return gravity_scale;
- } break;
+ }
case Physics2DServer::BODY_PARAM_LINEAR_DAMP: {
return linear_damp;
- } break;
+ }
case Physics2DServer::BODY_PARAM_ANGULAR_DAMP: {
return angular_damp;
- } break;
+ }
default: {
}
}
@@ -226,6 +224,7 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
_set_inv_transform(get_transform().affine_inverse());
_inv_mass = 0;
+ _inv_inertia = 0;
_set_static(p_mode == Physics2DServer::BODY_MODE_STATIC);
set_active(p_mode == Physics2DServer::BODY_MODE_KINEMATIC && contacts.size());
linear_velocity = Vector2();
@@ -237,17 +236,21 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
case Physics2DServer::BODY_MODE_RIGID: {
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
+ _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
_set_static(false);
} break;
case Physics2DServer::BODY_MODE_CHARACTER: {
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
+ _inv_inertia = 0;
_set_static(false);
+ angular_velocity = 0;
} break;
}
-
- _update_inertia();
+ if (p_mode == Physics2DServer::BODY_MODE_RIGID && _inv_inertia == 0) {
+ _update_inertia();
+ }
/*
if (get_space())
_update_queries();
@@ -343,19 +346,19 @@ Variant Body2DSW::get_state(Physics2DServer::BodyState p_state) const {
switch (p_state) {
case Physics2DServer::BODY_STATE_TRANSFORM: {
return get_transform();
- } break;
+ }
case Physics2DServer::BODY_STATE_LINEAR_VELOCITY: {
return linear_velocity;
- } break;
+ }
case Physics2DServer::BODY_STATE_ANGULAR_VELOCITY: {
return angular_velocity;
- } break;
+ }
case Physics2DServer::BODY_STATE_SLEEPING: {
return !is_active();
- } break;
+ }
case Physics2DServer::BODY_STATE_CAN_SLEEP: {
return can_sleep;
- } break;
+ }
}
return Variant();
@@ -608,7 +611,7 @@ void Body2DSW::call_queries() {
set_force_integration_callback(0, StringName());
} else {
Variant::CallError ce;
- if (fi_callback->callback_udata.get_type()) {
+ if (fi_callback->callback_udata.get_type() != Variant::NIL) {
obj->call(fi_callback->method, vp, 2, ce);
@@ -668,6 +671,7 @@ Body2DSW::Body2DSW() :
angular_velocity = 0;
biased_angular_velocity = 0;
mass = 1;
+ inertia = 0;
user_inertia = false;
_inv_inertia = 0;
_inv_mass = 1;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 8c64dc9230..5df184c894 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -52,6 +52,7 @@ class Body2DSW : public CollisionObject2DSW {
real_t gravity_scale;
real_t mass;
+ real_t inertia;
real_t bounce;
real_t friction;
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 1bbb50c974..6dd19c2868 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -673,7 +673,7 @@ public IEnumerable<Point3D> GetCellsOnRay(Ray ray, int maxDepth)
// "A Fast Voxel Traversal Algorithm for Ray Tracing"
// John Amanatides, Andrew Woo
// http://www.cse.yorku.ca/~amana/research/grid.pdf
- // http://www.devmaster.net/articles/raytracing_series/A%20faster%20voxel%20traversal%20algorithm%20for%20ray%20tracing.pdf
+ // https://web.archive.org/web/20100616193049/http://www.devmaster.net/articles/raytracing_series/A%20faster%20voxel%20traversal%20algorithm%20for%20ray%20tracing.pdf
// NOTES:
// * This code assumes that the ray's position and direction are in 'cell coordinates', which means
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index f4bff66389..19e4b8c1d9 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -172,8 +172,8 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po
points_B = p_points_B;
}
- int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1;
- int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1;
+ int version_A = (pointcount_A > 2 ? 2 : pointcount_A) - 1;
+ int version_B = (pointcount_B > 2 ? 2 : pointcount_B) - 1;
GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B];
ERR_FAIL_COND(!contacts_func);
@@ -313,10 +313,12 @@ public:
if (best_axis == Vector2(0.0, 0.0))
return;
- callback->collided = true;
+ if (callback) {
+ callback->collided = true;
- if (!callback->callback)
- return; //only collide, no callback
+ if (!callback->callback)
+ return; //only collide, no callback
+ }
static const int max_supports = 2;
Vector2 supports_A[max_supports];
@@ -354,12 +356,13 @@ public:
supports_B[i] += best_axis * margin_B;
}
}
+ if (callback) {
+ callback->normal = best_axis;
+ _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
- callback->normal = best_axis;
- _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
-
- if (callback && callback->sep_axis && *callback->sep_axis != Vector2())
- *callback->sep_axis = Vector2(); //invalidate previous axis (no test)
+ if (callback->sep_axis && *callback->sep_axis != Vector2())
+ *callback->sep_axis = Vector2(); //invalidate previous axis (no test)
+ }
}
_FORCE_INLINE_ SeparatorAxisTest2D(const ShapeA *p_shape_A, const Transform2D &p_transform_a, const ShapeB *p_shape_B, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_A = Vector2(), const Vector2 &p_motion_B = Vector2(), real_t p_margin_A = 0, real_t p_margin_B = 0) {
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index e49961c048..03c0fd5981 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -249,6 +249,4 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
return collision_solver(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B);
}
-
- return false;
}
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index cc656d3b73..80e204087a 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -36,11 +36,8 @@
#include "core/project_settings.h"
#include "core/script_language.h"
-#define FLUSH_QUERY_CHECK(m_object) \
- if (m_object->get_space() && flushing_queries) { \
- ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead"); \
- ERR_FAIL(); \
- }
+#define FLUSH_QUERY_CHECK(m_object) \
+ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");
RID Physics2DServerSW::_shape_create(ShapeType p_shape) {
@@ -316,11 +313,7 @@ Physics2DDirectSpaceState *Physics2DServerSW::space_get_direct_state(RID p_space
Space2DSW *space = space_owner.get(p_space);
ERR_FAIL_COND_V(!space, NULL);
- if ((using_threads && !doing_sync) || space->is_locked()) {
-
- ERR_EXPLAIN("Space state is inaccessible right now, wait for iteration or physics process notification.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), NULL, "Space state is inaccessible right now, wait for iteration or physics process notification.");
return space->get_direct_state();
}
@@ -1075,10 +1068,7 @@ int Physics2DServerSW::body_test_ray_separation(RID p_body, const Transform2D &p
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
- if ((using_threads && !doing_sync)) {
- ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification.");
if (!body_owner.owns(p_body))
return NULL;
@@ -1086,12 +1076,7 @@ Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, NULL);
ERR_FAIL_COND_V(!body->get_space(), NULL);
-
- if (body->get_space()->is_locked()) {
-
- ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
- ERR_FAIL_V(NULL);
- }
+ ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), NULL, "Body state is inaccessible right now, wait for iteration or physics process notification.");
direct_state->body = body;
return direct_state;
@@ -1321,8 +1306,7 @@ void Physics2DServerSW::free(RID p_rid) {
} else {
- ERR_EXPLAIN("Invalid ID");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid ID.");
}
};
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
index 71c00c0abf..c698290fd9 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
@@ -54,8 +54,6 @@ void Physics2DServerWrapMT::thread_loop() {
server_thread = Thread::get_caller_id();
- OS::get_singleton()->make_rendering_thread();
-
physics_2d_server->init();
exit = false;
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index b61e1faad2..33a184ba3f 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -327,11 +327,11 @@ public:
static Physics2DServer *init_server() {
int tm = GLOBAL_DEF("physics/2d/thread_model", 1);
- if (tm == 0) //single unsafe
+ if (tm == 0) // single unsafe
return memnew(T);
- else if (tm == 1) //single saef
+ else if (tm == 1) // single safe
return memnew(Physics2DServerWrapMT(memnew(T), false));
- else //single unsafe
+ else // multi threaded
return memnew(Physics2DServerWrapMT(memnew(T), true));
}
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 7c89c43f36..2778775446 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -330,11 +330,9 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
cbk.amount = 0;
cbk.passed = 0;
cbk.ptr = r_results;
- CollisionSolver2DSW::CallbackResult cbkres = NULL;
+ CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk;
- Physics2DServerSW::CollCbkData *cbkptr = NULL;
- cbkptr = &cbk;
- cbkres = Physics2DServerSW::_shape_col_cbk;
+ Physics2DServerSW::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) {
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 31b468b50b..9aaebefd80 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -357,7 +357,6 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
- virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform) = 0;
/* Light API */
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 393c065b7d..1b9c3e2eff 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -283,6 +283,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_CF_DO, "do" },
{ TK_CF_SWITCH, "switch" },
{ TK_CF_CASE, "case" },
+ { TK_CF_DEFAULT, "default" },
{ TK_CF_BREAK, "break" },
{ TK_CF_CONTINUE, "continue" },
{ TK_CF_RETURN, "return" },
@@ -785,6 +786,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 +861,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, bool *r_is_const, int *r_array_size) {
if (p_builtin_types.has(p_identifier)) {
@@ -871,6 +883,12 @@ 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_is_const) {
+ *r_is_const = p_block->variables[p_identifier].is_const;
+ }
+ if (r_array_size) {
+ *r_array_size = p_block->variables[p_identifier].array_size;
+ }
if (r_type) {
*r_type = IDENTIFIER_LOCAL_VAR;
}
@@ -906,6 +924,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
if (r_data_type) {
*r_data_type = shader->varyings[p_identifier].type;
}
+ if (r_array_size) {
+ *r_array_size = shader->varyings[p_identifier].array_size;
+ }
if (r_type) {
*r_type = IDENTIFIER_VARYING;
}
@@ -944,6 +965,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
if (r_type) {
*r_type = IDENTIFIER_FUNCTION;
}
+ return true;
}
}
@@ -953,7 +975,7 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) {
bool valid = false;
- DataType ret_type;
+ DataType ret_type = TYPE_VOID;
switch (p_op->op) {
case OP_EQUAL:
@@ -1328,725 +1350,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_BVEC2, { TYPE_BVEC2, TYPE_VOID } },
- { "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID } },
- { "not", TYPE_BVEC4, { 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 },
+
+ { "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 },
- { "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 } },
+ { "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
- { "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 } },
+ //array
+ { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY },
- { NULL, TYPE_VOID, { TYPE_VOID } }
+ { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL }
};
@@ -2058,11 +2085,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 +2107,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;
@@ -2711,7 +2743,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
- if (shader->constants.has(var->name)) {
+ if (shader->constants.has(var->name) || var->is_const) {
if (r_message)
*r_message = RTR("Constants cannot be modified.");
return false;
@@ -2720,6 +2752,23 @@ 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) {
+
+ ArrayNode *arr = static_cast<ArrayNode *>(p_node);
+
+ if (arr->is_const) {
+ if (r_message)
+ *r_message = RTR("Constants cannot be modified.");
+ return false;
+ }
+
+ if (shader->varyings.has(arr->name) && current_function != String("vertex")) {
+ if (r_message)
+ *r_message = RTR("Varyings can only be assigned in vertex function.");
+ return false;
+ }
+
+ return true;
}
if (r_message)
@@ -2730,6 +2779,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 +2888,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 +2943,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 +2954,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
DataType data_type;
IdentifierType ident_type;
+ bool is_const = false;
+ 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, &is_const, &array_size)) {
_set_error("Unknown identifier in expression: " + String(identifier));
return NULL;
}
@@ -2915,10 +2967,70 @@ 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;
+ arrname->is_const = is_const;
+ expr = arrname;
+
+ } else {
+
+ VariableNode *varname = alloc_node<VariableNode>();
+ varname->name = identifier;
+ varname->datatype_cache = data_type;
+ varname->is_const = is_const;
+ expr = varname;
+ }
}
} else if (tk.type == TK_OP_ADD) {
@@ -2969,12 +3081,11 @@ 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;
bool ok = true;
- DataType member_type;
+ DataType member_type = TYPE_VOID;
switch (dt) {
case TYPE_BVEC2:
case TYPE_IVEC2:
@@ -3677,6 +3788,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
TkPos pos = _get_tkpos();
Token tk = _get_token();
+
+ if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_SWITCH) {
+ if (tk.type != TK_CF_CASE && tk.type != TK_CF_DEFAULT && tk.type != TK_CURLY_BRACKET_CLOSE) {
+ _set_error("Switch may contains only case and default blocks");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
if (tk.type == TK_CURLY_BRACKET_CLOSE) { //end of block
if (p_just_one) {
_set_error("Unexpected '}'");
@@ -3685,7 +3804,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return OK;
- } else if (is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) {
+ } else if (tk.type == TK_CONST || is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type)) {
+
+ bool is_const = false;
+
+ if (tk.type == TK_CONST) {
+ is_const = true;
+ tk = _get_token();
+ }
+
DataPrecision precision = PRECISION_DEFAULT;
if (is_token_precision(tk.type)) {
precision = get_token_precision(tk.type);
@@ -3705,11 +3832,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 +3851,213 @@ 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;
+ var.is_const = is_const;
+
+ tk = _get_token();
- VariableDeclarationNode::Declaration decl;
+ if (tk.type == TK_BRACKET_OPEN) {
+ bool unknown_size = false;
- decl.name = name;
- decl.initializer = NULL;
+ ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>();
+ node->datatype = type;
+ node->precision = precision;
+ node->is_const = is_const;
+ vardecl = (Node *)node;
- tk = _get_token();
+ 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;
+ }
+
+ decl.size = ((uint32_t)tk.constant);
+ tk = _get_token();
+
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return ERR_PARSE_ERROR;
+ }
+ 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;
+ }
+ if (is_const) {
+ _set_error("Expected initialization of constant");
+ 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;
+ node->is_const = is_const;
+ 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 +4070,27 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return ERR_PARSE_ERROR;
}
tk = _get_token();
+ node->declarations.push_back(decl);
+ } else {
+ if (is_const) {
+ _set_error("Expected initialization of constant");
+ return ERR_PARSE_ERROR;
+ }
+
+ 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();
@@ -3813,37 +4150,250 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos); //rollback
}
- } else if (tk.type == TK_CF_WHILE) {
- //if () {}
+ } else if (tk.type == TK_CF_SWITCH) {
+ // switch() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_error("Expected '(' after while");
+ _set_error("Expected '(' after switch");
return ERR_PARSE_ERROR;
}
-
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
- cf->flow_op = FLOW_OP_WHILE;
+ cf->flow_op = FLOW_OP_SWITCH;
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!n)
return ERR_PARSE_ERROR;
-
+ if (n->get_datatype() != TYPE_INT) {
+ _set_error("Expected integer expression");
+ return ERR_PARSE_ERROR;
+ }
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
+ tk = _get_token();
+ if (tk.type != TK_CURLY_BRACKET_OPEN) {
+ _set_error("Expected '{' after switch statement");
+ return ERR_PARSE_ERROR;
+ }
+ BlockNode *switch_block = alloc_node<BlockNode>();
+ switch_block->block_type = BlockNode::BLOCK_TYPE_SWITCH;
+ switch_block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(switch_block);
+ p_block->statements.push_back(cf);
- BlockNode *block = alloc_node<BlockNode>();
- block->parent_block = p_block;
+ int prev_type = TK_CF_CASE;
+ while (true) { // Go-through multiple cases.
+
+ if (_parse_block(switch_block, p_builtin_types, true, true, false) != OK) {
+ return ERR_PARSE_ERROR;
+ }
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_CF_CASE || tk.type == TK_CF_DEFAULT) {
+ if (prev_type == TK_CF_DEFAULT) {
+ if (tk.type == TK_CF_CASE) {
+ _set_error("Cases must be defined before default case.");
+ return ERR_PARSE_ERROR;
+ } else if (prev_type == TK_CF_DEFAULT) {
+ _set_error("Default case must be defined only once.");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ prev_type = tk.type;
+ _set_tkpos(pos);
+ continue;
+ } else {
+ Set<int> constants;
+ for (int i = 0; i < switch_block->statements.size(); i++) { // Checks for duplicates.
+ ControlFlowNode *flow = (ControlFlowNode *)switch_block->statements[i];
+ if (flow) {
+ if (flow->flow_op == FLOW_OP_CASE) {
+ ConstantNode *n2 = static_cast<ConstantNode *>(flow->expressions[0]);
+ if (!n2) {
+ return ERR_PARSE_ERROR;
+ }
+ if (n2->values.empty()) {
+ return ERR_PARSE_ERROR;
+ }
+ if (constants.has(n2->values[0].sint)) {
+ _set_error("Duplicated case label: '" + itos(n2->values[0].sint) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ constants.insert(n2->values[0].sint);
+ } else if (flow->flow_op == FLOW_OP_DEFAULT) {
+ continue;
+ } else {
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ return ERR_PARSE_ERROR;
+ }
+ }
+ break;
+ }
+ }
+
+ } else if (tk.type == TK_CF_CASE) {
+ // case x : break; | return;
+
+ if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
+ _set_tkpos(pos);
+ return OK;
+ }
+
+ if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
+ _set_error("case must be placed within switch block");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ int sign = 1;
+
+ if (tk.type == TK_OP_SUB) {
+ sign = -1;
+ tk = _get_token();
+ }
+
+ if (tk.type != TK_INT_CONSTANT) {
+ _set_error("Expected integer constant");
+ return ERR_PARSE_ERROR;
+ }
+
+ int constant = (int)tk.constant * sign;
+
+ tk = _get_token();
+
+ if (tk.type != TK_COLON) {
+ _set_error("Expected ':'");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_CASE;
+
+ ConstantNode *n = alloc_node<ConstantNode>();
+ ConstantNode::Value v;
+ v.sint = constant;
+ n->values.push_back(v);
+ n->datatype = TYPE_INT;
+
+ BlockNode *case_block = alloc_node<BlockNode>();
+ case_block->block_type = BlockNode::BLOCK_TYPE_CASE;
+ case_block->parent_block = p_block;
cf->expressions.push_back(n);
- cf->blocks.push_back(block);
+ cf->blocks.push_back(case_block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_builtin_types, true, true, true);
+ Error err = _parse_block(case_block, p_builtin_types, false, true, false);
+ if (err)
+ return err;
+
+ return OK;
+
+ } else if (tk.type == TK_CF_DEFAULT) {
+
+ if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
+ _set_tkpos(pos);
+ return OK;
+ }
+
+ if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
+ _set_error("default must be placed within switch block");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_COLON) {
+ _set_error("Expected ':'");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_DEFAULT;
+
+ BlockNode *default_block = alloc_node<BlockNode>();
+ default_block->block_type = BlockNode::BLOCK_TYPE_DEFAULT;
+ default_block->parent_block = p_block;
+ cf->blocks.push_back(default_block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(default_block, p_builtin_types, false, true, false);
if (err)
return err;
+
+ return OK;
+
+ } else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
+ // do {} while()
+ // while() {}
+ bool is_do = tk.type == TK_CF_DO;
+
+ BlockNode *do_block = NULL;
+ if (is_do) {
+
+ do_block = alloc_node<BlockNode>();
+ do_block->parent_block = p_block;
+
+ Error err = _parse_block(do_block, p_builtin_types, true, true, true);
+ if (err)
+ return err;
+
+ tk = _get_token();
+ if (tk.type != TK_CF_WHILE) {
+ _set_error("Expected while after do");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ tk = _get_token();
+
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after while");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ if (is_do) {
+ cf->flow_op = FLOW_OP_DO;
+ } else {
+ cf->flow_op = FLOW_OP_WHILE;
+ }
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' after expression");
+ return ERR_PARSE_ERROR;
+ }
+ if (!is_do) {
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(block, p_builtin_types, true, true, true);
+ if (err)
+ return err;
+ } else {
+
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(do_block);
+ p_block->statements.push_back(cf);
+
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ }
} else if (tk.type == TK_CF_FOR) {
- //if () {}
+ // for() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after for");
@@ -3944,6 +4494,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
p_block->statements.push_back(flow);
+ if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
+ return OK;
+ }
} else if (tk.type == TK_CF_DISCARD) {
//check return type
@@ -3990,9 +4543,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
p_block->statements.push_back(flow);
+ if (p_block->block_type == BlockNode::BLOCK_TYPE_CASE || p_block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
+ return OK;
+ }
+
} else if (tk.type == TK_CF_CONTINUE) {
- if (!p_can_break) {
+ if (!p_can_continue) {
//all is good
_set_error("Continuing is not allowed here");
}
@@ -4147,7 +4704,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (!uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
- _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 allowed.");
+ _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 or array of these types allowed.");
return ERR_PARSE_ERROR;
}
@@ -4329,13 +4886,36 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
varying.type = type;
varying.precision = precision;
varying.interpolation = interpolation;
- shader->varyings[name] = varying;
tk = _get_token();
- if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
+ _set_error("Expected ';' or '['");
return ERR_PARSE_ERROR;
}
+
+ if (tk.type == TK_BRACKET_OPEN) {
+ tk = _get_token();
+ if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
+ varying.array_size = (int)tk.constant;
+
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected ']'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ shader->varyings[name] = varying;
}
} break;
@@ -4369,6 +4949,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 +5110,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 +5134,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();
@@ -4577,6 +5173,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (err)
return err;
+ if (func_node->return_type != DataType::TYPE_VOID) {
+
+ BlockNode *block = func_node->body;
+ if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) {
+ _set_error("Expected at least one return statement in a non-void function.");
+ return ERR_PARSE_ERROR;
+ }
+ }
current_function = StringName();
}
}
@@ -4587,6 +5191,57 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return OK;
}
+Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) {
+
+ bool found = false;
+
+ for (int i = p_flow->blocks.size() - 1; i >= 0; i--) {
+ if (p_flow->blocks[i]->type == Node::TYPE_BLOCK) {
+ BlockNode *last_block = (BlockNode *)p_flow->blocks[i];
+ if (_find_last_flow_op_in_block(last_block, p_op) == OK) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (found) {
+ return OK;
+ }
+ return FAILED;
+}
+
+Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) {
+
+ bool found = false;
+
+ for (int i = p_block->statements.size() - 1; i >= 0; i--) {
+
+ if (p_block->statements[i]->type == Node::TYPE_CONTROL_FLOW) {
+ ControlFlowNode *flow = (ControlFlowNode *)p_block->statements[i];
+ if (flow->flow_op == p_op) {
+ found = true;
+ break;
+ } else {
+ if (_find_last_flow_op_in_op(flow, p_op) == OK) {
+ found = true;
+ break;
+ }
+ }
+ } else if (p_block->statements[i]->type == Node::TYPE_BLOCK) {
+ BlockNode *block = (BlockNode *)p_block->statements[i];
+ if (_find_last_flow_op_in_block(block, p_op) == OK) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ return OK;
+ }
+ return FAILED;
+}
+
// skips over whitespace and /* */ and // comments
static int _get_first_ident_pos(const String &p_code) {
@@ -4728,60 +5383,71 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
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(), ScriptCodeCompletionOption::KIND_VARIABLE);
+ 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, ScriptCodeCompletionOption::KIND_FUNCTION);
+ 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()) {
- ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
- if (E->get().constant) {
- kind = ScriptCodeCompletionOption::KIND_CONSTANT;
+ 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);
}
- 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(), ScriptCodeCompletionOption::KIND_VARIABLE);
+ 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(), ScriptCodeCompletionOption::KIND_MEMBER);
+
+ 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), ScriptCodeCompletionOption::KIND_FUNCTION);
- }
+ 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), ScriptCodeCompletionOption::KIND_FUNCTION);
- 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 (Map<String, ScriptCodeCompletionOption::Kind>::Element *E = matches.front(); E; E = E->next()) {
@@ -4793,7 +5459,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
return OK;
-
} break;
case COMPLETION_CALL_ARGUMENTS: {
@@ -4846,6 +5511,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";
@@ -4957,6 +5627,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 65bf78bddd..3a5630ef42 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -125,6 +125,7 @@ public:
TK_CF_DO,
TK_CF_SWITCH,
TK_CF_CASE,
+ TK_CF_DEFAULT,
TK_CF_BREAK,
TK_CF_CONTINUE,
TK_CF_RETURN,
@@ -266,6 +267,8 @@ public:
FLOW_OP_DO,
FLOW_OP_BREAK,
FLOW_OP_SWITCH,
+ FLOW_OP_CASE,
+ FLOW_OP_DEFAULT,
FLOW_OP_CONTINUE,
FLOW_OP_DISCARD
};
@@ -288,7 +291,9 @@ public:
TYPE_CONSTANT,
TYPE_OPERATOR,
TYPE_CONTROL_FLOW,
- TYPE_MEMBER
+ TYPE_MEMBER,
+ TYPE_ARRAY,
+ TYPE_ARRAY_DECLARATION,
};
Type type;
@@ -328,15 +333,18 @@ public:
DataType datatype_cache;
StringName name;
virtual DataType get_datatype() const { return datatype_cache; }
+ bool is_const;
VariableNode() :
Node(TYPE_VARIABLE),
- datatype_cache(TYPE_VOID) {}
+ datatype_cache(TYPE_VOID),
+ is_const(false) {}
};
struct VariableDeclarationNode : public Node {
DataPrecision precision;
DataType datatype;
+ bool is_const;
struct Declaration {
StringName name;
@@ -349,7 +357,46 @@ public:
VariableDeclarationNode() :
Node(TYPE_VARIABLE_DECLARATION),
precision(PRECISION_DEFAULT),
- datatype(TYPE_VOID) {}
+ datatype(TYPE_VOID),
+ is_const(false) {}
+ };
+
+ struct ArrayNode : public Node {
+ DataType datatype_cache;
+ StringName name;
+ Node *index_expression;
+ Node *call_expression;
+ bool is_const;
+
+ virtual DataType get_datatype() const { return datatype_cache; }
+
+ ArrayNode() :
+ Node(TYPE_ARRAY),
+ datatype_cache(TYPE_VOID),
+ index_expression(NULL),
+ call_expression(NULL),
+ is_const(false) {}
+ };
+
+ struct ArrayDeclarationNode : public Node {
+ DataPrecision precision;
+ DataType datatype;
+ bool is_const;
+
+ 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),
+ is_const(false) {}
};
struct ConstantNode : public Node {
@@ -376,10 +423,21 @@ public:
FunctionNode *parent_function;
BlockNode *parent_block;
+ enum BlockType {
+ BLOCK_TYPE_STANDART,
+ BLOCK_TYPE_SWITCH,
+ BLOCK_TYPE_CASE,
+ BLOCK_TYPE_DEFAULT,
+ };
+
+ int block_type;
+
struct Variable {
DataType type;
DataPrecision precision;
int line; //for completion
+ int array_size;
+ bool is_const;
};
Map<StringName, Variable> variables;
@@ -390,6 +448,7 @@ public:
Node(TYPE_BLOCK),
parent_function(NULL),
parent_block(NULL),
+ block_type(BLOCK_TYPE_STANDART),
single_statement(false) {}
};
@@ -460,11 +519,13 @@ public:
DataType type;
DataInterpolation interpolation;
DataPrecision precision;
+ int array_size;
Varying() :
type(TYPE_VOID),
interpolation(INTERPOLATION_FLAT),
- precision(PRECISION_DEFAULT) {}
+ precision(PRECISION_DEFAULT),
+ array_size(0) {}
};
struct Uniform {
@@ -552,6 +613,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);
@@ -645,16 +707,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, bool *r_is_const = 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
@@ -666,6 +734,7 @@ private:
int completion_line;
BlockNode *completion_block;
DataType completion_base;
+ SubClassTag completion_class;
StringName completion_function;
int completion_argument;
@@ -683,6 +752,9 @@ private:
Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
+ Error _find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op);
+ Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op);
+
public:
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 75910ff1c0..019f477362 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -235,6 +235,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW_VEC"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = constt(ShaderLanguage::TYPE_VEC2);
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index fc75fda583..f5a1276c27 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -386,8 +386,7 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
} else {
- ERR_EXPLAIN("Invalid parent");
- ERR_FAIL();
+ ERR_FAIL_MSG("Invalid parent.");
}
}
@@ -754,12 +753,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
ERR_FAIL_COND(uv_size != 0 && (uv_size != pointcount));
#endif
Vector<int> indices = Geometry::triangulate_polygon(p_points);
-
- if (indices.empty()) {
-
- ERR_EXPLAIN("Bad Polygon!");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(indices.empty(), "Invalid polygon data, triangulation failed.");
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
ERR_FAIL_COND(!polygon);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index f37d651dee..0df228457e 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -38,9 +38,6 @@
#include "visual_server_globals.h"
#include "visual_server_scene.h"
#include "visual_server_viewport.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServerRaster : public VisualServer {
@@ -297,7 +294,6 @@ public:
BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &)
- BIND3(skeleton_set_world_transform, RID, bool, const Transform &)
/* Light API */
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index f8ed035766..f515af4d91 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -63,7 +63,10 @@ static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewp
}
void VisualServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
- Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ Ref<ARVRInterface> arvr_interface;
+ if (ARVRServer::get_singleton() != NULL) {
+ arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ }
if (p_viewport->use_arvr && arvr_interface.is_valid()) {
VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
@@ -82,6 +85,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) {
VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario);
+ ERR_FAIL_COND(!scenario);
if (VSG::scene_render->is_environment(scenario->environment)) {
scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS;
@@ -260,11 +264,16 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
void VisualServerViewport::draw_viewports() {
+
// get our arvr interface in case we need it
- Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ Ref<ARVRInterface> arvr_interface;
- // process all our active interfaces
- ARVRServer::get_singleton()->_process();
+ if (ARVRServer::get_singleton() != NULL) {
+ arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+
+ // process all our active interfaces
+ ARVRServer::get_singleton()->_process();
+ }
if (Engine::get_singleton()->is_editor_hint()) {
clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
@@ -452,7 +461,7 @@ void VisualServerViewport::viewport_set_render_direct_to_screen(RID p_viewport,
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
viewport->viewport_render_direct_to_screen = p_enable;
- // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unneccesary buffer allocation
+ // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
if (VSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
VSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 24e50eb99e..273cf728c1 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -35,9 +35,6 @@
#include "core/os/thread.h"
#include "servers/visual_server.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServerWrapMT : public VisualServer {
// the real visual server
@@ -233,7 +230,6 @@ public:
FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &)
- FUNC3(skeleton_set_world_transform, RID, bool, const Transform &)
/* Light API */
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index c6468694fd..13fcda2402 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1118,7 +1118,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
}
offsets[i] = elem_size;
continue;
- } break;
+ }
default: {
ERR_FAIL();
}
@@ -1145,11 +1145,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
Vector<AABB> bone_aabb;
Error err = _surface_set_data(p_arrays, format, offsets, total_elem_size, vertex_array, array_len, index_array, index_array_len, aabb, bone_aabb);
-
- if (err) {
- ERR_EXPLAIN("Invalid array format for surface");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(err, "Invalid array format for surface.");
Vector<PoolVector<uint8_t> > blend_shape_data;
@@ -1162,10 +1158,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
AABB laabb;
Error err2 = _surface_set_data(p_blend_shapes[i], format & ~ARRAY_FORMAT_INDEX, offsets, total_elem_size, vertex_array_shape, array_len, noindex, 0, laabb, bone_aabb);
aabb.merge_with(laabb);
- if (err2 != OK) {
- ERR_EXPLAIN("Invalid blend shape array format for surface");
- ERR_FAIL();
- }
+ ERR_FAIL_COND_MSG(err2 != OK, "Invalid blend shape array format for surface.");
blend_shape_data.push_back(vertex_array_shape);
}
@@ -1286,7 +1279,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
}
offsets[i] = elem_size;
continue;
- } break;
+ }
default: {
ERR_FAIL_V(Array());
}
diff --git a/servers/visual_server.h b/servers/visual_server.h
index a84d395e3f..5e6c4d9b1e 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -39,9 +39,6 @@
#include "core/rid.h"
#include "core/variant.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class VisualServer : public Object {
GDCLASS(VisualServer, Object);
@@ -394,7 +391,6 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) = 0;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
- virtual void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_base_transform) = 0;
/* Light API */
diff --git a/thirdparty/README.md b/thirdparty/README.md
index dbdf9bbf4f..3f2fc6d8f9 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -4,7 +4,7 @@
## assimp
- Upstream: http://github.com/assimp/assimp
-- Version: git (d3d98a7ec0c8d38e1952b46dfe53f7e9233dc92d)
+- Version: git (1d565b0aab5a2ee00462f18c5b8a81f6a5454a48)
- License: BSD-3-Clause
@@ -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.
@@ -200,6 +200,7 @@ Important: Some files have Godot-made changes.
They are marked with `// -- GODOT start --` and `// -- GODOT end --`
comments.
+
## libtheora
- Upstream: https://www.theora.org
@@ -262,25 +263,13 @@ changes to ensure they build for Javascript/HTML5. Those
changes are marked with `// -- GODOT --` comments.
-## wslay
-
-- Upstream: https://github.com/tatsuhiro-t/wslay
-- Version: 1.1.0
-- License: MIT
-
-File extracted from upstream releaze 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).
@@ -391,7 +380,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
@@ -426,8 +415,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:
@@ -508,10 +497,23 @@ They can be reapplied using the patches included in the `vhacd`
folder.
+## wslay
+
+- Upstream: https://github.com/tatsuhiro-t/wslay
+- Version: 1.1.0
+- License: MIT
+
+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`
+
+
## xatlas
- Upstream: https://github.com/jpcy/xatlas
-- Version: git (b8ec29b, 2018)
+- Version: git (b4b5426, 2019)
- License: MIT
Files extracted from upstream source:
@@ -536,7 +538,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.4.0
+- Version: 1.4.1
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/assimp/assimp/config.h b/thirdparty/assimp/assimp/config.h
index 8b0634d28b..d0e4817349 100644
--- a/thirdparty/assimp/assimp/config.h
+++ b/thirdparty/assimp/assimp/config.h
@@ -647,6 +647,21 @@ enum aiComponent {
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall not remove empty bones.
+ *
+ *
+ * Empty bone are often used to define connections for other models.
+ */
+#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
+ "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+ "AI_CONFIG_FBX_CONVERT_TO_M"
+
+// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
* ASSIMP does not support vertex keyframes (only bone animation is supported).
@@ -968,6 +983,13 @@ enum aiComponent {
#define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
#endif // !! AI_DEBONE_THRESHOLD
+#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_APP_SCALE_KEY)
+# define AI_CONFIG_APP_SCALE_KEY 1.0
+#endif // AI_CONFIG_APP_SCALE_KEY
+
+
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
@@ -978,3 +1000,4 @@ enum aiComponent {
/* #cmakedefine ASSIMP_DOUBLE_PRECISION 1 */
#endif // !! AI_CONFIG_H_INC
+
diff --git a/thirdparty/assimp/code/CApi/AssimpCExport.cpp b/thirdparty/assimp/code/CApi/AssimpCExport.cpp
new file mode 100644
index 0000000000..7557edcfc6
--- /dev/null
+++ b/thirdparty/assimp/code/CApi/AssimpCExport.cpp
@@ -0,0 +1,156 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of the assimp team.
+
+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.
+---------------------------------------------------------------------------
+*/
+
+/** @file AssimpCExport.cpp
+Assimp C export interface. See Exporter.cpp for some notes.
+*/
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+#include "CInterfaceIOWrapper.h"
+#include <assimp/SceneCombiner.h>
+#include "Common/ScenePrivate.h"
+#include <assimp/Exporter.hpp>
+
+using namespace Assimp;
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API size_t aiGetExportFormatCount(void)
+{
+ return Exporter().GetExportFormatCount();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
+{
+ // Note: this is valid as the index always pertains to a built-in exporter,
+ // for which the returned structure is guaranteed to be of static storage duration.
+ Exporter exporter;
+ const aiExportFormatDesc* orig( exporter.GetExportFormatDescription( index ) );
+ if (NULL == orig) {
+ return NULL;
+ }
+
+ aiExportFormatDesc *desc = new aiExportFormatDesc;
+ desc->description = new char[ strlen( orig->description ) + 1 ]();
+ ::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
+ desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
+ ::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
+ desc->id = new char[ strlen( orig->id ) + 1 ]();
+ ::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
+
+ return desc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiReleaseExportFormatDescription( const aiExportFormatDesc *desc ) {
+ if (NULL == desc) {
+ return;
+ }
+
+ delete [] desc->description;
+ delete [] desc->fileExtension;
+ delete [] desc->id;
+ delete desc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
+{
+ if (!pOut || !pIn) {
+ return;
+ }
+
+ SceneCombiner::CopyScene(pOut,pIn,true);
+ ScenePriv(*pOut)->mIsCopy = true;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
+{
+ // note: aiReleaseImport() is also able to delete scene copies, but in addition
+ // it also handles scenes with import metadata.
+ delete pIn;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
+{
+ return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
+{
+ Exporter exp;
+
+ if (pIO) {
+ exp.SetIOHandler(new CIOSystemWrapper(pIO));
+ }
+ return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
+{
+ Exporter exp;
+ if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
+ return NULL;
+ }
+ const aiExportDataBlob* blob = exp.GetOrphanedBlob();
+ ai_assert(blob);
+
+ return blob;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
+{
+ delete pData;
+}
+
+#endif // !ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/CInterfaceIOWrapper.cpp b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp
index 5a3a49565a..5a3a49565a 100644
--- a/thirdparty/assimp/code/CInterfaceIOWrapper.cpp
+++ b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp
diff --git a/thirdparty/assimp/code/CInterfaceIOWrapper.h b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h
index 2162320302..2162320302 100644
--- a/thirdparty/assimp/code/CInterfaceIOWrapper.h
+++ b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h
diff --git a/thirdparty/assimp/code/Common/Assimp.cpp b/thirdparty/assimp/code/Common/Assimp.cpp
new file mode 100644
index 0000000000..178b2c01d0
--- /dev/null
+++ b/thirdparty/assimp/code/Common/Assimp.cpp
@@ -0,0 +1,695 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of the assimp team.
+
+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.
+---------------------------------------------------------------------------
+*/
+/** @file Assimp.cpp
+ * @brief Implementation of the Plain-C API
+ */
+
+#include <assimp/cimport.h>
+#include <assimp/LogStream.hpp>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/importerdesc.h>
+#include <assimp/scene.h>
+#include <assimp/GenericProperty.h>
+#include <assimp/Exceptional.h>
+#include <assimp/BaseImporter.h>
+
+#include "CApi/CInterfaceIOWrapper.h"
+#include "Importer.h"
+#include "ScenePrivate.h"
+
+#include <list>
+
+// ------------------------------------------------------------------------------------------------
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+# include <thread>
+# include <mutex>
+#endif
+// ------------------------------------------------------------------------------------------------
+using namespace Assimp;
+
+namespace Assimp {
+ // underlying structure for aiPropertyStore
+ typedef BatchLoader::PropertyMap PropertyMap;
+
+ /** Stores the LogStream objects for all active C log streams */
+ struct mpred {
+ bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
+ return s0.callback<s1.callback&&s0.user<s1.user;
+ }
+ };
+ typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
+
+ /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
+ typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
+
+ /** Local storage of all active log streams */
+ static LogStreamMap gActiveLogStreams;
+
+ /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
+ static PredefLogStreamMap gPredefinedStreams;
+
+ /** Error message of the last failed import process */
+ static std::string gLastErrorString;
+
+ /** Verbose logging active or not? */
+ static aiBool gVerboseLogging = false;
+
+ /** will return all registered importers. */
+ void GetImporterInstanceList(std::vector< BaseImporter* >& out);
+
+ /** will delete all registered importers. */
+ void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
+} // namespace assimp
+
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+/** Global mutex to manage the access to the log-stream map */
+static std::mutex gLogStreamMutex;
+#endif
+
+// ------------------------------------------------------------------------------------------------
+// Custom LogStream implementation for the C-API
+class LogToCallbackRedirector : public LogStream {
+public:
+ explicit LogToCallbackRedirector(const aiLogStream& s)
+ : stream (s) {
+ ai_assert(NULL != s.callback);
+ }
+
+ ~LogToCallbackRedirector() {
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ // (HACK) Check whether the 'stream.user' pointer points to a
+ // custom LogStream allocated by #aiGetPredefinedLogStream.
+ // In this case, we need to delete it, too. Of course, this
+ // might cause strange problems, but the chance is quite low.
+
+ PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
+ gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
+
+ if (it != gPredefinedStreams.end()) {
+ delete *it;
+ gPredefinedStreams.erase(it);
+ }
+ }
+
+ /** @copydoc LogStream::write */
+ void write(const char* message) {
+ stream.callback(message,stream.user);
+ }
+
+private:
+ aiLogStream stream;
+};
+
+// ------------------------------------------------------------------------------------------------
+void ReportSceneNotFoundError() {
+ ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. "
+ "The C-API does not accept scenes produced by the C++ API and vice versa");
+
+ ai_assert(false);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads the given file and returns its content.
+const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
+ return aiImportFileEx(pFile,pFlags,NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
+ return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
+ aiFileIO* pFS, const aiPropertyStore* props) {
+ ai_assert(NULL != pFile);
+
+ const aiScene* scene = NULL;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // create an Importer for this file
+ Assimp::Importer* imp = new Assimp::Importer();
+
+ // copy properties
+ if(props) {
+ const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
+ ImporterPimpl* pimpl = imp->Pimpl();
+ pimpl->mIntProperties = pp->ints;
+ pimpl->mFloatProperties = pp->floats;
+ pimpl->mStringProperties = pp->strings;
+ pimpl->mMatrixProperties = pp->matrices;
+ }
+ // setup a custom IO system if necessary
+ if (pFS) {
+ imp->SetIOHandler( new CIOSystemWrapper (pFS) );
+ }
+
+ // and have it read the file
+ scene = imp->ReadFile( pFile, pFlags);
+
+ // if succeeded, store the importer in the scene and keep it alive
+ if( scene) {
+ ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
+ priv->mOrigImporter = imp;
+ } else {
+ // if failed, extract error code and destroy the import
+ gLastErrorString = imp->GetErrorString();
+ delete imp;
+ }
+
+ // return imported data. If the import failed the pointer is NULL anyways
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+
+ return scene;
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileFromMemory(
+ const char* pBuffer,
+ unsigned int pLength,
+ unsigned int pFlags,
+ const char* pHint)
+{
+ return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileFromMemoryWithProperties(
+ const char* pBuffer,
+ unsigned int pLength,
+ unsigned int pFlags,
+ const char* pHint,
+ const aiPropertyStore* props)
+{
+ ai_assert( NULL != pBuffer );
+ ai_assert( 0 != pLength );
+
+ const aiScene* scene = NULL;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // create an Importer for this file
+ Assimp::Importer* imp = new Assimp::Importer();
+
+ // copy properties
+ if(props) {
+ const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
+ ImporterPimpl* pimpl = imp->Pimpl();
+ pimpl->mIntProperties = pp->ints;
+ pimpl->mFloatProperties = pp->floats;
+ pimpl->mStringProperties = pp->strings;
+ pimpl->mMatrixProperties = pp->matrices;
+ }
+
+ // and have it read the file from the memory buffer
+ scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
+
+ // if succeeded, store the importer in the scene and keep it alive
+ if( scene) {
+ ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
+ priv->mOrigImporter = imp;
+ }
+ else {
+ // if failed, extract error code and destroy the import
+ gLastErrorString = imp->GetErrorString();
+ delete imp;
+ }
+ // return imported data. If the import failed the pointer is NULL anyways
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+ return scene;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Releases all resources associated with the given import process.
+void aiReleaseImport( const aiScene* pScene)
+{
+ if (!pScene) {
+ return;
+ }
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pScene);
+ if( !priv || !priv->mOrigImporter) {
+ delete pScene;
+ }
+ else {
+ // deleting the Importer also deletes the scene
+ // Note: the reason that this is not written as 'delete priv->mOrigImporter'
+ // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
+ Importer* importer = priv->mOrigImporter;
+ delete importer;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
+ unsigned int pFlags)
+{
+ const aiScene* sc = NULL;
+
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pScene);
+ if( !priv || !priv->mOrigImporter) {
+ ReportSceneNotFoundError();
+ return NULL;
+ }
+
+ sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
+
+ if (!sc) {
+ aiReleaseImport(pScene);
+ return NULL;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+ return sc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene,
+ BaseProcess* process,
+ bool requestValidation ) {
+ const aiScene* sc( NULL );
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv( scene );
+ if ( NULL == priv || NULL == priv->mOrigImporter ) {
+ ReportSceneNotFoundError();
+ return NULL;
+ }
+
+ sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation );
+
+ if ( !sc ) {
+ aiReleaseImport( scene );
+ return NULL;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION( const aiScene* );
+
+ return sc;
+}
+
+// ------------------------------------------------------------------------------------------------
+void CallbackToLogRedirector (const char* msg, char* dt)
+{
+ ai_assert( NULL != msg );
+ ai_assert( NULL != dt );
+ LogStream* s = (LogStream*)dt;
+
+ s->write(msg);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
+{
+ aiLogStream sout;
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ LogStream* stream = LogStream::createDefaultStream(pStream,file);
+ if (!stream) {
+ sout.callback = NULL;
+ sout.user = NULL;
+ }
+ else {
+ sout.callback = &CallbackToLogRedirector;
+ sout.user = (char*)stream;
+ }
+ gPredefinedStreams.push_back(stream);
+ ASSIMP_END_EXCEPTION_REGION(aiLogStream);
+ return sout;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+
+ LogStream* lg = new LogToCallbackRedirector(*stream);
+ gActiveLogStreams[*stream] = lg;
+
+ if (DefaultLogger::isNullLogger()) {
+ DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
+ }
+ DefaultLogger::get()->attachStream(lg);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ // find the log-stream associated with this data
+ LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
+ // it should be there... else the user is playing fools with us
+ if( it == gActiveLogStreams.end()) {
+ return AI_FAILURE;
+ }
+ DefaultLogger::get()->detatchStream( it->second );
+ delete it->second;
+
+ gActiveLogStreams.erase( it);
+
+ if (gActiveLogStreams.empty()) {
+ DefaultLogger::kill();
+ }
+ ASSIMP_END_EXCEPTION_REGION(aiReturn);
+ return AI_SUCCESS;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiDetachAllLogStreams(void)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ Logger *logger( DefaultLogger::get() );
+ if ( NULL == logger ) {
+ return;
+ }
+
+ for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
+ logger->detatchStream( it->second );
+ delete it->second;
+ }
+ gActiveLogStreams.clear();
+ DefaultLogger::kill();
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiEnableVerboseLogging(aiBool d)
+{
+ if (!DefaultLogger::isNullLogger()) {
+ DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
+ }
+ gVerboseLogging = d;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns the error text of the last failed import process.
+const char* aiGetErrorString()
+{
+ return gLastErrorString.c_str();
+}
+
+// -----------------------------------------------------------------------------------------------
+// Return the description of a importer given its index
+const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
+{
+ return Importer().GetImporterInfo(pIndex);
+}
+
+// -----------------------------------------------------------------------------------------------
+// Return the number of importers
+size_t aiGetImportFormatCount(void)
+{
+ return Importer().GetImporterCount();
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns the error text of the last failed import process.
+aiBool aiIsExtensionSupported(const char* szExtension)
+{
+ ai_assert(NULL != szExtension);
+ aiBool candoit=AI_FALSE;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // FIXME: no need to create a temporary Importer instance just for that ..
+ Assimp::Importer tmp;
+ candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
+
+ ASSIMP_END_EXCEPTION_REGION(aiBool);
+ return candoit;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get a list of all file extensions supported by ASSIMP
+void aiGetExtensionList(aiString* szOut)
+{
+ ai_assert(NULL != szOut);
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // FIXME: no need to create a temporary Importer instance just for that ..
+ Assimp::Importer tmp;
+ tmp.GetExtensionList(*szOut);
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get the memory requirements for a particular import.
+void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
+ C_STRUCT aiMemoryInfo* in)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pIn);
+ if( !priv || !priv->mOrigImporter) {
+ ReportSceneNotFoundError();
+ return;
+ }
+
+ return priv->mOrigImporter->GetMemoryRequirements(*in);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
+{
+ return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
+{
+ delete reinterpret_cast<PropertyMap*>(p);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyInteger
+ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<int>(pp->ints,szName,value);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyFloat
+ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<ai_real>(pp->floats,szName,value);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyString
+ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
+ const C_STRUCT aiString* st)
+{
+ if (!st) {
+ return;
+ }
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyMatrix
+ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
+ const C_STRUCT aiMatrix4x4* mat)
+{
+ if (!mat) {
+ return;
+ }
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Rotation matrix to quaternion
+ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
+{
+ ai_assert( NULL != quat );
+ ai_assert( NULL != mat );
+ *quat = aiQuaternion(*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix decomposition
+ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
+ aiQuaternion* rotation,
+ aiVector3D* position)
+{
+ ai_assert( NULL != rotation );
+ ai_assert( NULL != position );
+ ai_assert( NULL != scaling );
+ ai_assert( NULL != mat );
+ mat->Decompose(*scaling,*rotation,*position);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix transpose
+ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
+{
+ ai_assert(NULL != mat);
+ mat->Transpose();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
+{
+ ai_assert(NULL != mat);
+ mat->Transpose();
+}
+
+// ------------------------------------------------------------------------------------------------
+// Vector transformation
+ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
+ const aiMatrix3x3* mat)
+{
+ ai_assert( NULL != mat );
+ ai_assert( NULL != vec);
+ *vec *= (*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
+ const aiMatrix4x4* mat)
+{
+ ai_assert( NULL != mat );
+ ai_assert( NULL != vec );
+
+ *vec *= (*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix multiplication
+ASSIMP_API void aiMultiplyMatrix4(
+ aiMatrix4x4* dst,
+ const aiMatrix4x4* src)
+{
+ ai_assert( NULL != dst );
+ ai_assert( NULL != src );
+ *dst = (*dst) * (*src);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiMultiplyMatrix3(
+ aiMatrix3x3* dst,
+ const aiMatrix3x3* src)
+{
+ ai_assert( NULL != dst );
+ ai_assert( NULL != src );
+ *dst = (*dst) * (*src);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix identity
+ASSIMP_API void aiIdentityMatrix3(
+ aiMatrix3x3* mat)
+{
+ ai_assert(NULL != mat);
+ *mat = aiMatrix3x3();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiIdentityMatrix4(
+ aiMatrix4x4* mat)
+{
+ ai_assert(NULL != mat);
+ *mat = aiMatrix4x4();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
+ if( NULL == extension ) {
+ return NULL;
+ }
+ const aiImporterDesc *desc( NULL );
+ std::vector< BaseImporter* > out;
+ GetImporterInstanceList( out );
+ for( size_t i = 0; i < out.size(); ++i ) {
+ if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
+ desc = out[ i ]->GetInfo();
+ break;
+ }
+ }
+
+ DeleteImporterInstanceList(out);
+
+ return desc;
+}
+
+// ------------------------------------------------------------------------------------------------
diff --git a/thirdparty/assimp/code/BaseImporter.cpp b/thirdparty/assimp/code/Common/BaseImporter.cpp
index 4803c6d6f2..de5018a250 100644
--- a/thirdparty/assimp/code/BaseImporter.cpp
+++ b/thirdparty/assimp/code/Common/BaseImporter.cpp
@@ -76,9 +76,25 @@ BaseImporter::~BaseImporter() {
// nothing to do here
}
+void BaseImporter::UpdateImporterScale( Importer* pImp )
+{
+ ai_assert(pImp != nullptr);
+ ai_assert(importerScale != 0.0);
+ ai_assert(fileScale != 0.0);
+
+ double activeScale = importerScale * fileScale;
+
+ // Set active scaling
+ pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
+
+ ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
+}
+
// ------------------------------------------------------------------------------------------------
// Imports the given file and returns the imported data.
-aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
+aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
+
+
m_progress = pImp->GetProgressHandler();
if (nullptr == m_progress) {
return nullptr;
@@ -100,6 +116,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
{
InternReadFile( pFile, sc.get(), &filter);
+ // Calculate import scale hook - required because pImp not available anywhere else
+ // passes scale into ScaleProcess
+ UpdateImporterScale(pImp);
+
+
} catch( const std::exception& err ) {
// extract error description
m_ErrorText = err.what();
@@ -112,7 +133,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
}
// ------------------------------------------------------------------------------------------------
-void BaseImporter::SetupProperties(const Importer* /*pImp*/)
+void BaseImporter::SetupProperties(const Importer* pImp)
{
// the default implementation does nothing
}
@@ -320,7 +341,11 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
return false;
}
-#include "../contrib/utf8cpp/source/utf8.h"
+#ifdef ASSIMP_USE_HUNTER
+# include <utf8/utf8.h>
+#else
+# include "../contrib/utf8cpp/source/utf8.h"
+#endif
// ------------------------------------------------------------------------------------------------
// Convert to UTF8 data
@@ -584,6 +609,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
return nullptr;
}
+
+
// ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll()
{
diff --git a/thirdparty/assimp/code/BaseProcess.cpp b/thirdparty/assimp/code/Common/BaseProcess.cpp
index 18872c3693..e247be418d 100644
--- a/thirdparty/assimp/code/BaseProcess.cpp
+++ b/thirdparty/assimp/code/Common/BaseProcess.cpp
@@ -89,7 +89,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
// and kill the partially imported data
delete pImp->Pimpl()->mScene;
- pImp->Pimpl()->mScene = NULL;
+ pImp->Pimpl()->mScene = nullptr;
}
}
diff --git a/thirdparty/assimp/code/BaseProcess.h b/thirdparty/assimp/code/Common/BaseProcess.h
index 4d5c7a76be..4d5c7a76be 100644
--- a/thirdparty/assimp/code/BaseProcess.h
+++ b/thirdparty/assimp/code/Common/BaseProcess.h
diff --git a/thirdparty/assimp/code/Bitmap.cpp b/thirdparty/assimp/code/Common/Bitmap.cpp
index b22b71ea9e..b22b71ea9e 100644
--- a/thirdparty/assimp/code/Bitmap.cpp
+++ b/thirdparty/assimp/code/Common/Bitmap.cpp
diff --git a/thirdparty/assimp/code/CreateAnimMesh.cpp b/thirdparty/assimp/code/Common/CreateAnimMesh.cpp
index 1a052849bb..98b60e5319 100644
--- a/thirdparty/assimp/code/CreateAnimMesh.cpp
+++ b/thirdparty/assimp/code/Common/CreateAnimMesh.cpp
@@ -47,10 +47,6 @@ namespace Assimp {
aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
{
aiAnimMesh *animesh = new aiAnimMesh;
- animesh->mVertices = NULL;
- animesh->mNormals = NULL;
- animesh->mTangents = NULL;
- animesh->mBitangents = NULL;
animesh->mNumVertices = mesh->mNumVertices;
if (mesh->mVertices) {
animesh->mVertices = new aiVector3D[animesh->mNumVertices];
diff --git a/thirdparty/assimp/code/DefaultIOStream.cpp b/thirdparty/assimp/code/Common/DefaultIOStream.cpp
index 1c100b6189..1c100b6189 100644
--- a/thirdparty/assimp/code/DefaultIOStream.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOStream.cpp
diff --git a/thirdparty/assimp/code/DefaultIOSystem.cpp b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
index d40b67de32..d40b67de32 100644
--- a/thirdparty/assimp/code/DefaultIOSystem.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
diff --git a/thirdparty/assimp/code/DefaultLogger.cpp b/thirdparty/assimp/code/Common/DefaultLogger.cpp
index de3528d2b4..de3528d2b4 100644
--- a/thirdparty/assimp/code/DefaultLogger.cpp
+++ b/thirdparty/assimp/code/Common/DefaultLogger.cpp
diff --git a/thirdparty/assimp/code/DefaultProgressHandler.h b/thirdparty/assimp/code/Common/DefaultProgressHandler.h
index bd2cce00be..bd2cce00be 100644
--- a/thirdparty/assimp/code/DefaultProgressHandler.h
+++ b/thirdparty/assimp/code/Common/DefaultProgressHandler.h
diff --git a/thirdparty/assimp/code/Exporter.cpp b/thirdparty/assimp/code/Common/Exporter.cpp
index 8848e87f5b..090b561ae0 100644
--- a/thirdparty/assimp/code/Exporter.cpp
+++ b/thirdparty/assimp/code/Common/Exporter.cpp
@@ -61,15 +61,16 @@ Here we implement only the C++ interface (Assimp::Exporter).
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
-
-#include "DefaultProgressHandler.h"
-#include "BaseProcess.h"
-#include "JoinVerticesProcess.h"
-#include "MakeVerboseFormat.h"
-#include "ConvertToLHProcess.h"
-#include "PretransformVertices.h"
#include <assimp/Exceptional.h>
-#include "ScenePrivate.h"
+
+#include "Common/DefaultProgressHandler.h"
+#include "Common/BaseProcess.h"
+#include "Common/ScenePrivate.h"
+#include "PostProcessing/CalcTangentsProcess.h"
+#include "PostProcessing/MakeVerboseFormat.h"
+#include "PostProcessing/JoinVerticesProcess.h"
+#include "PostProcessing/ConvertToLHProcess.h"
+#include "PostProcessing/PretransformVertices.h"
#include <memory>
@@ -101,6 +102,7 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
+void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
// ------------------------------------------------------------------------------------------------
// global array of all export formats which Assimp supports in its current build
@@ -161,11 +163,11 @@ Exporter::ExportFormatEntry gExporters[] =
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
- Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0 ),
+ Exporter::ExportFormatEntry( "assbin", "Assimp Binary File", "assbin" , &ExportSceneAssbin, 0 ),
#endif
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
- Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0 ),
+ Exporter::ExportFormatEntry( "assxml", "Assimp XML Document", "assxml" , &ExportSceneAssxml, 0 ),
#endif
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
@@ -178,7 +180,11 @@ Exporter::ExportFormatEntry gExporters[] =
#endif
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
- Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
+ Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 ),
+#endif
+
+#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
+ Exporter::ExportFormatEntry( "assjson", "Assimp JSON Document", "json", &ExportAssimp2Json, 0)
#endif
};
@@ -288,7 +294,7 @@ void Exporter::SetProgressHandler(ProgressHandler* pHandler) {
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
- unsigned int, const ExportProperties* /*pProperties*/ ) {
+ unsigned int pPreprocessing, const ExportProperties* pProperties) {
if (pimpl->blob) {
delete pimpl->blob;
pimpl->blob = nullptr;
@@ -298,7 +304,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
BlobIOSystem* blobio = new BlobIOSystem();
pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
- if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
+ if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) {
pimpl->mIOSystem = old;
return nullptr;
}
diff --git a/thirdparty/assimp/code/FileLogStream.h b/thirdparty/assimp/code/Common/FileLogStream.h
index 740c503192..740c503192 100644
--- a/thirdparty/assimp/code/FileLogStream.h
+++ b/thirdparty/assimp/code/Common/FileLogStream.h
diff --git a/thirdparty/assimp/code/FileSystemFilter.h b/thirdparty/assimp/code/Common/FileSystemFilter.h
index 9923cdbdd3..9923cdbdd3 100644
--- a/thirdparty/assimp/code/FileSystemFilter.h
+++ b/thirdparty/assimp/code/Common/FileSystemFilter.h
diff --git a/thirdparty/assimp/code/Common/IFF.h b/thirdparty/assimp/code/Common/IFF.h
new file mode 100644
index 0000000000..91d7d48289
--- /dev/null
+++ b/thirdparty/assimp/code/Common/IFF.h
@@ -0,0 +1,102 @@
+// Definitions for the Interchange File Format (IFF)
+// Alexander Gessler, 2006
+// Adapted to Assimp August 2008
+
+#ifndef AI_IFF_H_INCLUDED
+#define AI_IFF_H_INCLUDED
+
+#include <assimp/ByteSwapper.h>
+
+namespace Assimp {
+namespace IFF {
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Describes an IFF chunk header
+/////////////////////////////////////////////////////////////////////////////////
+struct ChunkHeader
+{
+ //! Type of the chunk header - FourCC
+ uint32_t type;
+
+ //! Length of the chunk data, in bytes
+ uint32_t length;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Describes an IFF sub chunk header
+/////////////////////////////////////////////////////////////////////////////////
+struct SubChunkHeader
+{
+ //! Type of the chunk header - FourCC
+ uint32_t type;
+
+ //! Length of the chunk data, in bytes
+ uint16_t length;
+};
+
+
+#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
+ ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
+
+
+#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Load a chunk header
+//! @param outFile Pointer to the file data - points to the chunk data afterwards
+//! @return Copy of the chunk header
+/////////////////////////////////////////////////////////////////////////////////
+inline ChunkHeader LoadChunk(uint8_t*& outFile)
+{
+ ChunkHeader head;
+ ::memcpy(&head.type, outFile, 4);
+ outFile += 4;
+ ::memcpy(&head.length, outFile, 4);
+ outFile += 4;
+ AI_LSWAP4(head.length);
+ AI_LSWAP4(head.type);
+ return head;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Load a sub chunk header
+//! @param outFile Pointer to the file data - points to the chunk data afterwards
+//! @return Copy of the sub chunk header
+/////////////////////////////////////////////////////////////////////////////////
+inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
+{
+ SubChunkHeader head;
+ ::memcpy(&head.type, outFile, 4);
+ outFile += 4;
+ ::memcpy(&head.length, outFile, 2);
+ outFile += 2;
+ AI_LSWAP2(head.length);
+ AI_LSWAP4(head.type);
+ return head;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Read the file header and return the type of the file and its size
+//! @param outFile Pointer to the file data. The buffer must at
+//! least be 12 bytes large.
+//! @param fileType Receives the type of the file
+//! @return 0 if everything was OK, otherwise an error message
+/////////////////////////////////////////////////////////////////////////////////
+inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
+{
+ ChunkHeader head = LoadChunk(outFile);
+ if(AI_IFF_FOURCC_FORM != head.type)
+ {
+ return "The file is not an IFF file: FORM chunk is missing";
+ }
+ ::memcpy(&fileType, outFile, 4);
+ AI_LSWAP4(fileType);
+ return 0;
+}
+
+
+}}
+
+#endif // !! AI_IFF_H_INCLUDED
diff --git a/thirdparty/assimp/code/Importer.cpp b/thirdparty/assimp/code/Common/Importer.cpp
index 65b16471cc..91b50859a0 100644
--- a/thirdparty/assimp/code/Importer.cpp
+++ b/thirdparty/assimp/code/Common/Importer.cpp
@@ -64,15 +64,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
// Internal headers
// ------------------------------------------------------------------------------------------------
-#include "Importer.h"
-#include <assimp/BaseImporter.h>
-#include "BaseProcess.h"
+#include "Common/Importer.h"
+#include "Common/BaseProcess.h"
+#include "Common/DefaultProgressHandler.h"
+#include "PostProcessing/ProcessHelper.h"
+#include "Common/ScenePreprocessor.h"
+#include "Common/ScenePrivate.h"
-#include "DefaultProgressHandler.h"
+#include <assimp/BaseImporter.h>
#include <assimp/GenericProperty.h>
-#include "ProcessHelper.h"
-#include "ScenePreprocessor.h"
-#include "ScenePrivate.h"
#include <assimp/MemoryIOWrapper.h>
#include <assimp/Profiler.h>
#include <assimp/TinyFormatter.h>
@@ -86,7 +86,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultIOSystem.h>
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
+# include "PostProcessing/ValidateDataStructure.h"
#endif
using namespace Assimp::Profiling;
@@ -590,10 +590,12 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
// Find an worker class which can handle the file
BaseImporter* imp = NULL;
+ SetPropertyInteger("importerIndex", -1);
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
imp = pimpl->mImporter[a];
+ SetPropertyInteger("importerIndex", a);
break;
}
}
@@ -606,6 +608,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
imp = pimpl->mImporter[a];
+ SetPropertyInteger("importerIndex", a);
break;
}
}
diff --git a/thirdparty/assimp/code/Importer.h b/thirdparty/assimp/code/Common/Importer.h
index a439d99c2f..a439d99c2f 100644
--- a/thirdparty/assimp/code/Importer.h
+++ b/thirdparty/assimp/code/Common/Importer.h
diff --git a/thirdparty/assimp/code/ImporterRegistry.cpp b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
index 747815fa6f..32ac3b4168 100644
--- a/thirdparty/assimp/code/ImporterRegistry.cpp
+++ b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
@@ -56,146 +56,146 @@ corresponding preprocessor flag to selectively disable formats.
// (include_new_importers_here)
// ------------------------------------------------------------------------------------------------
#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-# include "XFileImporter.h"
+# include "X/XFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-# include "AMFImporter.hpp"
+# include "AMF/AMFImporter.hpp"
#endif
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-# include "3DSLoader.h"
+# include "3DS/3DSLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-# include "MD3Loader.h"
+# include "MD3/MD3Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-# include "MDLLoader.h"
+# include "MDL/MDLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
-# include "MD2Loader.h"
+# include "MD2/MD2Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-# include "PlyLoader.h"
+# include "Ply/PlyLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-# include "ASELoader.h"
+# include "ASE/ASELoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-# include "ObjFileImporter.h"
+# include "Obj/ObjFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-# include "HMPLoader.h"
+# include "HMP/HMPLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-# include "SMDLoader.h"
+# include "SMD/SMDLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-# include "MDCLoader.h"
+# include "MDC/MDCLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-# include "MD5Loader.h"
+# include "MD5/MD5Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-# include "STLLoader.h"
+# include "STL/STLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-# include "LWOLoader.h"
+# include "LWO/LWOLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-# include "DXFLoader.h"
+# include "DXF/DXFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-# include "NFFLoader.h"
+# include "NFF/NFFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-# include "RawLoader.h"
+# include "Raw/RawLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
-# include "SIBImporter.h"
+# include "SIB/SIBImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-# include "OFFLoader.h"
+# include "OFF/OFFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-# include "ACLoader.h"
+# include "AC/ACLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
-# include "BVHLoader.h"
+# include "BVH/BVHLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-# include "IRRMeshLoader.h"
+# include "Irr/IRRMeshLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
-# include "IRRLoader.h"
+# include "Irr/IRRLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-# include "Q3DLoader.h"
+# include "Q3D/Q3DLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-# include "B3DImporter.h"
+# include "B3D/B3DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-# include "ColladaLoader.h"
+# include "Collada/ColladaLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-# include "TerragenLoader.h"
+# include "Terragen/TerragenLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-# include "CSMLoader.h"
+# include "CSM/CSMLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-# include "UnrealLoader.h"
+# include "Unreal/UnrealLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
-# include "LWSLoader.h"
+# include "LWS/LWSLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-# include "OgreImporter.h"
+# include "Ogre/OgreImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-# include "OpenGEXImporter.h"
+# include "OpenGEX/OpenGEXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-# include "MS3DLoader.h"
+# include "MS3D/MS3DLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-# include "COBLoader.h"
+# include "COB/COBLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-# include "BlenderLoader.h"
+# include "Blender/BlenderLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-# include "Q3BSPFileImporter.h"
+# include "Q3BSP/Q3BSPFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
-# include "NDOLoader.h"
+# include "NDO/NDOLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
# include "Importer/IFC/IFCLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
-# include "XGLLoader.h"
+# include "XGL/XGLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-# include "FBXImporter.h"
+# include "FBX/FBXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-# include "AssbinLoader.h"
+# include "Assbin/AssbinLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-# include "glTFImporter.h"
-# include "glTF2Importer.h"
+# include "glTF/glTFImporter.h"
+# include "glTF2/glTF2Importer.h"
#endif
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
-# include "C4DImporter.h"
+# include "C4D/C4DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
-# include "D3MFImporter.h"
+# include "3MF/D3MFImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-# include "X3DImporter.hpp"
+# include "X3D/X3DImporter.hpp"
#endif
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-# include "MMDImporter.h"
+# include "MMD/MMDImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
@@ -364,7 +364,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){
for(size_t i= 0; i<deleteList.size();++i){
delete deleteList[i];
- deleteList[i]=NULL;
+ deleteList[i]=nullptr;
}//for
}
diff --git a/thirdparty/assimp/code/PolyTools.h b/thirdparty/assimp/code/Common/PolyTools.h
index fbbda0e7d1..fbbda0e7d1 100644
--- a/thirdparty/assimp/code/PolyTools.h
+++ b/thirdparty/assimp/code/Common/PolyTools.h
diff --git a/thirdparty/assimp/code/PostStepRegistry.cpp b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
index 15b4a28843..ef58f8ddfd 100644
--- a/thirdparty/assimp/code/PostStepRegistry.cpp
+++ b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
@@ -48,89 +48,93 @@ directly (unless you are adding new steps), instead use the
corresponding preprocessor flag to selectively disable steps.
*/
-#include "ProcessHelper.h"
+#include "PostProcessing/ProcessHelper.h"
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
-# include "CalcTangentsProcess.h"
+# include "PostProcessing/CalcTangentsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-# include "JoinVerticesProcess.h"
+# include "PostProcessing/JoinVerticesProcess.h"
#endif
#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
-# include "ConvertToLHProcess.h"
+# include "PostProcessing/ConvertToLHProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-# include "TriangulateProcess.h"
+# include "PostProcessing/TriangulateProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS
-# include "DropFaceNormalsProcess.h"
+# include "PostProcessing/DropFaceNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
-# include "GenFaceNormalsProcess.h"
+# include "PostProcessing/GenFaceNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
-# include "GenVertexNormalsProcess.h"
+# include "PostProcessing/GenVertexNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
-# include "RemoveVCProcess.h"
+# include "PostProcessing/RemoveVCProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
-# include "SplitLargeMeshes.h"
+# include "PostProcessing/SplitLargeMeshes.h"
#endif
#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
-# include "PretransformVertices.h"
+# include "PostProcessing/PretransformVertices.h"
#endif
#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
-# include "LimitBoneWeightsProcess.h"
+# include "PostProcessing/LimitBoneWeightsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
+# include "PostProcessing/ValidateDataStructure.h"
#endif
#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
-# include "ImproveCacheLocality.h"
+# include "PostProcessing/ImproveCacheLocality.h"
#endif
#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
-# include "FixNormalsStep.h"
+# include "PostProcessing/FixNormalsStep.h"
#endif
#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
-# include "RemoveRedundantMaterials.h"
+# include "PostProcessing/RemoveRedundantMaterials.h"
#endif
#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
-# include "EmbedTexturesProcess.h"
+# include "PostProcessing/EmbedTexturesProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-# include "FindInvalidDataProcess.h"
+# include "PostProcessing/FindInvalidDataProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
-# include "FindDegenerates.h"
+# include "PostProcessing/FindDegenerates.h"
#endif
#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
-# include "SortByPTypeProcess.h"
+# include "PostProcessing/SortByPTypeProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
-# include "ComputeUVMappingProcess.h"
+# include "PostProcessing/ComputeUVMappingProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
-# include "TextureTransform.h"
+# include "PostProcessing/TextureTransform.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
-# include "FindInstancesProcess.h"
+# include "PostProcessing/FindInstancesProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-# include "OptimizeMeshes.h"
+# include "PostProcessing/OptimizeMeshes.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-# include "OptimizeGraph.h"
+# include "PostProcessing/OptimizeGraph.h"
#endif
#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
-# include "SplitByBoneCountProcess.h"
+# include "Common/SplitByBoneCountProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
-# include "DeboneProcess.h"
+# include "PostProcessing/DeboneProcess.h"
#endif
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
-# include "ScaleProcess.h"
+# include "PostProcessing/ScaleProcess.h"
#endif
+#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
+# include "PostProcessing/GenBoundingBoxesProcess.h"
+#endif
+
namespace Assimp {
@@ -246,6 +250,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
out.push_back( new ImproveCacheLocalityProcess());
#endif
+#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
+ out.push_back(new GenBoundingBoxesProcess);
+#endif
}
}
diff --git a/thirdparty/assimp/code/RemoveComments.cpp b/thirdparty/assimp/code/Common/RemoveComments.cpp
index 91700a7699..91700a7699 100644
--- a/thirdparty/assimp/code/RemoveComments.cpp
+++ b/thirdparty/assimp/code/Common/RemoveComments.cpp
diff --git a/thirdparty/assimp/code/SGSpatialSort.cpp b/thirdparty/assimp/code/Common/SGSpatialSort.cpp
index 120070b0aa..120070b0aa 100644
--- a/thirdparty/assimp/code/SGSpatialSort.cpp
+++ b/thirdparty/assimp/code/Common/SGSpatialSort.cpp
diff --git a/thirdparty/assimp/code/SceneCombiner.cpp b/thirdparty/assimp/code/Common/SceneCombiner.cpp
index e445bd7434..e445bd7434 100644
--- a/thirdparty/assimp/code/SceneCombiner.cpp
+++ b/thirdparty/assimp/code/Common/SceneCombiner.cpp
diff --git a/thirdparty/assimp/code/ScenePreprocessor.cpp b/thirdparty/assimp/code/Common/ScenePreprocessor.cpp
index 432a3d7666..432a3d7666 100644
--- a/thirdparty/assimp/code/ScenePreprocessor.cpp
+++ b/thirdparty/assimp/code/Common/ScenePreprocessor.cpp
diff --git a/thirdparty/assimp/code/ScenePreprocessor.h b/thirdparty/assimp/code/Common/ScenePreprocessor.h
index 3f4c8d7c3f..3f4c8d7c3f 100644
--- a/thirdparty/assimp/code/ScenePreprocessor.h
+++ b/thirdparty/assimp/code/Common/ScenePreprocessor.h
diff --git a/thirdparty/assimp/code/ScenePrivate.h b/thirdparty/assimp/code/Common/ScenePrivate.h
index f336aafc9a..f336aafc9a 100644
--- a/thirdparty/assimp/code/ScenePrivate.h
+++ b/thirdparty/assimp/code/Common/ScenePrivate.h
diff --git a/thirdparty/assimp/code/SkeletonMeshBuilder.cpp b/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp
index 06cfe034e9..06cfe034e9 100644
--- a/thirdparty/assimp/code/SkeletonMeshBuilder.cpp
+++ b/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp
diff --git a/thirdparty/assimp/code/SpatialSort.cpp b/thirdparty/assimp/code/Common/SpatialSort.cpp
index a4f3a4e4b8..a4f3a4e4b8 100644
--- a/thirdparty/assimp/code/SpatialSort.cpp
+++ b/thirdparty/assimp/code/Common/SpatialSort.cpp
diff --git a/thirdparty/assimp/code/SplitByBoneCountProcess.cpp b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp
index 2ef66a9afc..2ef66a9afc 100644
--- a/thirdparty/assimp/code/SplitByBoneCountProcess.cpp
+++ b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp
diff --git a/thirdparty/assimp/code/SplitByBoneCountProcess.h b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h
index 6c904a9df4..6c904a9df4 100644
--- a/thirdparty/assimp/code/SplitByBoneCountProcess.h
+++ b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h
diff --git a/thirdparty/assimp/code/StandardShapes.cpp b/thirdparty/assimp/code/Common/StandardShapes.cpp
index 2e5100130f..2e5100130f 100644
--- a/thirdparty/assimp/code/StandardShapes.cpp
+++ b/thirdparty/assimp/code/Common/StandardShapes.cpp
diff --git a/thirdparty/assimp/code/StdOStreamLogStream.h b/thirdparty/assimp/code/Common/StdOStreamLogStream.h
index 893e261a2b..893e261a2b 100644
--- a/thirdparty/assimp/code/StdOStreamLogStream.h
+++ b/thirdparty/assimp/code/Common/StdOStreamLogStream.h
diff --git a/thirdparty/assimp/code/Subdivision.cpp b/thirdparty/assimp/code/Common/Subdivision.cpp
index 19db223a55..60c54939f5 100644
--- a/thirdparty/assimp/code/Subdivision.cpp
+++ b/thirdparty/assimp/code/Common/Subdivision.cpp
@@ -43,9 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Subdivision.h>
#include <assimp/SceneCombiner.h>
#include <assimp/SpatialSort.h>
-#include "ProcessHelper.h"
#include <assimp/Vertex.h>
#include <assimp/ai_assert.h>
+
+#include "PostProcessing/ProcessHelper.h"
+
#include <stdio.h>
using namespace Assimp;
@@ -56,8 +58,7 @@ void mydummy() {}
* implementation is basing on recursive refinement. Directly evaluating the result is also
* possible and much quicker, but it depends on lengthy matrix lookup tables. */
// ------------------------------------------------------------------------------------------------
-class CatmullClarkSubdivider : public Subdivider
-{
+class CatmullClarkSubdivider : public Subdivider {
public:
void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
void Subdivide (aiMesh** smesh, size_t nmesh,
diff --git a/thirdparty/assimp/code/TargetAnimation.cpp b/thirdparty/assimp/code/Common/TargetAnimation.cpp
index b8062499ff..b8062499ff 100644
--- a/thirdparty/assimp/code/TargetAnimation.cpp
+++ b/thirdparty/assimp/code/Common/TargetAnimation.cpp
diff --git a/thirdparty/assimp/code/TargetAnimation.h b/thirdparty/assimp/code/Common/TargetAnimation.h
index 91634ab5aa..91634ab5aa 100644
--- a/thirdparty/assimp/code/TargetAnimation.h
+++ b/thirdparty/assimp/code/Common/TargetAnimation.h
diff --git a/thirdparty/assimp/code/Version.cpp b/thirdparty/assimp/code/Common/Version.cpp
index 0381037ff1..cc94340ac8 100644
--- a/thirdparty/assimp/code/Version.cpp
+++ b/thirdparty/assimp/code/Common/Version.cpp
@@ -134,7 +134,7 @@ ASSIMP_API aiScene::aiScene()
, mCameras(nullptr)
, mMetaData(nullptr)
, mPrivate(new Assimp::ScenePrivateData()) {
- // empty
+ // empty
}
// ------------------------------------------------------------------------------------------------
diff --git a/thirdparty/assimp/code/VertexTriangleAdjacency.cpp b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp
index 7cfd1a3505..7cfd1a3505 100644
--- a/thirdparty/assimp/code/VertexTriangleAdjacency.cpp
+++ b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp
diff --git a/thirdparty/assimp/code/VertexTriangleAdjacency.h b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h
index f3be47612d..f3be47612d 100644
--- a/thirdparty/assimp/code/VertexTriangleAdjacency.h
+++ b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h
diff --git a/thirdparty/assimp/code/Win32DebugLogStream.h b/thirdparty/assimp/code/Common/Win32DebugLogStream.h
index a6063a261e..a6063a261e 100644
--- a/thirdparty/assimp/code/Win32DebugLogStream.h
+++ b/thirdparty/assimp/code/Common/Win32DebugLogStream.h
diff --git a/thirdparty/assimp/code/Common/assbin_chunks.h b/thirdparty/assimp/code/Common/assbin_chunks.h
new file mode 100644
index 0000000000..15e4af5e7d
--- /dev/null
+++ b/thirdparty/assimp/code/Common/assbin_chunks.h
@@ -0,0 +1,196 @@
+#ifndef INCLUDED_ASSBIN_CHUNKS_H
+#define INCLUDED_ASSBIN_CHUNKS_H
+
+#define ASSBIN_VERSION_MAJOR 1
+#define ASSBIN_VERSION_MINOR 0
+
+/**
+@page assfile .ASS File formats
+
+@section over Overview
+Assimp provides its own interchange format, which is intended to applications which need
+to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to
+be read by Assimp itself. They encode additional information needed by Assimp to optimize
+its postprocessing pipeline. If you once apply specific steps to a scene, then save it
+and reread it from an ASS format using the same post processing settings, they won't
+be executed again.
+
+The format comes in two flavours: XML and binary - both of them hold a complete dump of
+the 'aiScene' data structure returned by the APIs. The focus for the binary format
+(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML
+flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene.
+
+ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt>&lt;root&gt;/tools/assimp_cmd</tt>) is able to
+write it and the core library provides a loader for it.
+
+@section assxml XML File format
+
+The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure.
+With few exceptions, C structures are wrapped in XML elements.
+
+The DTD for ASSXML can be found in <tt>&lt;root&gt;/doc/AssXML_Scheme.xml</tt>. Or have look
+at the output files generated by assimp_cmd.
+
+@section assbin Binary file format
+
+The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure.
+This makes the format extensible and allows backward-compatibility with future data structure
+versions. The <tt>&lt;root&gt;/code/assbin_chunks.h</tt> header contains some magic constants
+for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found
+in <tt>&lt;root&gt;/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...).
+
+@verbatim
+
+-------------------------------------------------------------------------------
+1. File structure:
+-------------------------------------------------------------------------------
+
+----------------------
+| Header (512 bytes) |
+----------------------
+| Variable chunks |
+----------------------
+
+-------------------------------------------------------------------------------
+2. Definitions:
+-------------------------------------------------------------------------------
+
+integer is four bytes wide, stored in little-endian byte order.
+short is two bytes wide, stored in little-endian byte order.
+byte is a single byte.
+string is an integer n followed by n UTF-8 characters, not terminated by zero
+float is an IEEE 754 single-precision floating-point value
+double is an IEEE 754 double-precision floating-point value
+t[n] is an array of n elements of type t
+
+-------------------------------------------------------------------------------
+2. Header:
+-------------------------------------------------------------------------------
+
+byte[44] Magic identification string for ASSBIN files.
+ 'ASSIMP.binary'
+
+integer Major version of the Assimp library which wrote the file
+integer Minor version of the Assimp library which wrote the file
+ match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR
+
+integer SVN revision of the Assimp library (intended for our internal
+ debugging - if you write Ass files from your own APPs, set this value to 0.
+integer Assimp compile flags
+
+short 0 for normal files, 1 for shortened dumps for regression tests
+ these should have the file extension assbin.regress
+
+short 1 if the data after the header is compressed with the DEFLATE algorithm,
+ 0 for uncompressed files.
+ For compressed files, the first integer after the header is
+ always the uncompressed data size
+
+byte[256] Zero-terminated source file name, UTF-8
+byte[128] Zero-terminated command line parameters passed to assimp_cmd, UTF-8
+
+byte[64] Reserved for future use
+---> Total length: 512 bytes
+
+-------------------------------------------------------------------------------
+3. Chunks:
+-------------------------------------------------------------------------------
+
+integer Magic chunk ID (ASSBIN_CHUNK_XXX)
+integer Chunk data length, in bytes
+ (unknown chunks are possible, a good reader skips over them)
+ (chunk-data-length does not include the first two integers)
+
+byte[n] chunk-data-length bytes of data, depending on the chunk type
+
+Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk,
+their size is included in chunk-data-length.
+
+The chunk layout for all ASSIMP data structures is derived from their C declarations.
+The general 'rule' to get from Assimp headers to the serialized layout is:
+
+ 1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices),
+ in order of declaration.
+
+ 2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights),
+ in order of declaration.
+
+ 2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in
+ subchunks directly following the data written in 1.) and 2.)
+
+
+ Of course, there are some exceptions to this general order:
+
+[[aiScene]]
+
+ - The root node holding the scene structure is naturally stored in
+ a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is
+ empty for aiScene).
+
+[[aiMesh]]
+
+ - mTextureCoords and mNumUVComponents are serialized as follows:
+
+ [number of used uv channels times]
+ integer mNumUVComponents[n]
+ float mTextureCoords[n][3]
+
+ -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp
+ builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange
+ data.
+ -> the on-disk format always uses 3 floats to write UV coordinates.
+ If mNumUVComponents[0] is 1, the corresponding mTextureCoords array
+ consists of 3 floats.
+
+ - The array member block of aiMesh is prefixed with an integer that specifies
+ the kinds of vertex components actually present in the mesh. This is a
+ bitwise combination of the ASSBIN_MESH_HAS_xxx constants.
+
+[[aiFace]]
+
+ - mNumIndices is stored as short
+ - mIndices are written as short, if aiMesh::mNumVertices<65536
+
+[[aiNode]]
+
+ - mParent is omitted
+
+[[aiLight]]
+
+ - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL
+ - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT
+
+[[aiMaterial]]
+
+ - mNumAllocated is omitted, for obvious reasons :-)
+
+
+ @endverbatim*/
+
+
+#define ASSBIN_HEADER_LENGTH 512
+
+// these are the magic chunk identifiers for the binary ASS file format
+#define ASSBIN_CHUNK_AICAMERA 0x1234
+#define ASSBIN_CHUNK_AILIGHT 0x1235
+#define ASSBIN_CHUNK_AITEXTURE 0x1236
+#define ASSBIN_CHUNK_AIMESH 0x1237
+#define ASSBIN_CHUNK_AINODEANIM 0x1238
+#define ASSBIN_CHUNK_AISCENE 0x1239
+#define ASSBIN_CHUNK_AIBONE 0x123a
+#define ASSBIN_CHUNK_AIANIMATION 0x123b
+#define ASSBIN_CHUNK_AINODE 0x123c
+#define ASSBIN_CHUNK_AIMATERIAL 0x123d
+#define ASSBIN_CHUNK_AIMATERIALPROPERTY 0x123e
+
+#define ASSBIN_MESH_HAS_POSITIONS 0x1
+#define ASSBIN_MESH_HAS_NORMALS 0x2
+#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS 0x4
+#define ASSBIN_MESH_HAS_TEXCOORD_BASE 0x100
+#define ASSBIN_MESH_HAS_COLOR_BASE 0x10000
+
+#define ASSBIN_MESH_HAS_TEXCOORD(n) (ASSBIN_MESH_HAS_TEXCOORD_BASE << n)
+#define ASSBIN_MESH_HAS_COLOR(n) (ASSBIN_MESH_HAS_COLOR_BASE << n)
+
+
+#endif // INCLUDED_ASSBIN_CHUNKS_H
diff --git a/thirdparty/assimp/code/scene.cpp b/thirdparty/assimp/code/Common/scene.cpp
index 2acb348d81..2acb348d81 100644
--- a/thirdparty/assimp/code/scene.cpp
+++ b/thirdparty/assimp/code/Common/scene.cpp
diff --git a/thirdparty/assimp/code/simd.cpp b/thirdparty/assimp/code/Common/simd.cpp
index 04615f408e..04615f408e 100644
--- a/thirdparty/assimp/code/simd.cpp
+++ b/thirdparty/assimp/code/Common/simd.cpp
diff --git a/thirdparty/assimp/code/simd.h b/thirdparty/assimp/code/Common/simd.h
index 3eecdd4581..3eecdd4581 100644
--- a/thirdparty/assimp/code/simd.h
+++ b/thirdparty/assimp/code/Common/simd.h
diff --git a/thirdparty/assimp/code/FBXAnimation.cpp b/thirdparty/assimp/code/FBX/FBXAnimation.cpp
index 874914431b..874914431b 100644
--- a/thirdparty/assimp/code/FBXAnimation.cpp
+++ b/thirdparty/assimp/code/FBX/FBXAnimation.cpp
diff --git a/thirdparty/assimp/code/FBXBinaryTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp
index 7138df4315..a4a2bc8e79 100644
--- a/thirdparty/assimp/code/FBXBinaryTokenizer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp
@@ -98,7 +98,7 @@ namespace FBX {
// return (flags & to_check) != 0;
//}
// ------------------------------------------------------------------------------------------------
-Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
+Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset)
:
#ifdef DEBUG
contents(sbegin, static_cast<size_t>(send-sbegin)),
@@ -122,18 +122,18 @@ namespace {
// ------------------------------------------------------------------------------------------------
// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError.
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset)
+AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) AI_WONT_RETURN_SUFFIX;
+AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
{
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
}
// ------------------------------------------------------------------------------------------------
-uint32_t Offset(const char* begin, const char* cursor) {
+size_t Offset(const char* begin, const char* cursor) {
ai_assert(begin <= cursor);
- return static_cast<unsigned int>(cursor - begin);
+ return cursor - begin;
}
// ------------------------------------------------------------------------------------------------
@@ -424,7 +424,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// ------------------------------------------------------------------------------------------------
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
-void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
+void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
{
ai_assert(input);
diff --git a/thirdparty/assimp/code/FBXCommon.h b/thirdparty/assimp/code/FBX/FBXCommon.h
index fcb20a5cad..e516449130 100644
--- a/thirdparty/assimp/code/FBXCommon.h
+++ b/thirdparty/assimp/code/FBX/FBXCommon.h
@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
-
+namespace Assimp {
namespace FBX
{
const std::string NULL_RECORD = { // 13 null bytes
@@ -80,7 +80,7 @@ namespace FBX
TransformInheritance_MAX // end-of-enum sentinel
};
}
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC
diff --git a/thirdparty/assimp/code/FBXCompileConfig.h b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
index 3a3841fa5b..3a3841fa5b 100644
--- a/thirdparty/assimp/code/FBXCompileConfig.h
+++ b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
diff --git a/thirdparty/assimp/code/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp
index 09ae06a64f..3f64016ea4 100644
--- a/thirdparty/assimp/code/FBXConverter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp
@@ -66,6 +66,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <sstream>
#include <iomanip>
+#include <cstdint>
+
namespace Assimp {
namespace FBX {
@@ -76,20 +78,19 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
- FBXConverter::FBXConverter(aiScene* out, const Document& doc)
- : defaultMaterialIndex()
- , lights()
- , cameras()
- , textures()
- , materials_converted()
- , textures_converted()
- , meshes_converted()
- , node_anim_chain_bits()
- , mNodeNameInstances()
- , mNodeNames()
- , anim_fps()
- , out(out)
- , doc(doc) {
+ FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
+ : defaultMaterialIndex()
+ , lights()
+ , cameras()
+ , textures()
+ , materials_converted()
+ , textures_converted()
+ , meshes_converted()
+ , node_anim_chain_bits()
+ , mNodeNames()
+ , anim_fps()
+ , out(out)
+ , doc(doc) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@@ -138,12 +139,46 @@ namespace Assimp {
void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode();
- out->mRootNode->mName.Set("RootNode");
+ std::string unique_name;
+ GetUniqueName("RootNode", unique_name);
+ out->mRootNode->mName.Set(unique_name);
// root has ID 0
ConvertNodes(0L, *out->mRootNode);
}
+ static std::string getAncestorBaseName(const aiNode* node)
+ {
+ const char* nodeName = nullptr;
+ size_t length = 0;
+ while (node && (!nodeName || length == 0))
+ {
+ nodeName = node->mName.C_Str();
+ length = node->mName.length;
+ node = node->mParent;
+ }
+
+ if (!nodeName || length == 0)
+ {
+ return {};
+ }
+ // could be std::string_view if c++17 available
+ return std::string(nodeName, length);
+ }
+
+ // Make unique name
+ std::string FBXConverter::MakeUniqueNodeName(const Model* const model, const aiNode& parent)
+ {
+ std::string original_name = FixNodeName(model->Name());
+ if (original_name.empty())
+ {
+ original_name = getAncestorBaseName(&parent);
+ }
+ std::string unique_name;
+ GetUniqueName(original_name, unique_name);
+ return unique_name;
+ }
+
void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
@@ -175,35 +210,18 @@ namespace Assimp {
aiMatrix4x4 new_abs_transform = parent_transform;
+ std::string unique_name = MakeUniqueNodeName(model, parent);
+
// even though there is only a single input node, the design of
// assimp (or rather: the complicated transformation chain that
// is employed by fbx) means that we may need multiple aiNode's
// to represent a fbx node's transformation.
- GenerateTransformationNodeChain(*model, nodes_chain, post_nodes_chain);
+ const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
ai_assert(nodes_chain.size());
- std::string original_name = FixNodeName(model->Name());
-
- // check if any of the nodes in the chain has the name the fbx node
- // is supposed to have. If there is none, add another node to
- // preserve the name - people might have scripts etc. that rely
- // on specific node names.
- aiNode* name_carrier = NULL;
- for (aiNode* prenode : nodes_chain) {
- if (!strcmp(prenode->mName.C_Str(), original_name.c_str())) {
- name_carrier = prenode;
- break;
- }
- }
-
- if (!name_carrier) {
- std::string old_original_name = original_name;
- GetUniqueName(old_original_name, original_name);
- nodes_chain.push_back(new aiNode(original_name));
- }
- else {
- original_name = nodes_chain.back()->mName.C_Str();
+ if (need_additional_node) {
+ nodes_chain.push_back(new aiNode(unique_name));
}
//setup metadata on newest node
@@ -265,11 +283,11 @@ namespace Assimp {
ConvertNodes(model->ID(), *last_parent, new_abs_transform);
if (doc.Settings().readLights) {
- ConvertLights(*model, original_name);
+ ConvertLights(*model, unique_name);
}
if (doc.Settings().readCameras) {
- ConvertCameras(*model, original_name);
+ ConvertCameras(*model, unique_name);
}
nodes.push_back(nodes_chain.front());
@@ -387,6 +405,7 @@ namespace Assimp {
break;
default:
ai_assert(false);
+ break;
}
}
@@ -399,11 +418,6 @@ namespace Assimp {
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
- //cameras are defined along positive x direction
- /*out_camera->mPosition = cam.Position();
- out_camera->mLookAt = (cam.InterestPosition() - out_camera->mPosition).Normalize();
- out_camera->mUp = cam.UpVector();*/
-
out_camera->mPosition = aiVector3D(0.0f);
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
@@ -421,21 +435,16 @@ namespace Assimp {
void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueName)
{
uniqueName = name;
- int i = 0;
- auto it = mNodeNameInstances.find(name); // duplicate node name instance count
- if (it != mNodeNameInstances.end())
+ auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
+ unsigned int& i = it_pair.first->second;
+ while (!it_pair.second)
{
- i = it->second;
- while (mNodeNames.find(uniqueName) != mNodeNames.end())
- {
- i++;
- std::stringstream ext;
- ext << name << std::setfill('0') << std::setw(3) << i;
- uniqueName = ext.str();
- }
+ i++;
+ std::ostringstream ext;
+ ext << name << std::setfill('0') << std::setw(3) << i;
+ uniqueName = ext.str();
+ it_pair = mNodeNames.insert({ uniqueName, 0 });
}
- mNodeNameInstances[name] = i;
- mNodeNames.insert(uniqueName);
}
const char* FBXConverter::NameTransformationComp(TransformationComp comp) {
@@ -651,8 +660,7 @@ namespace Assimp {
if ((v - all_ones).SquareLength() > zero_epsilon) {
return true;
}
- }
- else if (ok) {
+ } else if (ok) {
if (v.SquareLength() > zero_epsilon) {
return true;
}
@@ -667,7 +675,7 @@ namespace Assimp {
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
}
- void FBXConverter::GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes,
+ bool FBXConverter::GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes,
std::vector<aiNode*>& post_output_nodes) {
const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder();
@@ -675,30 +683,37 @@ namespace Assimp {
bool ok;
aiMatrix4x4 chain[TransformationComp_MAXIMUM];
+
+ ai_assert(TransformationComp_MAXIMUM < 32);
+ std::uint32_t chainBits = 0;
+ // A node won't need a node chain if it only has these.
+ const std::uint32_t chainMaskSimple = (1 << TransformationComp_Translation) + (1 << TransformationComp_Scaling) + (1 << TransformationComp_Rotation);
+ // A node will need a node chain if it has any of these.
+ const std::uint32_t chainMaskComplex = ((1 << (TransformationComp_MAXIMUM)) - 1) - chainMaskSimple;
+
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
// generate transformation matrices for all the different transformation components
const float zero_epsilon = 1e-6f;
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
- bool is_complex = false;
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
if (ok && PreRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_PreRotation);
GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PreRotation, chain[TransformationComp_PreRotation]);
}
const aiVector3D& PostRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
if (ok && PostRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_PostRotation);
GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PostRotation, chain[TransformationComp_PostRotation]);
}
const aiVector3D& RotationPivot = PropertyGet<aiVector3D>(props, "RotationPivot", ok);
if (ok && RotationPivot.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_RotationPivot) | (1 << TransformationComp_RotationPivotInverse);
aiMatrix4x4::Translation(RotationPivot, chain[TransformationComp_RotationPivot]);
aiMatrix4x4::Translation(-RotationPivot, chain[TransformationComp_RotationPivotInverse]);
@@ -706,21 +721,21 @@ namespace Assimp {
const aiVector3D& RotationOffset = PropertyGet<aiVector3D>(props, "RotationOffset", ok);
if (ok && RotationOffset.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_RotationOffset);
aiMatrix4x4::Translation(RotationOffset, chain[TransformationComp_RotationOffset]);
}
const aiVector3D& ScalingOffset = PropertyGet<aiVector3D>(props, "ScalingOffset", ok);
if (ok && ScalingOffset.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_ScalingOffset);
aiMatrix4x4::Translation(ScalingOffset, chain[TransformationComp_ScalingOffset]);
}
const aiVector3D& ScalingPivot = PropertyGet<aiVector3D>(props, "ScalingPivot", ok);
if (ok && ScalingPivot.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_ScalingPivot) | (1 << TransformationComp_ScalingPivotInverse);
aiMatrix4x4::Translation(ScalingPivot, chain[TransformationComp_ScalingPivot]);
aiMatrix4x4::Translation(-ScalingPivot, chain[TransformationComp_ScalingPivotInverse]);
@@ -728,22 +743,28 @@ namespace Assimp {
const aiVector3D& Translation = PropertyGet<aiVector3D>(props, "Lcl Translation", ok);
if (ok && Translation.SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Translation);
+
aiMatrix4x4::Translation(Translation, chain[TransformationComp_Translation]);
}
const aiVector3D& Scaling = PropertyGet<aiVector3D>(props, "Lcl Scaling", ok);
if (ok && (Scaling - all_ones).SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Scaling);
+
aiMatrix4x4::Scaling(Scaling, chain[TransformationComp_Scaling]);
}
const aiVector3D& Rotation = PropertyGet<aiVector3D>(props, "Lcl Rotation", ok);
if (ok && Rotation.SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Rotation);
+
GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]);
}
const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>(props, "GeometricScaling", ok);
if (ok && (GeometricScaling - all_ones).SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricScaling);
aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]);
aiVector3D GeometricScalingInverse = GeometricScaling;
bool canscale = true;
@@ -758,13 +779,14 @@ namespace Assimp {
}
}
if (canscale) {
+ chainBits = chainBits | (1 << TransformationComp_GeometricScalingInverse);
aiMatrix4x4::Scaling(GeometricScalingInverse, chain[TransformationComp_GeometricScalingInverse]);
}
}
const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>(props, "GeometricRotation", ok);
if (ok && GeometricRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricRotation) | (1 << TransformationComp_GeometricRotationInverse);
GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotation]);
GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotationInverse]);
chain[TransformationComp_GeometricRotationInverse].Inverse();
@@ -772,7 +794,7 @@ namespace Assimp {
const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>(props, "GeometricTranslation", ok);
if (ok && GeometricTranslation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricTranslation) | (1 << TransformationComp_GeometricTranslationInverse);
aiMatrix4x4::Translation(GeometricTranslation, chain[TransformationComp_GeometricTranslation]);
aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]);
}
@@ -780,14 +802,12 @@ namespace Assimp {
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
- ai_assert(NeedsComplexTransformationChain(model) == is_complex);
-
- std::string name = FixNodeName(model.Name());
+ ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets.
- if (is_complex && doc.Settings().preservePivots) {
+ if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) {
FBXImporter::LogInfo("generating full transformation chain for node: " + name);
// query the anim_chain_bits dictionary to find out which chain elements
@@ -800,7 +820,7 @@ namespace Assimp {
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
const TransformationComp comp = static_cast<TransformationComp>(i);
- if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) {
+ if ((chainBits & bit) == 0 && (anim_chain_bitmask & bit) == 0) {
continue;
}
@@ -825,20 +845,20 @@ namespace Assimp {
}
ai_assert(output_nodes.size());
- return;
+ return true;
}
// else, we can just multiply the matrices together
aiNode* nd = new aiNode();
output_nodes.push_back(nd);
- std::string uniqueName;
- GetUniqueName(name, uniqueName);
- nd->mName.Set(uniqueName);
+ // name passed to the method is already unique
+ nd->mName.Set(name);
for (const auto &transform : chain) {
nd->mTransformation = nd->mTransformation * transform;
}
+ return false;
}
void FBXConverter::SetupNodeMetadata(const Model& model, aiNode& nd)
@@ -977,7 +997,9 @@ namespace Assimp {
unsigned int epcount = 0;
for (unsigned i = 0; i < indices.size(); i++)
{
- if (indices[i] < 0) epcount++;
+ if (indices[i] < 0) {
+ epcount++;
+ }
}
unsigned int pcount = static_cast<unsigned int>( indices.size() );
unsigned int scount = out_mesh->mNumFaces = pcount - epcount;
@@ -1237,10 +1259,10 @@ namespace Assimp {
ai_assert(count_faces);
ai_assert(count_vertices);
- // mapping from output indices to DOM indexing, needed to resolve weights
+ // mapping from output indices to DOM indexing, needed to resolve weights or blendshapes
std::vector<unsigned int> reverseMapping;
-
- if (process_weights) {
+ std::map<unsigned int, unsigned int> translateIndexMap;
+ if (process_weights || mesh.GetBlendShapes().size() > 0) {
reverseMapping.resize(count_vertices);
}
@@ -1347,6 +1369,7 @@ namespace Assimp {
if (reverseMapping.size()) {
reverseMapping[cursor] = in_cursor;
+ translateIndexMap[in_cursor] = cursor;
}
out_mesh->mVertices[cursor] = vertices[in_cursor];
@@ -1378,6 +1401,50 @@ namespace Assimp {
ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
}
+ std::vector<aiAnimMesh*> animMeshes;
+ for (const BlendShape* blendShape : mesh.GetBlendShapes()) {
+ for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) {
+ const std::vector<const ShapeGeometry*>& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+ for (size_t i = 0; i < shapeGeometries.size(); i++) {
+ aiAnimMesh* animMesh = aiCreateAnimMesh(out_mesh);
+ const ShapeGeometry* shapeGeometry = shapeGeometries.at(i);
+ const std::vector<aiVector3D>& vertices = shapeGeometry->GetVertices();
+ const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals();
+ const std::vector<unsigned int>& indices = shapeGeometry->GetIndices();
+ animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
+ for (size_t j = 0; j < indices.size(); j++) {
+ unsigned int index = indices.at(j);
+ aiVector3D vertex = vertices.at(j);
+ aiVector3D normal = normals.at(j);
+ unsigned int count = 0;
+ const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count);
+ for (unsigned int k = 0; k < count; k++) {
+ unsigned int outIndex = outIndices[k];
+ if (translateIndexMap.find(outIndex) == translateIndexMap.end())
+ continue;
+ unsigned int index = translateIndexMap[outIndex];
+ animMesh->mVertices[index] += vertex;
+ if (animMesh->mNormals != nullptr) {
+ animMesh->mNormals[index] += normal;
+ animMesh->mNormals[index].NormalizeSafe();
+ }
+ }
+ }
+ animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f;
+ animMeshes.push_back(animMesh);
+ }
+ }
+ }
+
+ const size_t numAnimMeshes = animMeshes.size();
+ if (numAnimMeshes > 0) {
+ out_mesh->mNumAnimMeshes = static_cast<unsigned int>(numAnimMeshes);
+ out_mesh->mAnimMeshes = new aiAnimMesh*[numAnimMeshes];
+ for (size_t i = 0; i < numAnimMeshes; i++) {
+ out_mesh->mAnimMeshes[i] = animMeshes.at(i);
+ }
+ }
+
return static_cast<unsigned int>(meshes.size() - 1);
}
@@ -1407,14 +1474,8 @@ namespace Assimp {
const WeightIndexArray& indices = cluster->GetIndices();
- if (indices.empty()) {
- continue;
- }
-
const MatIndexArray& mats = geo.GetMaterialIndices();
- bool ok = false;
-
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
count_out_indices.clear();
@@ -1439,13 +1500,11 @@ namespace Assimp {
if (index_out_indices.back() == no_index_sentinel) {
index_out_indices.back() = out_indices.size();
-
}
if (no_mat_check) {
out_indices.push_back(out_idx[i]);
- }
- else {
+ } else {
// this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn)
const std::vector<unsigned int>::iterator it = std::lower_bound(
outputVertStartIndices->begin(),
@@ -1456,19 +1515,16 @@ namespace Assimp {
out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
}
- ++count_out_indices.back();
- ok = true;
+ ++count_out_indices.back();
}
}
}
-
+
// if we found at least one, generate the output bones
// XXX this could be heavily simplified by collecting the bone
// data in a single step.
- if (ok) {
- ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
+ ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
count_out_indices, node_global_transform);
- }
}
}
catch (std::exception&) {
@@ -1596,6 +1652,13 @@ namespace Assimp {
out_mat->AddProperty(&str, AI_MATKEY_NAME);
}
+ // Set the shading mode as best we can: The FBX specification only mentions Lambert and Phong, and only Phong is mentioned in Assimp's aiShadingMode enum.
+ if (material.GetShadingModel() == "phong")
+ {
+ aiShadingMode shadingMode = aiShadingMode_Phong;
+ out_mat->AddProperty<aiShadingMode>(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
+ }
+
// shading stuff and colors
SetShadingPropertiesCommon(out_mat, props);
SetShadingPropertiesRaw( out_mat, props, material.Textures(), mesh );
@@ -1621,7 +1684,7 @@ namespace Assimp {
out_tex->pcData = reinterpret_cast<aiTexel*>(const_cast<Video&>(video).RelinquishContent());
// try to extract a hint from the file extension
- const std::string& filename = video.FileName().empty() ? video.RelativeFilename() : video.FileName();
+ const std::string& filename = video.RelativeFilename().empty() ? video.FileName() : video.RelativeFilename();
std::string ext = BaseImporter::GetExtension(filename);
if (ext == "jpeg") {
@@ -1632,7 +1695,7 @@ namespace Assimp {
memcpy(out_tex->achFormatHint, ext.c_str(), ext.size());
}
- out_tex->mFilename.Set(video.FileName().c_str());
+ out_tex->mFilename.Set(filename.c_str());
return static_cast<unsigned int>(textures.size() - 1);
}
@@ -1678,9 +1741,8 @@ namespace Assimp {
}
void FBXConverter::TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh)
- {
+ const std::string& propName,
+ aiTextureType target, const MeshGeometry* const mesh) {
TextureMap::const_iterator it = textures.find(propName);
if (it == textures.end()) {
return;
@@ -1939,6 +2001,21 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
+
+ // Maya PBR
+ TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+
+ // Maya stingray
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
}
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@@ -3407,8 +3484,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
na->mScalingKeys = new aiVectorKey[keys.size()];
- if (keys.size() > 0)
+ if (keys.size() > 0) {
InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
+ }
}
void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
@@ -3525,9 +3603,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
// ------------------------------------------------------------------------------------------------
- void ConvertToAssimpScene(aiScene* out, const Document& doc)
+ void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{
- FBXConverter converter(out, doc);
+ FBXConverter converter(out, doc, removeEmptyBones);
}
} // !FBX
diff --git a/thirdparty/assimp/code/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h
index 50637468b9..ab610058a4 100644
--- a/thirdparty/assimp/code/FBXConverter.h
+++ b/thirdparty/assimp/code/FBX/FBXConverter.h
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXUtil.h"
#include "FBXProperties.h"
#include "FBXImporter.h"
+
#include <assimp/anim.h>
#include <assimp/material.h>
#include <assimp/light.h>
@@ -76,12 +77,22 @@ namespace FBX {
class Document;
+enum class FbxUnit {
+ cm = 0,
+ m,
+ km,
+ NumUnits,
+
+ Undefined
+};
+
/**
* Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated
- * @param doc Parsed FBX document
+ * @param doc Parsed FBX document
+ * @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/
-void ConvertToAssimpScene(aiScene* out, const Document& doc);
+void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
/** Dummy class to encapsulate the conversion process */
class FBXConverter {
@@ -112,7 +123,7 @@ public:
};
public:
- FBXConverter(aiScene* out, const Document& doc);
+ FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter();
private:
@@ -145,6 +156,11 @@ private:
const char* NameTransformationComp(TransformationComp comp);
// ------------------------------------------------------------------------------------------------
+ // Returns an unique name for a node or traverses up a hierarchy until a non-empty name is found and
+ // then makes this name unique
+ std::string MakeUniqueNodeName(const Model* const model, const aiNode& parent);
+
+ // ------------------------------------------------------------------------------------------------
// note: this returns the REAL fbx property names
const char* NameTransformationCompProperty(TransformationComp comp);
@@ -167,7 +183,7 @@ private:
/**
* note: memory for output_nodes will be managed by the caller
*/
- void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
+ bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
// ------------------------------------------------------------------------------------------------
void SetupNodeMetadata(const Model& model, aiNode& nd);
@@ -443,16 +459,14 @@ private:
NodeAnimBitMap node_anim_chain_bits;
// number of nodes with the same name
- using NodeAnimNameMap = std::unordered_map<std::string, unsigned int>;
- NodeAnimNameMap mNodeNameInstances;
-
- using NodeNameCache = std::unordered_set<std::string>;
+ using NodeNameCache = std::unordered_map<std::string, unsigned int>;
NodeNameCache mNodeNames;
double anim_fps;
aiScene* const out;
const FBX::Document& doc;
+ FbxUnit mCurrentUnit;
};
}
diff --git a/thirdparty/assimp/code/FBXDeformer.cpp b/thirdparty/assimp/code/FBX/FBXDeformer.cpp
index 6927553450..6927553450 100644
--- a/thirdparty/assimp/code/FBXDeformer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDeformer.cpp
diff --git a/thirdparty/assimp/code/FBXDocument.cpp b/thirdparty/assimp/code/FBX/FBXDocument.cpp
index 1af08fe6d8..506fd978dd 100644
--- a/thirdparty/assimp/code/FBXDocument.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDocument.cpp
@@ -90,14 +90,6 @@ const Object* LazyObject::Get(bool dieOnError)
return object.get();
}
- // if this is the root object, we return a dummy since there
- // is no root object int he fbx file - it is just referenced
- // with id 0.
- if(id == 0L) {
- object.reset(new Object(id, element, "Model::RootNode"));
- return object.get();
- }
-
const Token& key = element.KeyToken();
const TokenList& tokens = element.Tokens();
diff --git a/thirdparty/assimp/code/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h
index c849defdcd..18e5c38f13 100644
--- a/thirdparty/assimp/code/FBXDocument.h
+++ b/thirdparty/assimp/code/FBX/FBXDocument.h
@@ -627,7 +627,7 @@ public:
return content;
}
- uint32_t ContentLength() const {
+ uint64_t ContentLength() const {
return contentLength;
}
@@ -643,7 +643,7 @@ private:
std::string fileName;
std::shared_ptr<const PropertyTable> props;
- uint32_t contentLength;
+ uint64_t contentLength;
uint8_t* content;
};
diff --git a/thirdparty/assimp/code/FBXDocumentUtil.cpp b/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp
index f84691479a..f84691479a 100644
--- a/thirdparty/assimp/code/FBXDocumentUtil.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp
diff --git a/thirdparty/assimp/code/FBXDocumentUtil.h b/thirdparty/assimp/code/FBX/FBXDocumentUtil.h
index 2450109e59..2450109e59 100644
--- a/thirdparty/assimp/code/FBXDocumentUtil.h
+++ b/thirdparty/assimp/code/FBX/FBXDocumentUtil.h
diff --git a/thirdparty/assimp/code/FBXExportNode.cpp b/thirdparty/assimp/code/FBX/FBXExportNode.cpp
index e5215466a1..06c89cee46 100644
--- a/thirdparty/assimp/code/FBXExportNode.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportNode.cpp
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream> // ostringstream
#include <memory> // shared_ptr
+namespace Assimp {
// AddP70<type> helpers... there's no usable pattern here,
// so all are defined as separate functions.
// Even "animatable" properties are often completely different
@@ -252,7 +253,8 @@ void FBX::Node::DumpChildren(
} else {
std::ostringstream ss;
DumpChildrenAscii(ss, indent);
- s.PutString(ss.str());
+ if (ss.tellp() > 0)
+ s.PutString(ss.str());
}
}
@@ -266,7 +268,8 @@ void FBX::Node::End(
} else {
std::ostringstream ss;
EndAscii(ss, indent, has_children);
- s.PutString(ss.str());
+ if (ss.tellp() > 0)
+ s.PutString(ss.str());
}
}
@@ -367,7 +370,7 @@ void FBX::Node::EndBinary(
bool has_children
) {
// if there were children, add a null record
- if (has_children) { s.PutString(FBX::NULL_RECORD); }
+ if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD); }
// now go back and write initial pos
this->end_pos = s.Tell();
@@ -563,6 +566,6 @@ void FBX::Node::WritePropertyNode(
FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
}
}
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/FBXExportNode.h b/thirdparty/assimp/code/FBX/FBXExportNode.h
index e1ebc36969..ef3bc781a4 100644
--- a/thirdparty/assimp/code/FBXExportNode.h
+++ b/thirdparty/assimp/code/FBX/FBXExportNode.h
@@ -54,16 +54,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
+namespace Assimp {
namespace FBX {
class Node;
}
-class FBX::Node
-{
-public: // public data members
+class FBX::Node {
+public:
// TODO: accessors
std::string name; // node name
- std::vector<FBX::Property> properties; // node properties
+ std::vector<FBX::FBXExportProperty> properties; // node properties
std::vector<FBX::Node> children; // child nodes
// some nodes always pretend they have children...
@@ -214,7 +214,7 @@ public: // static member functions
Assimp::StreamWriterLE& s,
bool binary, int indent
) {
- FBX::Property p(value);
+ FBX::FBXExportProperty p(value);
FBX::Node node(name, p);
node.Dump(s, binary, indent);
}
@@ -264,7 +264,7 @@ private: // static helper functions
);
};
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
diff --git a/thirdparty/assimp/code/FBXExportProperty.cpp b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
index 9981d6b1c6..f8593e6295 100644
--- a/thirdparty/assimp/code/FBXExportProperty.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
@@ -52,187 +52,210 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <locale>
#include <sstream> // ostringstream
+namespace Assimp {
+namespace FBX {
// constructors for single element properties
-FBX::Property::Property(bool v)
- : type('C'), data(1)
-{
- data = {uint8_t(v)};
+FBXExportProperty::FBXExportProperty(bool v)
+: type('C')
+, data(1) {
+ data = {
+ uint8_t(v)
+ };
}
-FBX::Property::Property(int16_t v) : type('Y'), data(2)
-{
+FBXExportProperty::FBXExportProperty(int16_t v)
+: type('Y')
+, data(2) {
uint8_t* d = data.data();
(reinterpret_cast<int16_t*>(d))[0] = v;
}
-FBX::Property::Property(int32_t v) : type('I'), data(4)
-{
+FBXExportProperty::FBXExportProperty(int32_t v)
+: type('I')
+, data(4) {
uint8_t* d = data.data();
(reinterpret_cast<int32_t*>(d))[0] = v;
}
-FBX::Property::Property(float v) : type('F'), data(4)
-{
+FBXExportProperty::FBXExportProperty(float v)
+: type('F')
+, data(4) {
uint8_t* d = data.data();
(reinterpret_cast<float*>(d))[0] = v;
}
-FBX::Property::Property(double v) : type('D'), data(8)
-{
+FBXExportProperty::FBXExportProperty(double v)
+: type('D')
+, data(8) {
uint8_t* d = data.data();
(reinterpret_cast<double*>(d))[0] = v;
}
-FBX::Property::Property(int64_t v) : type('L'), data(8)
-{
+FBXExportProperty::FBXExportProperty(int64_t v)
+: type('L')
+, data(8) {
uint8_t* d = data.data();
(reinterpret_cast<int64_t*>(d))[0] = v;
}
-
// constructors for array-type properties
-FBX::Property::Property(const char* c, bool raw)
- : Property(std::string(c), raw)
-{}
+FBXExportProperty::FBXExportProperty(const char* c, bool raw)
+: FBXExportProperty(std::string(c), raw) {
+ // empty
+}
// strings can either be saved as "raw" (R) data, or "string" (S) data
-FBX::Property::Property(const std::string& s, bool raw)
- : type(raw ? 'R' : 'S'), data(s.size())
-{
+FBXExportProperty::FBXExportProperty(const std::string& s, bool raw)
+: type(raw ? 'R' : 'S')
+, data(s.size()) {
for (size_t i = 0; i < s.size(); ++i) {
data[i] = uint8_t(s[i]);
}
}
-FBX::Property::Property(const std::vector<uint8_t>& r)
- : type('R'), data(r)
-{}
+FBXExportProperty::FBXExportProperty(const std::vector<uint8_t>& r)
+: type('R')
+, data(r) {
+ // empty
+}
-FBX::Property::Property(const std::vector<int32_t>& va)
- : type('i'), data(4*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<int32_t>& va)
+: type('i')
+, data(4 * va.size() ) {
int32_t* d = reinterpret_cast<int32_t*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<int64_t>& va)
- : type('l'), data(8*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<int64_t>& va)
+: type('l')
+, data(8 * va.size()) {
int64_t* d = reinterpret_cast<int64_t*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<float>& va)
- : type('f'), data(4*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<float>& va)
+: type('f')
+, data(4 * va.size()) {
float* d = reinterpret_cast<float*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<double>& va)
- : type('d'), data(8*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<double>& va)
+: type('d')
+, data(8 * va.size()) {
double* d = reinterpret_cast<double*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const aiMatrix4x4& vm)
- : type('d'), data(8*16)
-{
+FBXExportProperty::FBXExportProperty(const aiMatrix4x4& vm)
+: type('d')
+, data(8 * 16) {
double* d = reinterpret_cast<double*>(data.data());
for (unsigned int c = 0; c < 4; ++c) {
for (unsigned int r = 0; r < 4; ++r) {
- d[4*c+r] = vm[r][c];
+ d[4 * c + r] = vm[r][c];
}
}
}
// public member functions
-size_t FBX::Property::size()
-{
+size_t FBXExportProperty::size() {
switch (type) {
- case 'C': case 'Y': case 'I': case 'F': case 'D': case 'L':
- return data.size() + 1;
- case 'S': case 'R':
- return data.size() + 5;
- case 'i': case 'd':
- return data.size() + 13;
- default:
- throw DeadlyExportError("Requested size on property of unknown type");
+ case 'C':
+ case 'Y':
+ case 'I':
+ case 'F':
+ case 'D':
+ case 'L':
+ return data.size() + 1;
+ case 'S':
+ case 'R':
+ return data.size() + 5;
+ case 'i':
+ case 'd':
+ return data.size() + 13;
+ default:
+ throw DeadlyExportError("Requested size on property of unknown type");
}
}
-void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s)
-{
+void FBXExportProperty::DumpBinary(Assimp::StreamWriterLE& s) {
s.PutU1(type);
uint8_t* d = data.data();
size_t N;
switch (type) {
- case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
- case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
- case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
- case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
- case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
- case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
- case 'S':
- case 'R':
- s.PutU4(uint32_t(data.size()));
- for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
- return;
- case 'i':
- N = data.size() / 4;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
- }
- return;
- case 'l':
- N = data.size() / 8;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
- }
- return;
- case 'f':
- N = data.size() / 4;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutF4((reinterpret_cast<float*>(d))[i]);
- }
- return;
- case 'd':
- N = data.size() / 8;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutF8((reinterpret_cast<double*>(d))[i]);
- }
- return;
- default:
- std::ostringstream err;
- err << "Tried to dump property with invalid type '";
- err << type << "'!";
- throw DeadlyExportError(err.str());
+ case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
+ case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
+ case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
+ case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
+ case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
+ case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
+ case 'S':
+ case 'R':
+ s.PutU4(uint32_t(data.size()));
+ for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
+ return;
+ case 'i':
+ N = data.size() / 4;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
+ }
+ return;
+ case 'l':
+ N = data.size() / 8;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
+ }
+ return;
+ case 'f':
+ N = data.size() / 4;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutF4((reinterpret_cast<float*>(d))[i]);
+ }
+ return;
+ case 'd':
+ N = data.size() / 8;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutF8((reinterpret_cast<double*>(d))[i]);
+ }
+ return;
+ default:
+ std::ostringstream err;
+ err << "Tried to dump property with invalid type '";
+ err << type << "'!";
+ throw DeadlyExportError(err.str());
}
}
-void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
-{
+void FBXExportProperty::DumpAscii(Assimp::StreamWriterLE& outstream, int indent) {
std::ostringstream ss;
ss.imbue(std::locale::classic());
ss.precision(15); // this seems to match official FBX SDK exports
@@ -240,8 +263,7 @@ void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
outstream.PutString(ss.str());
}
-void FBX::Property::DumpAscii(std::ostream& s, int indent)
-{
+void FBXExportProperty::DumpAscii(std::ostream& s, int indent) {
// no writing type... or anything. just shove it into the stream.
uint8_t* d = data.data();
size_t N;
@@ -360,5 +382,8 @@ void FBX::Property::DumpAscii(std::ostream& s, int indent)
}
}
+} // Namespace FBX
+} // Namespace Assimp
+
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/FBXExportProperty.h b/thirdparty/assimp/code/FBX/FBXExportProperty.h
index 9c9d37c362..d692fe6ee3 100644
--- a/thirdparty/assimp/code/FBXExportProperty.h
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.h
@@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
-
#include <assimp/types.h> // aiMatrix4x4
#include <assimp/StreamWriter.h> // StreamWriterLE
@@ -56,11 +55,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ostream>
#include <type_traits> // is_void
+namespace Assimp {
namespace FBX {
- class Property;
-}
-/** FBX::Property
+/** @brief FBX::Property
*
* Holds a value of any of FBX's recognized types,
* each represented by a particular one-character code.
@@ -78,35 +76,34 @@ namespace FBX {
* S : string (array of 1-byte char)
* R : raw data (array of bytes)
*/
-class FBX::Property
-{
+class FBXExportProperty {
public:
// constructors for basic types.
// all explicit to avoid accidental typecasting
- explicit Property(bool v);
+ explicit FBXExportProperty(bool v);
// TODO: determine if there is actually a byte type,
// or if this always means <bool>. 'C' seems to imply <char>,
// so possibly the above was intended to represent both.
- explicit Property(int16_t v);
- explicit Property(int32_t v);
- explicit Property(float v);
- explicit Property(double v);
- explicit Property(int64_t v);
+ explicit FBXExportProperty(int16_t v);
+ explicit FBXExportProperty(int32_t v);
+ explicit FBXExportProperty(float v);
+ explicit FBXExportProperty(double v);
+ explicit FBXExportProperty(int64_t v);
// strings can either be stored as 'R' (raw) or 'S' (string) type
- explicit Property(const char* c, bool raw=false);
- explicit Property(const std::string& s, bool raw=false);
- explicit Property(const std::vector<uint8_t>& r);
- explicit Property(const std::vector<int32_t>& va);
- explicit Property(const std::vector<int64_t>& va);
- explicit Property(const std::vector<double>& va);
- explicit Property(const std::vector<float>& va);
- explicit Property(const aiMatrix4x4& vm);
+ explicit FBXExportProperty(const char* c, bool raw = false);
+ explicit FBXExportProperty(const std::string& s, bool raw = false);
+ explicit FBXExportProperty(const std::vector<uint8_t>& r);
+ explicit FBXExportProperty(const std::vector<int32_t>& va);
+ explicit FBXExportProperty(const std::vector<int64_t>& va);
+ explicit FBXExportProperty(const std::vector<double>& va);
+ explicit FBXExportProperty(const std::vector<float>& va);
+ explicit FBXExportProperty(const aiMatrix4x4& vm);
// this will catch any type not defined above,
// so that we don't accidentally convert something we don't want.
// for example (const char*) --> (bool)... seriously wtf C++
template <class T>
- explicit Property(T v) : type('X') {
+ explicit FBXExportProperty(T v) : type('X') {
static_assert(std::is_void<T>::value, "TRIED TO CREATE FBX PROPERTY WITH UNSUPPORTED TYPE, CHECK YOUR PROPERTY INSTANTIATION");
} // note: no line wrap so it appears verbatim on the compiler error
@@ -114,9 +111,9 @@ public:
size_t size();
// write this property node as binary data to the given stream
- void DumpBinary(Assimp::StreamWriterLE &s);
- void DumpAscii(Assimp::StreamWriterLE &s, int indent=0);
- void DumpAscii(std::ostream &s, int indent=0);
+ void DumpBinary(Assimp::StreamWriterLE& s);
+ void DumpAscii(Assimp::StreamWriterLE& s, int indent = 0);
+ void DumpAscii(std::ostream& s, int indent = 0);
// note: make sure the ostream is in classic "C" locale
private:
@@ -124,6 +121,9 @@ private:
std::vector<uint8_t> data;
};
+} // Namespace FBX
+} // Namespace Assimp
+
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXEXPORTPROPERTY_H_INC
diff --git a/thirdparty/assimp/code/FBXExporter.cpp b/thirdparty/assimp/code/FBX/FBXExporter.cpp
index acb1227144..8ebc8555a2 100644
--- a/thirdparty/assimp/code/FBXExporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExporter.cpp
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXExportNode.h"
#include "FBXExportProperty.h"
#include "FBXCommon.h"
+#include "FBXUtil.h"
#include <assimp/version.h> // aiGetVersion
#include <assimp/IOSystem.hpp>
@@ -73,7 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian
+using namespace Assimp;
+using namespace Assimp::FBX;
+
// some constants that we'll use for writing metadata
+namespace Assimp {
namespace FBX {
const std::string EXPORT_VERSION_STR = "7.4.0";
const uint32_t EXPORT_VERSION_INT = 7400; // 7.4 == 2014/2015
@@ -92,11 +97,6 @@ namespace FBX {
";------------------------------------------------------------------";
}
-using namespace Assimp;
-using namespace FBX;
-
-namespace Assimp {
-
// ---------------------------------------------------------------------
// Worker function for exporting a scene to binary FBX.
// Prototyped and registered in Exporter.cpp
@@ -121,6 +121,7 @@ namespace Assimp {
IOSystem* pIOSystem,
const aiScene* pScene,
const ExportProperties* pProperties
+
){
// initialize the exporter
FBXExporter exporter(pScene, pProperties);
@@ -1218,6 +1219,16 @@ void FBXExporter::WriteObjects ()
layer.AddChild(le);
layer.Dump(outstream, binary, indent);
+ for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
+ {
+ FBX::Node layerExtra("Layer", int32_t(1));
+ layerExtra.AddChild("Version", int32_t(100));
+ FBX::Node leExtra("LayerElement");
+ leExtra.AddChild("Type", "LayerElementUV");
+ leExtra.AddChild("TypedIndex", int32_t(lr));
+ layerExtra.AddChild(leExtra);
+ layerExtra.Dump(outstream, binary, indent);
+ }
// finish the node record
indent = 1;
n.End(outstream, binary, indent, true);
@@ -1393,10 +1404,6 @@ void FBXExporter::WriteObjects ()
// FbxVideo - stores images used by textures.
for (const auto &it : uid_by_image) {
- if (it.first.compare(0, 1, "*") == 0) {
- // TODO: embedded textures
- continue;
- }
FBX::Node n("Video");
const int64_t& uid = it.second;
const std::string name = ""; // TODO: ... name???
@@ -1406,7 +1413,33 @@ void FBXExporter::WriteObjects ()
// TODO: get full path... relative path... etc... ugh...
// for now just use the same path for everything,
// and hopefully one of them will work out.
- const std::string& path = it.first;
+ std::string path = it.first;
+ // try get embedded texture
+ const aiTexture* embedded_texture = mScene->GetEmbeddedTexture(it.first.c_str());
+ if (embedded_texture != nullptr) {
+ // change the path (use original filename, if available. If name is empty, concatenate texture index with file extension)
+ std::stringstream newPath;
+ if (embedded_texture->mFilename.length > 0) {
+ newPath << embedded_texture->mFilename.C_Str();
+ } else if (embedded_texture->achFormatHint[0]) {
+ int texture_index = std::stoi(path.substr(1, path.size() - 1));
+ newPath << texture_index << "." << embedded_texture->achFormatHint;
+ }
+ path = newPath.str();
+ // embed the texture
+ size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
+ if (binary) {
+ // embed texture as binary data
+ std::vector<uint8_t> tex_data;
+ tex_data.resize(texture_size);
+ memcpy(&tex_data[0], (char*)embedded_texture->pcData, texture_size);
+ n.AddChild("Content", tex_data);
+ } else {
+ // embed texture in base64 encoding
+ std::string encoded_texture = FBX::Util::EncodeBase64((char*)embedded_texture->pcData, texture_size);
+ n.AddChild("Content", encoded_texture);
+ }
+ }
p.AddP70("Path", "KString", "XRefUrl", "", path);
n.AddChild(p);
n.AddChild("UseMipMap", int32_t(0));
@@ -1419,17 +1452,17 @@ void FBXExporter::WriteObjects ()
// referenced by material_index/texture_type pairs.
std::map<std::pair<size_t,size_t>,int64_t> texture_uids;
const std::map<aiTextureType,std::string> prop_name_by_tt = {
- {aiTextureType_DIFFUSE, "DiffuseColor"},
- {aiTextureType_SPECULAR, "SpecularColor"},
- {aiTextureType_AMBIENT, "AmbientColor"},
- {aiTextureType_EMISSIVE, "EmissiveColor"},
- {aiTextureType_HEIGHT, "Bump"},
- {aiTextureType_NORMALS, "NormalMap"},
- {aiTextureType_SHININESS, "ShininessExponent"},
- {aiTextureType_OPACITY, "TransparentColor"},
+ {aiTextureType_DIFFUSE, "DiffuseColor"},
+ {aiTextureType_SPECULAR, "SpecularColor"},
+ {aiTextureType_AMBIENT, "AmbientColor"},
+ {aiTextureType_EMISSIVE, "EmissiveColor"},
+ {aiTextureType_HEIGHT, "Bump"},
+ {aiTextureType_NORMALS, "NormalMap"},
+ {aiTextureType_SHININESS, "ShininessExponent"},
+ {aiTextureType_OPACITY, "TransparentColor"},
{aiTextureType_DISPLACEMENT, "DisplacementColor"},
//{aiTextureType_LIGHTMAP, "???"},
- {aiTextureType_REFLECTION, "ReflectionColor"}
+ {aiTextureType_REFLECTION, "ReflectionColor"}
//{aiTextureType_UNKNOWN, ""}
};
for (size_t i = 0; i < mScene->mNumMaterials; ++i) {
@@ -1575,19 +1608,41 @@ void FBXExporter::WriteObjects ()
// one sticky point is that the number of vertices may not match,
// because assimp splits vertices by normal, uv, etc.
+ // functor for aiNode sorting
+ struct SortNodeByName
+ {
+ bool operator()(const aiNode *lhs, const aiNode *rhs) const
+ {
+ return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0;
+ }
+ };
+
// first we should mark the skeleton for each mesh.
// the skeleton must include not only the aiBones,
// but also all their parent nodes.
// anything that affects the position of any bone node must be included.
- std::vector<std::set<const aiNode*>> skeleton_by_mesh(mScene->mNumMeshes);
+ // Use SorNodeByName to make sure the exported result will be the same across all systems
+ // Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent
+ std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes);
// at the same time we can build a list of all the skeleton nodes,
// which will be used later to mark them as type "limbNode".
std::unordered_set<const aiNode*> limbnodes;
+
+ //actual bone nodes in fbx, without parenting-up
+ std::unordered_set<std::string> setAllBoneNamesInScene;
+ for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
+ {
+ aiMesh* pMesh = mScene->mMeshes[m];
+ for(unsigned int b = 0; b < pMesh->mNumBones; ++ b)
+ setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
+ }
+ aiMatrix4x4 mxTransIdentity;
+
// and a map of nodes by bone name, as finding them is annoying.
std::map<std::string,aiNode*> node_by_bone;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi];
- std::set<const aiNode*> skeleton;
+ std::set<const aiNode*, SortNodeByName> skeleton;
for (size_t bi =0; bi < m->mNumBones; ++bi) {
const aiBone* b = m->mBones[bi];
const std::string name(b->mName.C_Str());
@@ -1626,6 +1681,11 @@ void FBXExporter::WriteObjects ()
if (node_name.find(MAGIC_NODE_TAG) != std::string::npos) {
continue;
}
+ //not a bone in scene && no effect in transform
+ if(setAllBoneNamesInScene.find(node_name)==setAllBoneNamesInScene.end()
+ && parent->mTransformation == mxTransIdentity) {
+ continue;
+ }
// otherwise check if this is the root of the skeleton
bool end = false;
// is the mesh part of this node?
@@ -1646,8 +1706,7 @@ void FBXExporter::WriteObjects ()
}
if (end) { break; }
}
- limbnodes.insert(parent);
- skeleton.insert(parent);
+
// if it was the skeleton root we can finish here
if (end) { break; }
}
@@ -1728,7 +1787,7 @@ void FBXExporter::WriteObjects ()
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
// now make a subdeformer for each bone in the skeleton
- const std::set<const aiNode*> &skeleton = skeleton_by_mesh[mi];
+ const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi];
for (const aiNode* bone_node : skeleton) {
// if there's a bone for this node, find it
const aiBone* b = nullptr;
@@ -1788,41 +1847,10 @@ void FBXExporter::WriteObjects ()
inverse_bone_xform.Inverse();
aiMatrix4x4 tr = inverse_bone_xform * mesh_xform;
- // this should be the same as the bone's mOffsetMatrix.
- // if it's not the same, the skeleton isn't in the bind pose.
- const float epsilon = 1e-4f; // some error is to be expected
- bool bone_xform_okay = true;
- if (b && ! tr.Equal(b->mOffsetMatrix, epsilon)) {
- not_in_bind_pose.insert(b);
- bone_xform_okay = false;
- }
+ sdnode.AddChild("Transform", tr);
- // if we have a bone we should use the mOffsetMatrix,
- // otherwise try to just use the calculated transform.
- if (b) {
- sdnode.AddChild("Transform", b->mOffsetMatrix);
- } else {
- sdnode.AddChild("Transform", tr);
- }
- // note: it doesn't matter if we mix these,
- // because if they disagree we'll throw an exception later.
- // it could be that the skeleton is not in the bone pose
- // but all bones are still defined,
- // in which case this would use the mOffsetMatrix for everything
- // and a correct skeleton would still be output.
-
- // transformlink should be the position of the bone in world space.
- // if the bone is in the bind pose (or nonexistent),
- // we can just use the matrix we already calculated
- if (bone_xform_okay) {
- sdnode.AddChild("TransformLink", bone_xform);
- // otherwise we can only work it out using the mesh position.
- } else {
- aiMatrix4x4 trl = b->mOffsetMatrix;
- trl.Inverse();
- trl *= mesh_xform;
- sdnode.AddChild("TransformLink", trl);
- }
+
+ sdnode.AddChild("TransformLink", bone_xform);
// note: this means we ALWAYS rely on the mesh node transform
// being unchanged from the time the skeleton was bound.
// there's not really any way around this at the moment.
@@ -2237,8 +2265,8 @@ void FBXExporter::WriteModelNode(
// not sure what these are for,
// but they seem to be omnipresent
- m.AddChild("Shading", Property(true));
- m.AddChild("Culling", Property("CullingOff"));
+ m.AddChild("Shading", FBXExportProperty(true));
+ m.AddChild("Culling", FBXExportProperty("CullingOff"));
m.Dump(outstream, binary, 1);
}
@@ -2351,7 +2379,7 @@ void FBXExporter::WriteModelNodes(
na.AddProperties(
node_attribute_uid, FBX::SEPARATOR + "NodeAttribute", "LimbNode"
);
- na.AddChild("TypeFlags", Property("Skeleton"));
+ na.AddChild("TypeFlags", FBXExportProperty("Skeleton"));
na.Dump(outstream, binary, 1);
// and connect them
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
diff --git a/thirdparty/assimp/code/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h
index 71fb55c57f..71fb55c57f 100644
--- a/thirdparty/assimp/code/FBXExporter.h
+++ b/thirdparty/assimp/code/FBX/FBXExporter.h
diff --git a/thirdparty/assimp/code/FBXImportSettings.h b/thirdparty/assimp/code/FBX/FBXImportSettings.h
index d5e1c20608..1a4c80f8b2 100644
--- a/thirdparty/assimp/code/FBXImportSettings.h
+++ b/thirdparty/assimp/code/FBX/FBXImportSettings.h
@@ -53,19 +53,22 @@ namespace FBX {
struct ImportSettings
{
ImportSettings()
- : strictMode(true)
- , readAllLayers(true)
- , readAllMaterials(false)
- , readMaterials(true)
- , readTextures(true)
- , readCameras(true)
- , readLights(true)
- , readAnimations(true)
- , readWeights(true)
- , preservePivots(true)
- , optimizeEmptyAnimationCurves(true)
- , useLegacyEmbeddedTextureNaming(false)
- {}
+ : strictMode(true)
+ , readAllLayers(true)
+ , readAllMaterials(false)
+ , readMaterials(true)
+ , readTextures(true)
+ , readCameras(true)
+ , readLights(true)
+ , readAnimations(true)
+ , readWeights(true)
+ , preservePivots(true)
+ , optimizeEmptyAnimationCurves(true)
+ , useLegacyEmbeddedTextureNaming(false)
+ , removeEmptyBones( true )
+ , convertToMeters( false ) {
+ // empty
+ }
/** enable strict mode:
@@ -141,8 +144,16 @@ struct ImportSettings
bool optimizeEmptyAnimationCurves;
/** use legacy naming for embedded textures eg: (*0, *1, *2)
- **/
+ */
bool useLegacyEmbeddedTextureNaming;
+
+ /** Empty bones shall be removed
+ */
+ bool removeEmptyBones;
+
+ /** Set to true to perform a conversion from cm to meter after the import
+ */
+ bool convertToMeters;
};
diff --git a/thirdparty/assimp/code/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp
index 2cc8bffc29..271935a568 100644
--- a/thirdparty/assimp/code/FBXImporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp
@@ -140,6 +140,8 @@ void FBXImporter::SetupProperties(const Importer* pImp)
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
+ settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+ settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
}
// ------------------------------------------------------------------------------------------------
@@ -170,7 +172,7 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
bool is_binary = false;
if (!strncmp(begin,"Kaydara FBX Binary",18)) {
is_binary = true;
- TokenizeBinary(tokens,begin,static_cast<unsigned int>(contents.size()));
+ TokenizeBinary(tokens,begin,contents.size());
}
else {
Tokenize(tokens,begin);
@@ -183,8 +185,20 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// take the raw parse-tree and convert it to a FBX DOM
Document doc(parser,settings);
+ FbxUnit unit(FbxUnit::cm);
+ if (settings.convertToMeters) {
+ unit = FbxUnit::m;
+ }
+
// convert the FBX DOM to aiScene
- ConvertToAssimpScene(pScene,doc);
+ ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+
+ // size relative to cm
+ float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
+
+ // Set FBX file scale is relative to CM must be converted to M for
+ // assimp universal format (M)
+ SetFileScale( size_relative_to_cm * 0.01f);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
}
diff --git a/thirdparty/assimp/code/FBXImporter.h b/thirdparty/assimp/code/FBX/FBXImporter.h
index c365b2cddf..c365b2cddf 100644
--- a/thirdparty/assimp/code/FBXImporter.h
+++ b/thirdparty/assimp/code/FBX/FBXImporter.h
diff --git a/thirdparty/assimp/code/FBXMaterial.cpp b/thirdparty/assimp/code/FBX/FBXMaterial.cpp
index f16f134404..f43a8b84b0 100644
--- a/thirdparty/assimp/code/FBXMaterial.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMaterial.cpp
@@ -316,7 +316,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
}
- if(Content) {
+ if(Content && !Content->Tokens().empty()) {
//this field is omitted when the embedded texture is already loaded, let's ignore if it's not found
try {
const Token& token = GetRequiredToken(*Content, 0);
@@ -326,16 +326,40 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
DOMError("embedded content is not surrounded by quotation marks", &element);
}
else {
- const char* encodedData = data + 1;
- size_t encodedDataLen = static_cast<size_t>(token.end() - token.begin());
- // search for last quotation mark
- while (encodedDataLen > 1 && encodedData[encodedDataLen] != '"')
- encodedDataLen--;
- if (encodedDataLen % 4 != 0) {
- DOMError("embedded content is invalid, needs to be in base64", &element);
+ size_t targetLength = 0;
+ auto numTokens = Content->Tokens().size();
+ // First time compute size (it could be large like 64Gb and it is good to allocate it once)
+ for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
+ {
+ const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
+ size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
+ const char* base64data = dataToken.begin() + 1;
+ const size_t outLength = Util::ComputeDecodedSizeBase64(base64data, tokenLength);
+ if (outLength == 0)
+ {
+ DOMError("Corrupted embedded content found", &element);
+ }
+ targetLength += outLength;
}
- else {
- contentLength = Util::DecodeBase64(encodedData, encodedDataLen, content);
+ if (targetLength == 0)
+ {
+ DOMError("Corrupted embedded content found", &element);
+ }
+ content = new uint8_t[targetLength];
+ contentLength = static_cast<uint64_t>(targetLength);
+ size_t dst_offset = 0;
+ for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
+ {
+ const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
+ size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
+ const char* base64data = dataToken.begin() + 1;
+ dst_offset += Util::DecodeBase64(base64data, tokenLength, content + dst_offset, targetLength - dst_offset);
+ }
+ if (targetLength != dst_offset)
+ {
+ delete[] content;
+ contentLength = 0;
+ DOMError("Corrupted embedded content found", &element);
}
}
}
diff --git a/thirdparty/assimp/code/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
index d75476b826..5c9a0e309d 100644
--- a/thirdparty/assimp/code/FBXMeshGeometry.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
@@ -115,7 +115,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
if(tempVerts.empty()) {
FBXImporter::LogWarn("encountered mesh with no vertices");
- return;
}
std::vector<int> tempFaces;
@@ -123,7 +122,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
if(tempFaces.empty()) {
FBXImporter::LogWarn("encountered mesh with no faces");
- return;
}
m_vertices.reserve(tempFaces.size());
@@ -568,15 +566,15 @@ void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, cons
}
// ------------------------------------------------------------------------------------------------
-static const std::string TangentIndexToken = "TangentIndex";
-static const std::string TangentsIndexToken = "TangentsIndex";
+static const char *TangentIndexToken = "TangentIndex";
+static const char *TangentsIndexToken = "TangentsIndex";
void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
const std::string& MappingInformationType,
const std::string& ReferenceInformationType)
{
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
- const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
+ const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken;
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
str,
strIdx,
@@ -612,7 +610,10 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
const std::string& ReferenceInformationType)
{
const size_t face_count = m_faces.size();
- ai_assert(face_count);
+ if(face_count <= 0)
+ {
+ return;
+ }
// materials are handled separately. First of all, they are assigned per-face
// and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
@@ -630,10 +631,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
materials_out.clear();
}
- m_materials.assign(m_vertices.size(),materials_out[0]);
+ materials_out.resize(m_vertices.size());
+ std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0));
}
else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
- m_materials.resize(face_count);
+ materials_out.resize(face_count);
if(materials_out.size() != face_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
diff --git a/thirdparty/assimp/code/FBXMeshGeometry.h b/thirdparty/assimp/code/FBX/FBXMeshGeometry.h
index d6d4512177..d6d4512177 100644
--- a/thirdparty/assimp/code/FBXMeshGeometry.h
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.h
diff --git a/thirdparty/assimp/code/FBXModel.cpp b/thirdparty/assimp/code/FBX/FBXModel.cpp
index 589af36ac7..589af36ac7 100644
--- a/thirdparty/assimp/code/FBXModel.cpp
+++ b/thirdparty/assimp/code/FBX/FBXModel.cpp
diff --git a/thirdparty/assimp/code/FBXNodeAttribute.cpp b/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp
index b72e5637ee..b72e5637ee 100644
--- a/thirdparty/assimp/code/FBXNodeAttribute.cpp
+++ b/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp
diff --git a/thirdparty/assimp/code/FBXParser.cpp b/thirdparty/assimp/code/FBX/FBXParser.cpp
index b255c47347..4a9346040d 100644
--- a/thirdparty/assimp/code/FBXParser.cpp
+++ b/thirdparty/assimp/code/FBX/FBXParser.cpp
@@ -117,7 +117,7 @@ namespace FBX {
Element::Element(const Token& key_token, Parser& parser)
: key_token(key_token)
{
- TokenPtr n = NULL;
+ TokenPtr n = nullptr;
do {
n = parser.AdvanceToNextToken();
if(!n) {
@@ -643,9 +643,9 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count3; ++i, d += 3) {
- out.push_back(aiVector3D(static_cast<float>(d[0]),
- static_cast<float>(d[1]),
- static_cast<float>(d[2])));
+ out.push_back(aiVector3D(static_cast<ai_real>(d[0]),
+ static_cast<ai_real>(d[1]),
+ static_cast<ai_real>(d[2])));
}
// for debugging
/*for ( size_t i = 0; i < out.size(); i++ ) {
@@ -963,7 +963,6 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
}
}
-
// ------------------------------------------------------------------------------------------------
// read an array of uints
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
@@ -1280,7 +1279,6 @@ float ParseTokenAsFloat(const Token& t)
return i;
}
-
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt() with ParseError handling
int ParseTokenAsInt(const Token& t)
@@ -1293,8 +1291,6 @@ int ParseTokenAsInt(const Token& t)
return i;
}
-
-
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt64() with ParseError handling
int64_t ParseTokenAsInt64(const Token& t)
diff --git a/thirdparty/assimp/code/FBXParser.h b/thirdparty/assimp/code/FBX/FBXParser.h
index 7b0cf72039..7b0cf72039 100644
--- a/thirdparty/assimp/code/FBXParser.h
+++ b/thirdparty/assimp/code/FBX/FBXParser.h
diff --git a/thirdparty/assimp/code/FBXProperties.cpp b/thirdparty/assimp/code/FBX/FBXProperties.cpp
index 8d7036b6a9..8d7036b6a9 100644
--- a/thirdparty/assimp/code/FBXProperties.cpp
+++ b/thirdparty/assimp/code/FBX/FBXProperties.cpp
diff --git a/thirdparty/assimp/code/FBXProperties.h b/thirdparty/assimp/code/FBX/FBXProperties.h
index 58755542fc..58755542fc 100644
--- a/thirdparty/assimp/code/FBXProperties.h
+++ b/thirdparty/assimp/code/FBX/FBXProperties.h
diff --git a/thirdparty/assimp/code/FBXTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXTokenizer.cpp
index 252cce3557..252cce3557 100644
--- a/thirdparty/assimp/code/FBXTokenizer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXTokenizer.cpp
diff --git a/thirdparty/assimp/code/FBXTokenizer.h b/thirdparty/assimp/code/FBX/FBXTokenizer.h
index 2af29743f4..afa588a470 100644
--- a/thirdparty/assimp/code/FBXTokenizer.h
+++ b/thirdparty/assimp/code/FBX/FBXTokenizer.h
@@ -93,7 +93,7 @@ public:
Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column);
/** construct a binary token */
- Token(const char* sbegin, const char* send, TokenType type, unsigned int offset);
+ Token(const char* sbegin, const char* send, TokenType type, size_t offset);
~Token();
@@ -118,14 +118,14 @@ public:
return type;
}
- unsigned int Offset() const {
+ size_t Offset() const {
ai_assert(IsBinary());
return offset;
}
unsigned int Line() const {
ai_assert(!IsBinary());
- return line;
+ return static_cast<unsigned int>(line);
}
unsigned int Column() const {
@@ -147,8 +147,8 @@ private:
const TokenType type;
union {
- const unsigned int line;
- unsigned int offset;
+ size_t line;
+ size_t offset;
};
const unsigned int column;
};
@@ -178,7 +178,7 @@ void Tokenize(TokenList& output_tokens, const char* input);
* @param input_buffer Binary input buffer to be processed.
* @param length Length of input buffer, in bytes. There is no 0-terminal.
* @throw DeadlyImportError if something goes wrong */
-void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length);
+void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length);
} // ! FBX
diff --git a/thirdparty/assimp/code/FBXUtil.cpp b/thirdparty/assimp/code/FBX/FBXUtil.cpp
index fb483161b2..c10e057c8c 100644
--- a/thirdparty/assimp/code/FBXUtil.cpp
+++ b/thirdparty/assimp/code/FBX/FBXUtil.cpp
@@ -86,7 +86,7 @@ const char* TokenTypeString(TokenType t)
// ------------------------------------------------------------------------------------------------
-std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset)
+std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) );
}
@@ -114,47 +114,126 @@ std::string AddTokenText(const std::string& prefix, const std::string& text, con
text) );
}
+// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
static const uint8_t base64DecodeTable[128] = {
- 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, 62, 0, 0, 0, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
- 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255
};
uint8_t DecodeBase64(char ch)
{
- return base64DecodeTable[size_t(ch)];
+ const auto idx = static_cast<uint8_t>(ch);
+ if (idx > 127)
+ return 255;
+ return base64DecodeTable[idx];
}
-size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
+size_t ComputeDecodedSizeBase64(const char* in, size_t inLength)
{
- if (inLength < 4) {
- out = 0;
+ if (inLength < 2)
+ {
+ return 0;
+ }
+ const size_t equals = size_t(in[inLength - 1] == '=') + size_t(in[inLength - 2] == '=');
+ const size_t full_length = (inLength * 3) >> 2; // div by 4
+ if (full_length < equals)
+ {
+ return 0;
+ }
+ return full_length - equals;
+}
+
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength)
+{
+ if (maxOutLength == 0 || inLength < 2) {
return 0;
}
+ const size_t realLength = inLength - size_t(in[inLength - 1] == '=') - size_t(in[inLength - 2] == '=');
+ size_t dst_offset = 0;
+ int val = 0, valb = -8;
+ for (size_t src_offset = 0; src_offset < realLength; ++src_offset)
+ {
+ const uint8_t table_value = Util::DecodeBase64(in[src_offset]);
+ if (table_value == 255)
+ {
+ return 0;
+ }
+ val = (val << 6) + table_value;
+ valb += 6;
+ if (valb >= 0)
+ {
+ out[dst_offset++] = static_cast<uint8_t>((val >> valb) & 0xFF);
+ valb -= 8;
+ val &= 0xFFF;
+ }
+ }
+ return dst_offset;
+}
- const size_t outLength = (inLength * 3) / 4;
- out = new uint8_t[outLength];
- memset(out, 0, outLength);
+static const char to_base64_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+char EncodeBase64(char byte)
+{
+ return to_base64_string[(size_t)byte];
+}
- size_t i = 0;
- size_t j = 0;
- for (i = 0; i < inLength - 4; i += 4)
+/** Encodes a block of 4 bytes to base64 encoding
+*
+* @param bytes Bytes to encode.
+* @param out_string String to write encoded values to.
+* @param string_pos Position in out_string.*/
+void EncodeByteBlock(const char* bytes, std::string& out_string, size_t string_pos)
+{
+ char b0 = (bytes[0] & 0xFC) >> 2;
+ char b1 = (bytes[0] & 0x03) << 4 | ((bytes[1] & 0xF0) >> 4);
+ char b2 = (bytes[1] & 0x0F) << 2 | ((bytes[2] & 0xC0) >> 6);
+ char b3 = (bytes[2] & 0x3F);
+
+ out_string[string_pos + 0] = EncodeBase64(b0);
+ out_string[string_pos + 1] = EncodeBase64(b1);
+ out_string[string_pos + 2] = EncodeBase64(b2);
+ out_string[string_pos + 3] = EncodeBase64(b3);
+}
+
+std::string EncodeBase64(const char* data, size_t length)
+{
+ // calculate extra bytes needed to get a multiple of 3
+ size_t extraBytes = 3 - length % 3;
+
+ // number of base64 bytes
+ size_t encodedBytes = 4 * (length + extraBytes) / 3;
+
+ std::string encoded_string(encodedBytes, '=');
+
+ // read blocks of 3 bytes
+ for (size_t ib3 = 0; ib3 < length / 3; ib3++)
{
- uint8_t b0 = Util::DecodeBase64(in[i]);
- uint8_t b1 = Util::DecodeBase64(in[i + 1]);
- uint8_t b2 = Util::DecodeBase64(in[i + 2]);
- uint8_t b3 = Util::DecodeBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- out[j++] = (uint8_t)((b2 << 6) | b3);
+ const size_t iByte = ib3 * 3;
+ const size_t iEncodedByte = ib3 * 4;
+ const char* currData = &data[iByte];
+
+ EncodeByteBlock(currData, encoded_string, iEncodedByte);
+ }
+
+ // if size of data is not a multiple of 3, also encode the final bytes (and add zeros where needed)
+ if (extraBytes > 0)
+ {
+ char finalBytes[4] = { 0,0,0,0 };
+ memcpy(&finalBytes[0], &data[length - length % 3], length % 3);
+
+ const size_t iEncodedByte = encodedBytes - 4;
+ EncodeByteBlock(&finalBytes[0], encoded_string, iEncodedByte);
+
+ // add '=' at the end
+ for (size_t i = 0; i < 4 * extraBytes / 3; i++)
+ encoded_string[encodedBytes - i - 1] = '=';
}
- return outLength;
+ return encoded_string;
}
} // !Util
diff --git a/thirdparty/assimp/code/FBXUtil.h b/thirdparty/assimp/code/FBX/FBXUtil.h
index 6890e015ba..b634418858 100644
--- a/thirdparty/assimp/code/FBXUtil.h
+++ b/thirdparty/assimp/code/FBX/FBXUtil.h
@@ -78,7 +78,7 @@ const char* TokenTypeString(TokenType t);
* @param line Line index, 1-based
* @param column Column index, 1-based
* @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/
-std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset);
+std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset);
/** Format log/error messages using a given line location in the source file.
@@ -105,13 +105,30 @@ std::string AddTokenText(const std::string& prefix, const std::string& text, con
* @return decoded byte value*/
uint8_t DecodeBase64(char ch);
+/** Compute decoded size of a Base64-encoded string
+*
+* @param in Characters to decode.
+* @param inLength Number of characters to decode.
+* @return size of the decoded data (number of bytes)*/
+size_t ComputeDecodedSizeBase64(const char* in, size_t inLength);
+
/** Decode a Base64-encoded string
*
* @param in Characters to decode.
* @param inLength Number of characters to decode.
-* @param out Reference to pointer where we will store the decoded data.
+* @param out Pointer where we will store the decoded data.
+* @param maxOutLength Size of output buffer.
* @return size of the decoded data (number of bytes)*/
-size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength);
+
+char EncodeBase64(char byte);
+
+/** Encode bytes in base64-encoding
+*
+* @param data Binary data to encode.
+* @param inLength Number of bytes to encode.
+* @return base64-encoded string*/
+std::string EncodeBase64(const char* data, size_t length);
}
}
diff --git a/thirdparty/assimp/code/FIReader.cpp b/thirdparty/assimp/code/FIReader.cpp
deleted file mode 100644
index 2116316ca3..0000000000
--- a/thirdparty/assimp/code/FIReader.cpp
+++ /dev/null
@@ -1,1834 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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.
-
-----------------------------------------------------------------------
-*/
-/// \file FIReader.cpp
-/// \brief Reader for Fast Infoset encoded binary XML files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "FIReader.hpp"
-#include <assimp/StringUtils.h>
-
-// Workaround for issue #1361
-// https://github.com/assimp/assimp/issues/1361
-#ifdef __ANDROID__
-# define _GLIBCXX_USE_C99 1
-#endif
-
-#include <assimp/Exceptional.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/types.h>
-#include <assimp/MemoryIOWrapper.h>
-#include <assimp/irrXMLWrapper.h>
-#include "../contrib/utf8cpp/source/utf8.h"
-#include <assimp/fast_atof.h>
-#include <stack>
-#include <map>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-namespace Assimp {
-
-static const std::string parseErrorMessage = "Fast Infoset parse error";
-
-static const char *xmlDeclarations[] = {
- "<?xml encoding='finf'?>",
- "<?xml encoding='finf' standalone='yes'?>",
- "<?xml encoding='finf' standalone='no'?>",
- "<?xml version='1.0' encoding='finf'?>",
- "<?xml version='1.0' encoding='finf' standalone='yes'?>",
- "<?xml version='1.0' encoding='finf' standalone='no'?>",
- "<?xml version='1.1' encoding='finf'?>",
- "<?xml version='1.1' encoding='finf' standalone='yes'?>",
- "<?xml version='1.1' encoding='finf' standalone='no'?>"
-};
-
-static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) {
- if (dataEnd - data < 4) {
- return 0;
- }
- uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- switch (magic) {
- case 0xe0000001:
- return 4;
- case 0x3c3f786d: // "<?xm"
- {
- size_t xmlDeclarationsLength = sizeof(xmlDeclarations) / sizeof(xmlDeclarations[0]);
- for (size_t i = 0; i < xmlDeclarationsLength; ++i) {
- auto xmlDeclaration = xmlDeclarations[i];
- ptrdiff_t xmlDeclarationLength = strlen(xmlDeclaration);
- if ((dataEnd - data >= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) {
- data += xmlDeclarationLength;
- if (dataEnd - data < 4) {
- return 0;
- }
- magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- return magic == 0xe0000001 ? xmlDeclarationLength + 4 : 0;
- }
- }
- return 0;
- }
- default:
- return 0;
- }
-}
-
-static std::string parseUTF8String(const uint8_t *data, size_t len) {
- return std::string((char*)data, len);
-}
-
-static std::string parseUTF16String(const uint8_t *data, size_t len) {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t numShorts = len / 2;
- std::vector<short> utf16;
- utf16.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- short v = (data[0] << 8) | data[1];
- utf16.push_back(v);
- data += 2;
- }
- std::string result;
- utf8::utf16to8(utf16.begin(), utf16.end(), back_inserter(result));
- return result;
-}
-
-struct FIStringValueImpl: public FIStringValue {
- inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
- return std::make_shared<FIStringValueImpl>(std::move(value));
-}
-
-struct FIHexValueImpl: public FIHexValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIHexValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast<int>(c); });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIHexValueImpl>(std::move(value));
-}
-
-struct FIBase64ValueImpl: public FIBase64Value {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBase64ValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- uint8_t c1 = 0, c2;
- int imod3 = 0;
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- c2 = value[i];
- switch (imod3) {
- case 0:
- os << basis_64[c2 >> 2];
- imod3 = 1;
- break;
- case 1:
- os << basis_64[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
- imod3 = 2;
- break;
- case 2:
- os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f];
- imod3 = 0;
- break;
- }
- c1 = c2;
- }
- switch (imod3) {
- case 1:
- os << basis_64[(c1 & 0x03) << 4] << "==";
- break;
- case 2:
- os << basis_64[(c1 & 0x0f) << 2] << '=';
- break;
- }
- strValue = os.str();
- }
- return strValue;
- };
- static const char basis_64[];
-};
-
-const char FIBase64ValueImpl::basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-std::shared_ptr<FIBase64Value> FIBase64Value::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIBase64ValueImpl>(std::move(value));
-}
-
-struct FIShortValueImpl: public FIShortValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIShortValueImpl(std::vector<int16_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIShortValue> FIShortValue::create(std::vector<int16_t> &&value) {
- return std::make_shared<FIShortValueImpl>(std::move(value));
-}
-
-struct FIIntValueImpl: public FIIntValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIIntValueImpl(std::vector<int32_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int32_t i) { if (++n > 1) os << ' '; os << i; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIIntValue> FIIntValue::create(std::vector<int32_t> &&value) {
- return std::make_shared<FIIntValueImpl>(std::move(value));
-}
-
-struct FILongValueImpl: public FILongValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FILongValueImpl(std::vector<int64_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int64_t l) { if (++n > 1) os << ' '; os << l; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FILongValue> FILongValue::create(std::vector<int64_t> &&value) {
- return std::make_shared<FILongValueImpl>(std::move(value));
-}
-
-struct FIBoolValueImpl: public FIBoolValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBoolValueImpl(std::vector<bool> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::boolalpha;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](bool b) { if (++n > 1) os << ' '; os << b; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIBoolValue> FIBoolValue::create(std::vector<bool> &&value) {
- return std::make_shared<FIBoolValueImpl>(std::move(value));
-}
-
-struct FIFloatValueImpl: public FIFloatValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIFloatValueImpl(std::vector<float> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIFloatValue> FIFloatValue::create(std::vector<float> &&value) {
- return std::make_shared<FIFloatValueImpl>(std::move(value));
-}
-
-struct FIDoubleValueImpl: public FIDoubleValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIDoubleValueImpl(std::vector<double> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](double d) { if (++n > 1) os << ' '; os << d; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIDoubleValue> FIDoubleValue::create(std::vector<double> &&value) {
- return std::make_shared<FIDoubleValueImpl>(std::move(value));
-}
-
-struct FIUUIDValueImpl: public FIUUIDValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIUUIDValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- switch (i & 15) {
- case 0:
- if (i > 0) {
- os << ' ';
- }
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- case 4:
- case 6:
- case 8:
- case 10:
- os << '-';
- // intentionally fall through!
- case 1:
- case 2:
- case 3:
- case 5:
- case 7:
- case 9:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- }
- }
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIUUIDValueImpl>(std::move(value));
-}
-
-struct FICDATAValueImpl: public FICDATAValue {
- inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
- return std::make_shared<FICDATAValueImpl>(std::move(value));
-}
-
-struct FIHexDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIHexValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIBase64Decoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIBase64Value::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIShortDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int16_t> value;
- size_t numShorts = len / 2;
- value.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- int16_t v = (data[0] << 8) | data[1];
- value.push_back(v);
- data += 2;
- }
- return FIShortValue::create(std::move(value));
- }
-};
-
-struct FIIntDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int32_t> value;
- size_t numInts = len / 4;
- value.reserve(numInts);
- for (size_t i = 0; i < numInts; ++i) {
- int32_t v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- value.push_back(v);
- data += 4;
- }
- return FIIntValue::create(std::move(value));
- }
-};
-
-struct FILongDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int64_t> value;
- size_t numLongs = len / 8;
- value.reserve(numLongs);
- for (size_t i = 0; i < numLongs; ++i) {
- int64_t b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- int64_t v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- value.push_back(v);
- data += 8;
- }
- return FILongValue::create(std::move(value));
- }
-};
-
-struct FIBoolDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<bool> value;
- uint8_t b = *data++;
- size_t unusedBits = b >> 4;
- size_t numBools = (len * 8) - 4 - unusedBits;
- value.reserve(numBools);
- uint8_t mask = 1 << 3;
- for (size_t i = 0; i < numBools; ++i) {
- if (!mask) {
- mask = 1 << 7;
- b = *data++;
- }
- value.push_back((b & mask) != 0);
- }
- return FIBoolValue::create(std::move(value));
- }
-};
-
-struct FIFloatDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<float> value;
- size_t numFloats = len / 4;
- value.reserve(numFloats);
- for (size_t i = 0; i < numFloats; ++i) {
- int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- float f;
- memcpy(&f, &v, 4);
- value.push_back(f);
- data += 4;
- }
- return FIFloatValue::create(std::move(value));
- }
-};
-
-struct FIDoubleDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<double> value;
- size_t numDoubles = len / 8;
- value.reserve(numDoubles);
- for (size_t i = 0; i < numDoubles; ++i) {
- long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- double f;
- memcpy(&f, &v, 8);
- value.push_back(f);
- data += 8;
- }
- return FIDoubleValue::create(std::move(value));
- }
-};
-
-struct FIUUIDDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 15) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return FIUUIDValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FICDATADecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FICDATAValue::create(parseUTF8String(data, len));
- }
-};
-
-class CFIReaderImpl: public FIReader {
-public:
-
- CFIReaderImpl(std::unique_ptr<uint8_t[]> data_, size_t size):
- data(std::move(data_)), dataP(data.get()), dataEnd(data.get() + size), currentNodeType(irr::io::EXN_NONE),
- emptyElement(false), headerPending(true), terminatorPending(false)
- {}
-
- virtual ~CFIReaderImpl() {}
-
- virtual bool read() /*override*/ {
- if (headerPending) {
- headerPending = false;
- parseHeader();
- }
- if (terminatorPending) {
- terminatorPending = false;
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- if (dataP >= dataEnd) {
- return false;
- }
- uint8_t b = *dataP;
- if (b < 0x80) { // Element (C.2.11.2, C.3.7.2)
- // C.3
- parseElement();
- return true;
- }
- else if (b < 0xc0) { // Characters (C.3.7.5)
- // C.7
- auto chars = parseNonIdentifyingStringOrIndex3(vocabulary.charactersTable);
- nodeName = chars->toString();
- currentNodeType = irr::io::EXN_TEXT;
- return true;
- }
- else if (b < 0xe0) {
- if ((b & 0xfc) == 0xc4) { // DTD (C.2.11.5)
- // C.9
- ++dataP;
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- elementStack.push(EmptyString);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if ((b & 0xfc) == 0xc8) { // Unexpanded entity reference (C.3.7.4)
- // C.6
- ++dataP;
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- }
- else if (b < 0xf0) {
- if (b == 0xe1) { // Processing instruction (C.2.11.3, C.3.7.3)
- // C.5
- ++dataP;
- /*const std::string &target =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> data =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if (b == 0xe2) { // Comment (C.2.11.4, C.3.7.6)
- // C.8
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::shared_ptr<const FIValue> comment = parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- nodeName = comment->toString();
- currentNodeType = irr::io::EXN_COMMENT;
- return true;
- }
- }
- else { // Terminator (C.2.12, C.3.8)
- ++dataP;
- if (b == 0xff) {
- terminatorPending = true;
- }
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return currentNodeType;
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return static_cast<int>(attributes.size());
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].name.c_str();
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value->toString().c_str();
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value->toString().c_str();
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return EmptyString.c_str();
- }
- return attr->value->toString().c_str();
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attr->value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attr->value->toString().c_str());
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attributes[idx].value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attributes[idx].value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attr->value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
-
- return fast_atof(attr->value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attributes[idx].value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
- return fast_atof(attributes[idx].value->toString().c_str());
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return emptyElement;
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value;
- }
-
- virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {
- decoderMap[algorithmUri] = std::move(decoder);
- }
-
- virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {
- vocabularyMap[vocabularyUri] = vocabulary;
- }
-
-private:
-
- struct QName {
- std::string prefix;
- std::string uri;
- std::string name;
- inline QName() {}
- inline QName(const FIQName &qname): prefix(qname.prefix ? qname.prefix : ""), uri(qname.uri ? qname.uri : ""), name(qname.name) {}
- };
-
- struct Attribute {
- QName qname;
- std::string name;
- std::shared_ptr<const FIValue> value;
- };
-
- struct Vocabulary {
- std::vector<std::string> restrictedAlphabetTable;
- std::vector<std::string> encodingAlgorithmTable;
- std::vector<std::string> prefixTable;
- std::vector<std::string> namespaceNameTable;
- std::vector<std::string> localNameTable;
- std::vector<std::string> otherNCNameTable;
- std::vector<std::string> otherURITable;
- std::vector<std::shared_ptr<const FIValue>> attributeValueTable;
- std::vector<std::shared_ptr<const FIValue>> charactersTable;
- std::vector<std::shared_ptr<const FIValue>> otherStringTable;
- std::vector<QName> elementNameTable;
- std::vector<QName> attributeNameTable;
- Vocabulary() {
- prefixTable.push_back("xml");
- namespaceNameTable.push_back("http://www.w3.org/XML/1998/namespace");
- }
- };
-
- const Attribute* getAttributeByName(const char* name) const {
- if (!name) {
- return 0;
- }
- std::string n = name;
- for (int i=0; i<(int)attributes.size(); ++i) {
- if (attributes[i].name == n) {
- return &attributes[i];
- }
- }
- return 0;
- }
-
- size_t parseInt2() { // C.25
- uint8_t b = *dataP++;
- if (!(b & 0x40)) { // x0...... (C.25.2)
- return b & 0x3f;
- }
- else if ((b & 0x60) == 0x40) { // x10..... ........ (C.25.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x1f) << 8) | *dataP++) + 0x40;
- }
- }
- else if ((b & 0x70) == 0x60) { // x110.... ........ ........ (C.25.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x2040;
- dataP += 2;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt3() { // C.27
- uint8_t b = *dataP++;
- if (!(b & 0x20)) { // xx0..... (C.27.2)
- return b & 0x1f;
- }
- else if ((b & 0x38) == 0x20) { // xx100... ........ (C.27.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x07) << 8) | *dataP++) + 0x20;
- }
- }
- else if ((b & 0x38) == 0x28) { // xx101... ........ ........ (C.27.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x07) << 16) | (dataP[0] << 8) | dataP[1]) + 0x820;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x3f) == 0x30) { // xx110000 0000.... ........ ........ (C.27.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x80820;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt4() { // C.28
- uint8_t b = *dataP++;
- if (!(b & 0x10)) { // xxx0.... (C.28.2)
- return b & 0x0f;
- }
- else if ((b & 0x1c) == 0x10) { // xxx100.. ........ (C.28.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x03) << 8) | *dataP++) + 0x10;
- }
- }
- else if ((b & 0x1c) == 0x14) { // xxx101.. ........ ........ (C.28.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x03) << 16) | (dataP[0] << 8) | dataP[1]) + 0x410;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x1f) == 0x18) { // xxx11000 0000.... ........ ........ (C.28.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x40410;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseSequenceLen() { // C.21
- if (dataEnd - dataP > 0) {
- uint8_t b = *dataP++;
- if (b < 0x80) { // 0....... (C.21.2)
- return b;
- }
- else if ((b & 0xf0) == 0x80) { // 1000.... ........ ........ (C.21.3)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x80;
- dataP += 2;
- return result;
- }
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::string parseNonEmptyOctetString2() { // C.22
- // Parse the length of the string
- uint8_t b = *dataP++ & 0x7f;
- size_t len;
- if (!(b & 0x40)) { // x0...... (C.22.3.1)
- len = b + 1;
- }
- else if (b == 0x40) { // x1000000 ........ (C.22.3.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = *dataP++ + 0x41;
- }
- else if (b == 0x60) { // x1100000 ........ ........ ........ ........ (C.22.3.3)
- if (dataEnd - dataP < 4) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x141;
- dataP += 4;
- }
- else {
- throw DeadlyImportError(parseErrorMessage);
- }
-
- // Parse the string (C.22.4)
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string s = parseUTF8String(dataP, len);
- dataP += len;
-
- return s;
- }
-
- size_t parseNonEmptyOctetString5Length() { // C.23
- // Parse the length of the string
- size_t b = *dataP++ & 0x0f;
- if (!(b & 0x08)) { // xxxx0... (C.23.3.1)
- return b + 1;
- }
- else if (b == 0x08) { // xxxx1000 ........ (C.23.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x09;
- }
- }
- else if (b == 0x0c) { // xxxx1100 ........ ........ ........ ........ (C.23.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x109;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseNonEmptyOctetString7Length() { // C.24
- // Parse the length of the string
- size_t b = *dataP++ & 0x03;
- if (!(b & 0x02)) { // xxxxxx0. (C.24.3.1)
- return b + 1;
- }
- else if (b == 0x02) { // xxxxxx10 ........ (C.24.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x3;
- }
- }
- else if (b == 0x03) { // xxxxxx11 ........ ........ ........ ........ (C.24.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x103;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::shared_ptr<const FIValue> parseEncodedData(size_t index, size_t len) {
- if (index < 32) {
- FIDecoder *decoder = defaultDecoder[index];
- if (!decoder) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- return decoder->decode(dataP, len);
- }
- else {
- if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
- auto it = decoderMap.find(uri);
- if (it == decoderMap.end()) {
- throw DeadlyImportError("Unsupported encoding algorithm " + uri);
- }
- else {
- return it->second->decode(dataP, len);
- }
- }
- }
-
- std::shared_ptr<const FIValue> parseRestrictedAlphabet(size_t index, size_t len) {
- std::string alphabet;
- if (index < 16) {
- switch (index) {
- case 0: // numeric
- alphabet = "0123456789-+.e ";
- break;
- case 1: // date and time
- alphabet = "0123456789-:TZ ";
- break;
- default:
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- }
- else {
- if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- alphabet = vocabulary.restrictedAlphabetTable[index - 16];
- }
- std::vector<uint32_t> alphabetUTF32;
- utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
- std::string::size_type alphabetLength = alphabetUTF32.size();
- if (alphabetLength < 2) {
- throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
- }
- std::string::size_type bitsPerCharacter = 1;
- while ((1ull << bitsPerCharacter) <= alphabetLength) {
- ++bitsPerCharacter;
- }
- size_t bitsAvail = 0;
- uint8_t mask = (1 << bitsPerCharacter) - 1;
- uint32_t bits = 0;
- std::string s;
- for (size_t i = 0; i < len; ++i) {
- bits = (bits << 8) | dataP[i];
- bitsAvail += 8;
- while (bitsAvail >= bitsPerCharacter) {
- bitsAvail -= bitsPerCharacter;
- size_t charIndex = (bits >> bitsAvail) & mask;
- if (charIndex < alphabetLength) {
- s.push_back(alphabetUTF32[charIndex]);
- }
- else if (charIndex != mask) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
- }
- return FIStringValue::create(std::move(s));
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString3() { // C.19
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x20) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x0f) << 4) | ((*dataP & 0xf0) >> 4); // C.29
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // encoding algorithm (C.19.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.19.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // UTF-16 (C.19.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.19.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString5() { // C.20
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x08) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x03) << 6) | ((*dataP & 0xfc) >> 2); /* C.29 */
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // encoding algorithm (C.20.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.20.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // UTF-16 (C.20.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.20.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- const std::string &parseIdentifyingStringOrIndex(std::vector<std::string> &stringTable) { // C.13
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP;
- if (b & 0x80) {
- // We have an index (C.13.4)
- size_t index = parseInt2();
- if (index >= stringTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return stringTable[index];
- }
- else {
- // We have a string (C.13.3)
- stringTable.push_back(parseNonEmptyOctetString2());
- return stringTable.back();
- }
- }
-
- QName parseNameSurrogate() { // C.16
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0xfc) { // Padding '000000' C.2.5.5
- throw DeadlyImportError(parseErrorMessage);
- }
- QName result;
- size_t index;
- if (b & 0x02) { // prefix (C.16.3)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.prefixTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.prefix = vocabulary.prefixTable[index];
- }
- if (b & 0x01) { // namespace-name (C.16.4)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.namespaceNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.uri = vocabulary.namespaceNameTable[index];
- }
- // local-name
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.localNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.name = vocabulary.localNameTable[index];
- return result;
- }
-
- const QName &parseQualifiedNameOrIndex2(std::vector<QName> &qNameTable) { // C.17
- uint8_t b = *dataP;
- if ((b & 0x7c) == 0x78) { // x11110..
- // We have a literal (C.17.3)
- ++dataP;
- QName result;
- // prefix (C.17.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.17.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.17.4)
- size_t index = parseInt2();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- const QName &parseQualifiedNameOrIndex3(std::vector<QName> &qNameTable) { // C.18
- uint8_t b = *dataP;
- if ((b & 0x3c) == 0x3c) { // xx1111..
- // We have a literal (C.18.3)
- ++dataP;
- QName result;
- // prefix (C.18.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.18.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.18.4)
- size_t index = parseInt3();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex1(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.14
- uint8_t b = *dataP;
- if (b == 0xff) { // C.26.2
- // empty string
- ++dataP;
- return EmptyFIString;
- }
- else if (b & 0x80) { // C.14.4
- // We have an index
- size_t index = parseInt2();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.14.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString3();
- if (b & 0x40) { // C.14.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex3(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.15
- uint8_t b = *dataP;
- if (b & 0x20) { // C.15.4
- // We have an index
- size_t index = parseInt4();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.15.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString5();
- if (b & 0x10) { // C.15.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- void parseElement() {
- // C.3
-
- attributes.clear();
-
- uint8_t b = *dataP;
- bool hasAttributes = (b & 0x40) != 0; // C.3.3
- if ((b & 0x3f) == 0x38) { // C.3.4.1
- // Parse namespaces
- ++dataP;
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP++;
- if (b == 0xf0) { // C.3.4.3
- break;
- }
- if ((b & 0xfc) != 0xcc) { // C.3.4.2
- throw DeadlyImportError(parseErrorMessage);
- }
- // C.12
- Attribute attr;
- attr.qname.prefix = "xmlns";
- attr.qname.name = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- attr.qname.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- attr.name = attr.qname.name.empty() ? "xmlns" : "xmlns:" + attr.qname.name;
- attr.value = FIStringValue::create(std::string(attr.qname.uri));
- attributes.push_back(attr);
- }
- if ((dataEnd - dataP < 1) || (*dataP & 0xc0)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
-
- // Parse Element name (C.3.5)
- const QName &elemName = parseQualifiedNameOrIndex3(vocabulary.elementNameTable);
- nodeName = elemName.prefix.empty() ? elemName.name : elemName.prefix + ':' + elemName.name;
-
- if (hasAttributes) {
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- if (b < 0x80) { // C.3.6.1
- // C.4
- Attribute attr;
- attr.qname = parseQualifiedNameOrIndex2(vocabulary.attributeNameTable);
- attr.name = attr.qname.prefix.empty() ? attr.qname.name : attr.qname.prefix + ':' + attr.qname.name;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- attr.value = parseNonIdentifyingStringOrIndex1(vocabulary.attributeValueTable);
- attributes.push_back(attr);
- }
- else {
- if ((b & 0xf0) != 0xf0) { // C.3.6.2
- throw DeadlyImportError(parseErrorMessage);
- }
- emptyElement = b == 0xff; // C.3.6.2, C.3.8
- ++dataP;
- break;
- }
- }
- }
- else {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- switch (b) {
- case 0xff:
- terminatorPending = true;
- // Intentionally fall through
- case 0xf0:
- emptyElement = true;
- ++dataP;
- break;
- default:
- emptyElement = false;
- }
- }
- if (!emptyElement) {
- elementStack.push(nodeName);
- }
-
- currentNodeType = irr::io::EXN_ELEMENT;
- }
-
- void parseHeader() {
- // Parse header (C.1.3)
- size_t magicSize = parseMagic(dataP, dataEnd);
- if (!magicSize) {
- throw DeadlyImportError(parseErrorMessage);
- }
- dataP += magicSize;
- // C.2.3
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0x40) {
- // Parse additional data (C.2.4)
- size_t len = parseSequenceLen();
- for (size_t i = 0; i < len; ++i) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string id =*/ parseNonEmptyOctetString2();
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string data =*/ parseNonEmptyOctetString2();
- }
- }
- if (b & 0x20) {
- // Parse initial vocabulary (C.2.5)
- if (dataEnd - dataP < 2) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint16_t b1 = (dataP[0] << 8) | dataP[1];
- dataP += 2;
- if (b1 & 0x1000) {
- // External vocabulary (C.2.5.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string uri = parseNonEmptyOctetString2();
- auto it = vocabularyMap.find(uri);
- if (it == vocabularyMap.end()) {
- throw DeadlyImportError("Unknown vocabulary " + uri);
- }
- const FIVocabulary *externalVocabulary = it->second;
- if (externalVocabulary->restrictedAlphabetTable) {
- std::copy(externalVocabulary->restrictedAlphabetTable, externalVocabulary->restrictedAlphabetTable + externalVocabulary->restrictedAlphabetTableSize, std::back_inserter(vocabulary.restrictedAlphabetTable));
- }
- if (externalVocabulary->encodingAlgorithmTable) {
- std::copy(externalVocabulary->encodingAlgorithmTable, externalVocabulary->encodingAlgorithmTable + externalVocabulary->encodingAlgorithmTableSize, std::back_inserter(vocabulary.encodingAlgorithmTable));
- }
- if (externalVocabulary->prefixTable) {
- std::copy(externalVocabulary->prefixTable, externalVocabulary->prefixTable + externalVocabulary->prefixTableSize, std::back_inserter(vocabulary.prefixTable));
- }
- if (externalVocabulary->namespaceNameTable) {
- std::copy(externalVocabulary->namespaceNameTable, externalVocabulary->namespaceNameTable + externalVocabulary->namespaceNameTableSize, std::back_inserter(vocabulary.namespaceNameTable));
- }
- if (externalVocabulary->localNameTable) {
- std::copy(externalVocabulary->localNameTable, externalVocabulary->localNameTable + externalVocabulary->localNameTableSize, std::back_inserter(vocabulary.localNameTable));
- }
- if (externalVocabulary->otherNCNameTable) {
- std::copy(externalVocabulary->otherNCNameTable, externalVocabulary->otherNCNameTable + externalVocabulary->otherNCNameTableSize, std::back_inserter(vocabulary.otherNCNameTable));
- }
- if (externalVocabulary->otherURITable) {
- std::copy(externalVocabulary->otherURITable, externalVocabulary->otherURITable + externalVocabulary->otherURITableSize, std::back_inserter(vocabulary.otherURITable));
- }
- if (externalVocabulary->attributeValueTable) {
- std::copy(externalVocabulary->attributeValueTable, externalVocabulary->attributeValueTable + externalVocabulary->attributeValueTableSize, std::back_inserter(vocabulary.attributeValueTable));
- }
- if (externalVocabulary->charactersTable) {
- std::copy(externalVocabulary->charactersTable, externalVocabulary->charactersTable + externalVocabulary->charactersTableSize, std::back_inserter(vocabulary.charactersTable));
- }
- if (externalVocabulary->otherStringTable) {
- std::copy(externalVocabulary->otherStringTable, externalVocabulary->otherStringTable + externalVocabulary->otherStringTableSize, std::back_inserter(vocabulary.otherStringTable));
- }
- if (externalVocabulary->elementNameTable) {
- std::copy(externalVocabulary->elementNameTable, externalVocabulary->elementNameTable + externalVocabulary->elementNameTableSize, std::back_inserter(vocabulary.elementNameTable));
- }
- if (externalVocabulary->attributeNameTable) {
- std::copy(externalVocabulary->attributeNameTable, externalVocabulary->attributeNameTable + externalVocabulary->attributeNameTableSize, std::back_inserter(vocabulary.attributeNameTable));
- }
- }
- if (b1 & 0x0800) {
- // Parse restricted alphabets (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.restrictedAlphabetTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0400) {
- // Parse encoding algorithms (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.encodingAlgorithmTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0200) {
- // Parse prefixes (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.prefixTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0100) {
- // Parse namespace names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.namespaceNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0080) {
- // Parse local names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.localNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0040) {
- // Parse other ncnames (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherNCNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0020) {
- // Parse other uris (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherURITable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0010) {
- // Parse attribute values (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.attributeValueTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0008) {
- // Parse content character chunks (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.charactersTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0004) {
- // Parse other strings (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherStringTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0002) {
- // Parse element name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.elementNameTable.push_back(parseNameSurrogate());
- }
- }
- if (b1 & 0x0001) {
- // Parse attribute name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.attributeNameTable.push_back(parseNameSurrogate());
- }
- }
- }
- if (b & 0x10) {
- // Parse notations (C.2.6)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfc) != 0xc0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.11 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b1 & 0x02) {
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- }
- }
- if (b & 0x08) {
- // Parse unparsed entities (C.2.7)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfe) != 0xd0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.10 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- /*const std::string &notationName =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- }
- }
- if (b & 0x04) {
- // Parse character encoding scheme (C.2.8)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string characterEncodingScheme =*/ parseNonEmptyOctetString2();
- }
- if (b & 0x02) {
- // Parse standalone flag (C.2.9)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 & 0xfe) {
- throw DeadlyImportError(parseErrorMessage);
- }
- //bool standalone = b1 & 0x01;
- }
- if (b & 0x01) {
- // Parse version (C.2.10)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> version =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- }
- }
-
- std::unique_ptr<uint8_t[]> data;
- uint8_t *dataP, *dataEnd;
- irr::io::EXML_NODE currentNodeType;
- bool emptyElement;
- bool headerPending;
- bool terminatorPending;
- Vocabulary vocabulary;
- std::vector<Attribute> attributes;
- std::stack<std::string> elementStack;
- std::string nodeName;
- std::map<std::string, std::unique_ptr<FIDecoder>> decoderMap;
- std::map<std::string, const FIVocabulary*> vocabularyMap;
-
- static const std::string EmptyString;
- static std::shared_ptr<const FIValue> EmptyFIString;
-
- static FIHexDecoder hexDecoder;
- static FIBase64Decoder base64Decoder;
- static FIShortDecoder shortDecoder;
- static FIIntDecoder intDecoder;
- static FILongDecoder longDecoder;
- static FIBoolDecoder boolDecoder;
- static FIFloatDecoder floatDecoder;
- static FIDoubleDecoder doubleDecoder;
- static FIUUIDDecoder uuidDecoder;
- static FICDATADecoder cdataDecoder;
- static FIDecoder *defaultDecoder[32];
-};
-
-const std::string CFIReaderImpl::EmptyString;
-std::shared_ptr<const FIValue> CFIReaderImpl::EmptyFIString = FIStringValue::create(std::string());
-
-FIHexDecoder CFIReaderImpl::hexDecoder;
-FIBase64Decoder CFIReaderImpl::base64Decoder;
-FIShortDecoder CFIReaderImpl::shortDecoder;
-FIIntDecoder CFIReaderImpl::intDecoder;
-FILongDecoder CFIReaderImpl::longDecoder;
-FIBoolDecoder CFIReaderImpl::boolDecoder;
-FIFloatDecoder CFIReaderImpl::floatDecoder;
-FIDoubleDecoder CFIReaderImpl::doubleDecoder;
-FIUUIDDecoder CFIReaderImpl::uuidDecoder;
-FICDATADecoder CFIReaderImpl::cdataDecoder;
-
-FIDecoder *CFIReaderImpl::defaultDecoder[32] = {
- &hexDecoder,
- &base64Decoder,
- &shortDecoder,
- &intDecoder,
- &longDecoder,
- &boolDecoder,
- &floatDecoder,
- &doubleDecoder,
- &uuidDecoder,
- &cdataDecoder
-};
-
-class CXMLReaderImpl : public FIReader
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader_)
- : reader(std::move(reader_))
- {}
-
- virtual ~CXMLReaderImpl() {}
-
- virtual bool read() /*override*/ {
- return reader->read();
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return reader->getNodeType();
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return reader->getAttributeCount();
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- return reader->getAttributeName(idx);
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- return reader->getAttributeValue(idx);
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- return reader->getAttributeValue(name);
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- return reader->getAttributeValueSafe(name);
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- return reader->getAttributeValueAsInt(name);
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- return reader->getAttributeValueAsInt(idx);
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- return reader->getAttributeValueAsFloat(name);
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- return reader->getAttributeValueAsFloat(idx);
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return reader->getNodeName();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return reader->getNodeData();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return reader->isEmptyElement();
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return reader->getSourceFormat();
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return reader->getParserFormat();
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
- return nullptr;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
- return nullptr;
- }
-
- virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
-
-
- virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}
-
-private:
-
- std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader;
-};
-
-static std::unique_ptr<uint8_t[]> readFile(IOStream *stream, size_t &size, bool &isFI) {
- size = stream->FileSize();
- std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
- if (stream->Read(data.get(), size, 1) != 1) {
- size = 0;
- data.reset();
- }
- isFI = parseMagic(data.get(), data.get() + size) > 0;
- return data;
-}
-
-std::unique_ptr<FIReader> FIReader::create(IOStream *stream)
-{
- size_t size;
- bool isFI;
- auto data = readFile(stream, size, isFI);
- if (isFI) {
- return std::unique_ptr<FIReader>(new CFIReaderImpl(std::move(data), size));
- }
- else {
- auto memios = std::unique_ptr<MemoryIOStream>(new MemoryIOStream(data.release(), size, true));
- auto callback = std::unique_ptr<CIrrXML_IOStreamReader>(new CIrrXML_IOStreamReader(memios.get()));
- return std::unique_ptr<FIReader>(new CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>>(createIrrXMLReader(callback.get()))));
- }
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/thirdparty/assimp/code/MMDCpp14.h b/thirdparty/assimp/code/MMD/MMDCpp14.h
index 638b0bfd2f..638b0bfd2f 100644
--- a/thirdparty/assimp/code/MMDCpp14.h
+++ b/thirdparty/assimp/code/MMD/MMDCpp14.h
diff --git a/thirdparty/assimp/code/MMDImporter.cpp b/thirdparty/assimp/code/MMD/MMDImporter.cpp
index 84b9e35a6b..e7744e4cd0 100644
--- a/thirdparty/assimp/code/MMDImporter.cpp
+++ b/thirdparty/assimp/code/MMD/MMDImporter.cpp
@@ -41,15 +41,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-#include "MMDImporter.h"
-#include "MMDPmdParser.h"
-#include "MMDPmxParser.h"
-#include "MMDVmdParser.h"
-#include "ConvertToLHProcess.h"
+#include "MMD/MMDImporter.h"
+#include "MMD/MMDPmdParser.h"
+#include "MMD/MMDPmxParser.h"
+#include "MMD/MMDVmdParser.h"
+#include "PostProcessing/ConvertToLHProcess.h"
+
#include <assimp/DefaultIOSystem.h>
#include <assimp/Importer.hpp>
#include <assimp/ai_assert.h>
#include <assimp/scene.h>
+
#include <fstream>
#include <iomanip>
#include <memory>
diff --git a/thirdparty/assimp/code/MMDImporter.h b/thirdparty/assimp/code/MMD/MMDImporter.h
index 4ee94eeb00..4ee94eeb00 100644
--- a/thirdparty/assimp/code/MMDImporter.h
+++ b/thirdparty/assimp/code/MMD/MMDImporter.h
diff --git a/thirdparty/assimp/code/MMDPmdParser.h b/thirdparty/assimp/code/MMD/MMDPmdParser.h
index d2f2224aa1..d2f2224aa1 100644
--- a/thirdparty/assimp/code/MMDPmdParser.h
+++ b/thirdparty/assimp/code/MMD/MMDPmdParser.h
diff --git a/thirdparty/assimp/code/MMDPmxParser.cpp b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
index 7425ceac22..80f0986dd7 100644
--- a/thirdparty/assimp/code/MMDPmxParser.cpp
+++ b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
@@ -42,7 +42,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <utility>
#include "MMDPmxParser.h"
#include <assimp/StringUtils.h>
-#include "../contrib/utf8cpp/source/utf8.h"
+#ifdef ASSIMP_USE_HUNTER
+# include <utf8/utf8.h>
+#else
+# include "../contrib/utf8cpp/source/utf8.h"
+#endif
#include <assimp/Exceptional.h>
namespace pmx
diff --git a/thirdparty/assimp/code/MMDPmxParser.h b/thirdparty/assimp/code/MMD/MMDPmxParser.h
index cf523a1298..cf523a1298 100644
--- a/thirdparty/assimp/code/MMDPmxParser.h
+++ b/thirdparty/assimp/code/MMD/MMDPmxParser.h
diff --git a/thirdparty/assimp/code/MMDVmdParser.h b/thirdparty/assimp/code/MMD/MMDVmdParser.h
index 947c3a2422..947c3a2422 100644
--- a/thirdparty/assimp/code/MMDVmdParser.h
+++ b/thirdparty/assimp/code/MMD/MMDVmdParser.h
diff --git a/thirdparty/assimp/code/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp
index 03d5a18a34..d0b39093b6 100644
--- a/thirdparty/assimp/code/MaterialSystem.cpp
+++ b/thirdparty/assimp/code/Material/MaterialSystem.cpp
@@ -96,12 +96,12 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
ai_real* pOut,
unsigned int* pMax)
{
- ai_assert( pOut != NULL );
- ai_assert( pMat != NULL );
+ ai_assert( pOut != nullptr );
+ ai_assert( pMat != nullptr );
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
- if (!prop) {
+ if ( nullptr == prop) {
return AI_FAILURE;
}
@@ -112,9 +112,11 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
}
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
+
+ for (unsigned int a = 0; a < iWrite; ++a) {
+ pOut[ a ] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
}
+
if (pMax) {
*pMax = iWrite;
}
diff --git a/thirdparty/assimp/code/MaterialSystem.h b/thirdparty/assimp/code/Material/MaterialSystem.h
index 67d53578cb..67d53578cb 100644
--- a/thirdparty/assimp/code/MaterialSystem.h
+++ b/thirdparty/assimp/code/Material/MaterialSystem.h
diff --git a/thirdparty/assimp/code/CalcTangentsProcess.cpp b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
index b30f39c274..a3f7dd2557 100644
--- a/thirdparty/assimp/code/CalcTangentsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
@@ -212,7 +212,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// project tangent and bitangent into the plane formed by the vertex' normal
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
- localTangent.Normalize(); localBitangent.Normalize();
+ localTangent.NormalizeSafe(); localBitangent.NormalizeSafe();
// reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
@@ -220,10 +220,10 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
if (invalid_tangent != invalid_bitangent) {
if (invalid_tangent) {
localTangent = meshNorm[p] ^ localBitangent;
- localTangent.Normalize();
+ localTangent.NormalizeSafe();
} else {
localBitangent = localTangent ^ meshNorm[p];
- localBitangent.Normalize();
+ localBitangent.NormalizeSafe();
}
}
diff --git a/thirdparty/assimp/code/CalcTangentsProcess.h b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h
index 18775abcc7..3568a624f8 100644
--- a/thirdparty/assimp/code/CalcTangentsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h
@@ -42,11 +42,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines a post processing step to calculate tangents and
- bitangents on all imported meshes.*/
+ bi-tangents on all imported meshes.*/
#ifndef AI_CALCTANGENTSPROCESS_H_INC
#define AI_CALCTANGENTSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
diff --git a/thirdparty/assimp/code/ComputeUVMappingProcess.cpp b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
index bb571a551b..bb571a551b 100644
--- a/thirdparty/assimp/code/ComputeUVMappingProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
diff --git a/thirdparty/assimp/code/ComputeUVMappingProcess.h b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h
index 24f6bb7218..a6d36e06ea 100644
--- a/thirdparty/assimp/code/ComputeUVMappingProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COMPUTEUVMAPPING_H_INC
#define AI_COMPUTEUVMAPPING_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
#include <assimp/material.h>
#include <assimp/types.h>
diff --git a/thirdparty/assimp/code/ConvertToLHProcess.cpp b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp
index b7cd4f0bc6..b7cd4f0bc6 100644
--- a/thirdparty/assimp/code/ConvertToLHProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp
diff --git a/thirdparty/assimp/code/ConvertToLHProcess.h b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h
index 63351568d0..f32b91fc39 100644
--- a/thirdparty/assimp/code/ConvertToLHProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h
@@ -52,7 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONVERTTOLHPROCESS_H_INC
#include <assimp/types.h>
-#include "BaseProcess.h"
+
+#include "Common/BaseProcess.h"
struct aiMesh;
struct aiNodeAnim;
diff --git a/thirdparty/assimp/code/DeboneProcess.cpp b/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp
index 83b8336bc9..83b8336bc9 100644
--- a/thirdparty/assimp/code/DeboneProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp
diff --git a/thirdparty/assimp/code/DeboneProcess.h b/thirdparty/assimp/code/PostProcessing/DeboneProcess.h
index ba77aba70e..8b64c2acc6 100644
--- a/thirdparty/assimp/code/DeboneProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/DeboneProcess.h
@@ -44,17 +44,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DEBONEPROCESS_H_INC
#define AI_DEBONEPROCESS_H_INC
-#include <vector>
-#include <utility>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
#include <assimp/scene.h>
+#include <vector>
+#include <utility>
+
+#// Forward declarations
class DeboneTest;
-namespace Assimp
-{
+namespace Assimp {
#if (!defined AI_DEBONE_THRESHOLD)
# define AI_DEBONE_THRESHOLD 1.0f
@@ -66,14 +67,11 @@ namespace Assimp
* the bone are split from the mesh. The split off (new) mesh is boneless. At any
* point in time, bones without affect upon a given mesh are to be removed.
*/
-class DeboneProcess : public BaseProcess
-{
+class DeboneProcess : public BaseProcess {
public:
-
DeboneProcess();
~DeboneProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -91,7 +89,6 @@ public:
void SetupProperties(const Importer* pImp);
protected:
-
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
diff --git a/thirdparty/assimp/code/DropFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp
index b11615bb82..b11615bb82 100644
--- a/thirdparty/assimp/code/DropFaceNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/DropFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h
index 0d116663b7..c710c5a5ee 100644
--- a/thirdparty/assimp/code/DropFaceNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h
@@ -44,23 +44,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DROPFACENORMALPROCESS_H_INC
#define AI_DROPFACENORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
-namespace Assimp
-{
+namespace Assimp {
// ---------------------------------------------------------------------------
/** The DropFaceNormalsProcess computes face normals for all faces of all meshes
*/
-class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess
-{
+class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
public:
-
DropFaceNormalsProcess();
~DropFaceNormalsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
diff --git a/thirdparty/assimp/code/EmbedTexturesProcess.cpp b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp
index 739382a057..739382a057 100644
--- a/thirdparty/assimp/code/EmbedTexturesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp
diff --git a/thirdparty/assimp/code/EmbedTexturesProcess.h b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h
index cdf40bef74..3c4b2eab4e 100644
--- a/thirdparty/assimp/code/EmbedTexturesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h
@@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <string>
diff --git a/thirdparty/assimp/code/FindDegenerates.cpp b/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp
index 365f5d7447..50fac46dba 100644
--- a/thirdparty/assimp/code/FindDegenerates.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp
@@ -228,6 +228,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
if ( area < 1e-6 ) {
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;
+ ++deg;
goto evil_jump_outside;
}
diff --git a/thirdparty/assimp/code/FindDegenerates.h b/thirdparty/assimp/code/PostProcessing/FindDegenerates.h
index 880f5f16a2..7a15e77cf1 100644
--- a/thirdparty/assimp/code/FindDegenerates.h
+++ b/thirdparty/assimp/code/PostProcessing/FindDegenerates.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDDEGENERATESPROCESS_H_INC
#define AI_FINDDEGENERATESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
class FindDegeneratesProcessTest;
diff --git a/thirdparty/assimp/code/FindInstancesProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp
index be1138116e..64907458a1 100644
--- a/thirdparty/assimp/code/FindInstancesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp
@@ -137,6 +137,11 @@ void FindInstancesProcess::Execute( aiScene* pScene)
aiMesh* inst = pScene->mMeshes[i];
hashes[i] = GetMeshHash(inst);
+ // Find an appropriate epsilon
+ // to compare position differences against
+ float epsilon = ComputePositionEpsilon(inst);
+ epsilon *= epsilon;
+
for (int a = i-1; a >= 0; --a) {
if (hashes[i] == hashes[a])
{
@@ -154,12 +159,7 @@ void FindInstancesProcess::Execute( aiScene* pScene)
orig->mPrimitiveTypes != inst->mPrimitiveTypes)
continue;
- // up to now the meshes are equal. find an appropriate
- // epsilon to compare position differences against
- float epsilon = ComputePositionEpsilon(inst);
- epsilon *= epsilon;
-
- // now compare vertex positions, normals,
+ // up to now the meshes are equal. Now compare vertex positions, normals,
// tangents and bitangents using this epsilon.
if (orig->HasPositions()) {
if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
diff --git a/thirdparty/assimp/code/FindInstancesProcess.h b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h
index ab4a371c71..64b838d7cc 100644
--- a/thirdparty/assimp/code/FindInstancesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h
@@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDINSTANCES_H_INC
#define AI_FINDINSTANCES_H_INC
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
+#include "Common/BaseProcess.h"
+#include "PostProcessing/ProcessHelper.h"
class FindInstancesProcessTest;
namespace Assimp {
diff --git a/thirdparty/assimp/code/FindInvalidDataProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
index 433f042448..433f042448 100644
--- a/thirdparty/assimp/code/FindInvalidDataProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
diff --git a/thirdparty/assimp/code/FindInvalidDataProcess.h b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h
index 8504fb7b1f..ce7375f34f 100644
--- a/thirdparty/assimp/code/FindInvalidDataProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h
@@ -46,7 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDINVALIDDATA_H_INC
#define AI_FINDINVALIDDATA_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
#include <assimp/anim.h>
diff --git a/thirdparty/assimp/code/FixNormalsStep.cpp b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp
index bbbe6899b4..bbbe6899b4 100644
--- a/thirdparty/assimp/code/FixNormalsStep.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp
diff --git a/thirdparty/assimp/code/FixNormalsStep.h b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h
index 6be27faef6..f60ce596a4 100644
--- a/thirdparty/assimp/code/FixNormalsStep.h
+++ b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FIXNORMALSPROCESS_H_INC
#define AI_FIXNORMALSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp
new file mode 100644
index 0000000000..c013454fc3
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp
@@ -0,0 +1,115 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of the assimp team.
+
+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.
+---------------------------------------------------------------------------
+*/
+
+#ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#include "PostProcessing/GenBoundingBoxesProcess.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+
+namespace Assimp {
+
+GenBoundingBoxesProcess::GenBoundingBoxesProcess()
+: BaseProcess() {
+
+}
+
+GenBoundingBoxesProcess::~GenBoundingBoxesProcess() {
+ // empty
+}
+
+bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
+ return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
+}
+
+void checkMesh(aiMesh* mesh, aiVector3D& min, aiVector3D& max) {
+ ai_assert(nullptr != mesh);
+
+ if (0 == mesh->mNumVertices) {
+ return;
+ }
+
+ for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
+ const aiVector3D &pos = mesh->mVertices[i];
+ if (pos.x < min.x) {
+ min.x = pos.x;
+ }
+ if (pos.y < min.y) {
+ min.y = pos.y;
+ }
+ if (pos.z < min.z) {
+ min.z = pos.z;
+ }
+
+ if (pos.x > max.x) {
+ max.x = pos.x;
+ }
+ if (pos.y > max.y) {
+ max.y = pos.y;
+ }
+ if (pos.z > max.z) {
+ max.z = pos.z;
+ }
+ }
+}
+
+void GenBoundingBoxesProcess::Execute(aiScene* pScene) {
+ if (nullptr == pScene) {
+ return;
+ }
+
+ for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
+ aiMesh* mesh = pScene->mMeshes[i];
+ if (nullptr == mesh) {
+ continue;
+ }
+
+ aiVector3D min(999999, 999999, 999999), max(-999999, -999999, -999999);
+ checkMesh(mesh, min, max);
+ mesh->mAABB.mMin = min;
+ mesh->mAABB.mMax = max;
+ }
+}
+
+} // Namespace Assimp
+
+#endif // ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
new file mode 100644
index 0000000000..4b43c82a42
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
@@ -0,0 +1,76 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of the assimp team.
+
+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.
+---------------------------------------------------------------------------
+*/
+
+/** @file Defines a post-processing step to generate Axis-aligned bounding
+ * volumes for all meshes.
+ */
+
+#pragma once
+
+#ifndef AI_GENBOUNDINGBOXESPROCESS_H_INC
+#define AI_GENBOUNDINGBOXESPROCESS_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#include "Common/BaseProcess.h"
+
+namespace Assimp {
+
+/** Post-processing process to find axis-aligned bounding volumes for amm meshes
+ * used in a scene
+ */
+class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
+public:
+ /// The class constructor.
+ GenBoundingBoxesProcess();
+ /// The class destructor.
+ ~GenBoundingBoxesProcess();
+ /// Will return true, if aiProcess_GenBoundingBoxes is defined.
+ bool IsActive(unsigned int pFlags) const override;
+ /// The execution callback.
+ void Execute(aiScene* pScene) override;
+};
+
+} // Namespace Assimp
+
+#endif // #ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#endif // AI_GENBOUNDINGBOXESPROCESS_H_INC
diff --git a/thirdparty/assimp/code/GenFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp
index 028334dec7..028334dec7 100644
--- a/thirdparty/assimp/code/GenFaceNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/GenFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h
index c80ec9fddc..c641fd6353 100644
--- a/thirdparty/assimp/code/GenFaceNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GENFACENORMALPROCESS_H_INC
#define AI_GENFACENORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
namespace Assimp
diff --git a/thirdparty/assimp/code/GenVertexNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp
index 3f6c2f86bd..3f6c2f86bd 100644
--- a/thirdparty/assimp/code/GenVertexNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/GenVertexNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h
index 9142ad26f5..2ceee17e85 100644
--- a/thirdparty/assimp/code/GenVertexNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h
@@ -45,24 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GENVERTEXNORMALPROCESS_H_INC
#define AI_GENVERTEXNORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/assbin_chunks.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
+// Forward declarations
class GenNormalsTest;
namespace Assimp {
// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes vertex normals for all vertizes
+/** The GenFaceNormalsProcess computes vertex normals for all vertices
*/
-class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
-{
+class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
public:
-
GenVertexNormalsProcess();
~GenVertexNormalsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -88,13 +88,10 @@ public:
// setter for configMaxAngle
- inline void SetMaxSmoothAngle(ai_real f)
- {
+ inline void SetMaxSmoothAngle(ai_real f) {
configMaxAngle =f;
}
-public:
-
// -------------------------------------------------------------------
/** Computes normals for a specific mesh
* @param pcMesh Mesh
@@ -104,7 +101,6 @@ public:
bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
private:
-
/** Configuration option: maximum smoothing angle, in radians*/
ai_real configMaxAngle;
mutable bool force_ = false;
diff --git a/thirdparty/assimp/code/ImproveCacheLocality.cpp b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp
index ace9d95ff8..d0a016fa42 100644
--- a/thirdparty/assimp/code/ImproveCacheLocality.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp
@@ -45,14 +45,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* <br>
* The algorithm is roughly basing on this paper:
* http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf
- * .. although overdraw rduction isn't implemented yet ...
+ * .. although overdraw reduction isn't implemented yet ...
*/
-
-
// internal headers
-#include "ImproveCacheLocality.h"
-#include "VertexTriangleAdjacency.h"
+#include "PostProcessing/ImproveCacheLocality.h"
+#include "Common/VertexTriangleAdjacency.h"
+
#include <assimp/StringUtils.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
@@ -64,36 +63,33 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
-ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() {
- configCacheDepth = PP_ICL_PTCACHE_SIZE;
+ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
+: mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
-ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess()
-{
+ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
-bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const
-{
+bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_ImproveCacheLocality) != 0;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration
-void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
-{
+void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp) {
// AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
- configCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
+ mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
-void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
-{
+void ImproveCacheLocalityProcess::Execute( aiScene* pScene) {
if (!pScene->mNumMeshes) {
ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
return;
@@ -103,7 +99,7 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
float out = 0.f;
unsigned int numf = 0, numm = 0;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++){
+ for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ){
const float res = ProcessMesh( pScene->mMeshes[a],a);
if (res) {
numf += pScene->mMeshes[a]->mNumFaces;
@@ -121,44 +117,41 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// Improves the cache coherency of a specific mesh
-float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum)
-{
+ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum) {
// TODO: rewrite this to use std::vector or boost::shared_array
- ai_assert(NULL != pMesh);
+ ai_assert(nullptr != pMesh);
// Check whether the input data is valid
// - there must be vertices and faces
// - all faces must be triangulated or we can't operate on them
if (!pMesh->HasFaces() || !pMesh->HasPositions())
- return 0.f;
+ return static_cast<ai_real>(0.f);
if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
ASSIMP_LOG_ERROR("This algorithm works on triangle meshes only");
- return 0.f;
+ return static_cast<ai_real>(0.f);
}
- if(pMesh->mNumVertices <= configCacheDepth) {
- return 0.f;
+ if(pMesh->mNumVertices <= mConfigCacheDepth) {
+ return static_cast<ai_real>(0.f);
}
- float fACMR = 3.f;
+ ai_real fACMR = 3.f;
const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
// Input ACMR is for logging purposes only
if (!DefaultLogger::isNullLogger()) {
- unsigned int* piFIFOStack = new unsigned int[configCacheDepth];
- memset(piFIFOStack,0xff,configCacheDepth*sizeof(unsigned int));
+ unsigned int* piFIFOStack = new unsigned int[mConfigCacheDepth];
+ memset(piFIFOStack,0xff,mConfigCacheDepth*sizeof(unsigned int));
unsigned int* piCur = piFIFOStack;
- const unsigned int* const piCurEnd = piFIFOStack + configCacheDepth;
+ const unsigned int* const piCurEnd = piFIFOStack + mConfigCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) {
-
for (unsigned int qq = 0; qq < 3;++qq) {
bool bInCache = false;
-
for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
@@ -176,7 +169,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
}
}
delete[] piFIFOStack;
- fACMR = (float)iCacheMisses / pMesh->mNumFaces;
+ fACMR = (ai_real) iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
@@ -185,7 +178,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// smaller than 3.0 ...
ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
ASSIMP_LOG_WARN(szBuff);
- return 0.f;
+ return static_cast<ai_real>(0.f);
}
}
@@ -258,7 +251,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
int ivdx = 0;
int ics = 1;
- int iStampCnt = configCacheDepth+1;
+ int iStampCnt = mConfigCacheDepth+1;
while (ivdx >= 0) {
unsigned int icnt = piNumTriPtrNoModify[ivdx];
@@ -294,7 +287,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
*piCSIter++ = dp;
// if the vertex is not yet in cache, set its cache count
- if (iStampCnt-piCachingStamps[dp] > configCacheDepth) {
+ if (iStampCnt-piCachingStamps[dp] > mConfigCacheDepth) {
piCachingStamps[dp] = iStampCnt++;
++iCacheMisses;
}
@@ -319,7 +312,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// will the vertex be in cache, even after fanning occurs?
unsigned int tmp;
- if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= configCacheDepth) {
+ if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= mConfigCacheDepth) {
priority = tmp;
}
@@ -356,7 +349,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
}
}
}
- float fACMR2 = 0.0f;
+ ai_real fACMR2 = 0.0f;
if (!DefaultLogger::isNullLogger()) {
fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
diff --git a/thirdparty/assimp/code/ImproveCacheLocality.h b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h
index 1b29ee0d6e..de25ecd9fb 100644
--- a/thirdparty/assimp/code/ImproveCacheLocality.h
+++ b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IMPROVECACHELOCALITY_H_INC
#define AI_IMPROVECACHELOCALITY_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
struct aiMesh;
@@ -87,12 +88,12 @@ protected:
* @param pMesh The mesh to process.
* @param meshNum Index of the mesh to process
*/
- float ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
+ ai_real ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
private:
//! Configuration parameter: specifies the size of the cache to
//! optimize the vertex data for.
- unsigned int configCacheDepth;
+ unsigned int mConfigCacheDepth;
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/JoinVerticesProcess.cpp b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
index 914ec05b46..914ec05b46 100644
--- a/thirdparty/assimp/code/JoinVerticesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
diff --git a/thirdparty/assimp/code/JoinVerticesProcess.h b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h
index 66fa362de2..e017ae62db 100644
--- a/thirdparty/assimp/code/JoinVerticesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_JOINVERTICESPROCESS_H_INC
#define AI_JOINVERTICESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
struct aiMesh;
@@ -61,13 +62,11 @@ namespace Assimp
* erases all but one of the copies. This usually reduces the number of vertices
* in a mesh by a serious amount and is the standard form to render a mesh.
*/
-class ASSIMP_API JoinVerticesProcess : public BaseProcess
-{
+class ASSIMP_API JoinVerticesProcess : public BaseProcess {
public:
JoinVerticesProcess();
~JoinVerticesProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
@@ -83,15 +82,12 @@ public:
*/
void Execute( aiScene* pScene);
-public:
// -------------------------------------------------------------------
/** Unites identical vertices in the given mesh.
* @param pMesh The mesh to process.
* @param meshIndex Index of the mesh to process
*/
int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
-private:
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/LimitBoneWeightsProcess.cpp b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp
index d560f19287..d560f19287 100644
--- a/thirdparty/assimp/code/LimitBoneWeightsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp
diff --git a/thirdparty/assimp/code/LimitBoneWeightsProcess.h b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h
index 3602fd8edf..73c2a68d53 100644
--- a/thirdparty/assimp/code/LimitBoneWeightsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h
@@ -44,14 +44,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+// Forward declarations
struct aiMesh;
class LimitBoneWeightsTest;
-namespace Assimp
-{
+namespace Assimp {
// NOTE: If you change these limits, don't forget to change the
// corresponding values in all Assimp ports
@@ -72,14 +72,11 @@ namespace Assimp
* The other weights on this bone are then renormalized to assure the sum weight
* to be 1.
*/
-class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess
-{
+class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
public:
-
LimitBoneWeightsProcess();
~LimitBoneWeightsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -96,8 +93,6 @@ public:
*/
void SetupProperties(const Importer* pImp);
-public:
-
// -------------------------------------------------------------------
/** Limits the bone weight count for all vertices in the given mesh.
* @param pMesh The mesh to process.
@@ -111,34 +106,29 @@ public:
*/
void Execute( aiScene* pScene);
-
-public:
-
// -------------------------------------------------------------------
/** Describes a bone weight on a vertex */
- struct Weight
- {
+ struct Weight {
unsigned int mBone; ///< Index of the bone
float mWeight; ///< Weight of that bone on this vertex
Weight() AI_NO_EXCEPT
: mBone(0)
- , mWeight(0.0f)
- { }
+ , mWeight(0.0f) {
+ // empty
+ }
Weight( unsigned int pBone, float pWeight)
- {
- mBone = pBone;
- mWeight = pWeight;
+ : mBone(pBone)
+ , mWeight(pWeight) {
+ // empty
}
/** Comparison operator to sort bone weights by descending weight */
- bool operator < (const Weight& pWeight) const
- {
+ bool operator < (const Weight& pWeight) const {
return mWeight > pWeight.mWeight;
}
};
-public:
/** Maximum number of bones influencing any single vertex. */
unsigned int mMaxWeights;
};
diff --git a/thirdparty/assimp/code/MakeVerboseFormat.cpp b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
index 50ff5ed93d..50ff5ed93d 100644
--- a/thirdparty/assimp/code/MakeVerboseFormat.cpp
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
diff --git a/thirdparty/assimp/code/MakeVerboseFormat.h b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
index d12db63ae1..1adf8e2f69 100644
--- a/thirdparty/assimp/code/MakeVerboseFormat.h
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
@@ -46,7 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MAKEVERBOSEFORMAT_H_INC
#define AI_MAKEVERBOSEFORMAT_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
struct aiMesh;
namespace Assimp {
diff --git a/thirdparty/assimp/code/OptimizeGraph.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp
index add9ab79e1..5db51f58b6 100644
--- a/thirdparty/assimp/code/OptimizeGraph.cpp
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
diff --git a/thirdparty/assimp/code/OptimizeGraph.h b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h
index e5bbed7679..82cc5db3fe 100644
--- a/thirdparty/assimp/code/OptimizeGraph.h
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h
@@ -46,13 +46,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
#define AI_OPTIMIZEGRAPHPROCESS_H_INC
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
+#include "Common/BaseProcess.h"
+#include "PostProcessing/ProcessHelper.h"
+
#include <assimp/types.h>
+
#include <set>
+// Forward declarations
struct aiMesh;
+
class OptimizeGraphProcessTest;
+
namespace Assimp {
// -----------------------------------------------------------------------------
@@ -64,14 +69,11 @@ namespace Assimp {
* @see aiProcess_OptimizeGraph for a detailed description of the
* algorithm being applied.
*/
-class OptimizeGraphProcess : public BaseProcess
-{
+class OptimizeGraphProcess : public BaseProcess {
public:
-
OptimizeGraphProcess();
~OptimizeGraphProcess();
-public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
@@ -81,14 +83,12 @@ public:
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
-
// -------------------------------------------------------------------
/** @brief Add a list of node names to be locked and not modified.
* @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for
* format explanations.
*/
- inline void AddLockedNodeList(std::string& in)
- {
+ inline void AddLockedNodeList(std::string& in) {
ConvertListToStrings (in,locked_nodes);
}
@@ -96,8 +96,7 @@ public:
/** @brief Add another node to be locked and not modified.
* @param name Name to be locked
*/
- inline void AddLockedNode(std::string& name)
- {
+ inline void AddLockedNode(std::string& name) {
locked_nodes.push_back(name);
}
@@ -105,25 +104,21 @@ public:
/** @brief Remove a node from the list of locked nodes.
* @param name Name to be unlocked
*/
- inline void RemoveLockedNode(std::string& name)
- {
+ inline void RemoveLockedNode(std::string& name) {
locked_nodes.remove(name);
}
protected:
-
void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes);
void FindInstancedMeshes (aiNode* pNode);
private:
-
#ifdef AI_OG_USE_HASHING
typedef std::set<unsigned int> LockedSetType;
#else
typedef std::set<std::string> LockedSetType;
#endif
-
//! Scene we're working with
aiScene* mScene;
diff --git a/thirdparty/assimp/code/OptimizeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp
index 3f6765f6ca..3f6765f6ca 100644
--- a/thirdparty/assimp/code/OptimizeMeshes.cpp
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp
diff --git a/thirdparty/assimp/code/OptimizeMeshes.h b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h
index 9f46f349b4..dec4ab52de 100644
--- a/thirdparty/assimp/code/OptimizeMeshes.h
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h
@@ -46,8 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC
#define AI_OPTIMIZEMESHESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
+
#include <vector>
struct aiMesh;
@@ -64,16 +66,14 @@ namespace Assimp {
*
* @note Instanced meshes are currently not processed.
*/
-class OptimizeMeshesProcess : public BaseProcess
-{
+class OptimizeMeshesProcess : public BaseProcess {
public:
/// @brief The class constructor.
OptimizeMeshesProcess();
- /// @brief The class destcructor,
+ /// @brief The class destructor.
~OptimizeMeshesProcess();
-
/** @brief Internal utility to store additional mesh info
*/
struct MeshInfo {
diff --git a/thirdparty/assimp/code/PretransformVertices.cpp b/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp
index 52001a0578..52001a0578 100644
--- a/thirdparty/assimp/code/PretransformVertices.cpp
+++ b/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp
diff --git a/thirdparty/assimp/code/PretransformVertices.h b/thirdparty/assimp/code/PostProcessing/PretransformVertices.h
index b7329af130..b2982951e0 100644
--- a/thirdparty/assimp/code/PretransformVertices.h
+++ b/thirdparty/assimp/code/PostProcessing/PretransformVertices.h
@@ -47,13 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PRETRANSFORMVERTICES_H_INC
#define AI_PRETRANSFORMVERTICES_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
+
#include <list>
#include <vector>
+// Forward declarations
struct aiNode;
+
class PretransformVerticesTest;
+
namespace Assimp {
// ---------------------------------------------------------------------------
@@ -80,10 +85,10 @@ public:
// -------------------------------------------------------------------
/** @brief Toggle the 'keep hierarchy' option
- * @param d hm ... difficult to guess what this means, hu!?
+ * @param keep true for keep configuration.
*/
- void KeepHierarchy(bool d) {
- configKeepHierarchy = d;
+ void KeepHierarchy(bool keep) {
+ configKeepHierarchy = keep;
}
// -------------------------------------------------------------------
@@ -148,8 +153,6 @@ private:
// Build reference counters for all meshes
void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs);
-
-
//! Configuration option: keep scene hierarchy as long as possible
bool configKeepHierarchy;
bool configNormalize;
diff --git a/thirdparty/assimp/code/ProcessHelper.cpp b/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp
index 59869fdff7..59869fdff7 100644
--- a/thirdparty/assimp/code/ProcessHelper.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp
diff --git a/thirdparty/assimp/code/ProcessHelper.h b/thirdparty/assimp/code/PostProcessing/ProcessHelper.h
index c59f3217bf..0afcc41420 100644
--- a/thirdparty/assimp/code/ProcessHelper.h
+++ b/thirdparty/assimp/code/PostProcessing/ProcessHelper.h
@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/SpatialSort.h>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/ParsingUtils.h>
#include <list>
diff --git a/thirdparty/assimp/code/RemoveRedundantMaterials.cpp b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp
index 632bdca3fe..49ec8f5c47 100644
--- a/thirdparty/assimp/code/RemoveRedundantMaterials.cpp
+++ b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RemoveRedundantMaterials.h"
#include <assimp/ParsingUtils.h>
#include "ProcessHelper.h"
-#include "MaterialSystem.h"
+#include "Material/MaterialSystem.h"
#include <stdio.h>
using namespace Assimp;
@@ -57,7 +57,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
-: configFixedMaterials() {
+: mConfigFixedMaterials() {
// nothing to do here
}
@@ -80,7 +80,7 @@ bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
{
// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
- configFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
+ mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
}
// ------------------------------------------------------------------------------------------------
@@ -100,10 +100,10 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// If a list of materials to be excluded was given, match the list with
// our imported materials and 'salt' all positive matches to ensure that
// we get unique hashes later.
- if (configFixedMaterials.length()) {
+ if (mConfigFixedMaterials.length()) {
std::list<std::string> strings;
- ConvertListToStrings(configFixedMaterials,strings);
+ ConvertListToStrings(mConfigFixedMaterials,strings);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
aiMaterial* mat = pScene->mMaterials[i];
diff --git a/thirdparty/assimp/code/RemoveRedundantMaterials.h b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h
index dbd4d44cc0..1f32a0abfb 100644
--- a/thirdparty/assimp/code/RemoveRedundantMaterials.h
+++ b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC
#define AI_REMOVEREDUNDANTMATERIALS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
class RemoveRedundantMatsTest;
@@ -57,8 +57,7 @@ namespace Assimp {
/** RemoveRedundantMatsProcess: Post-processing step to remove redundant
* materials from the imported scene.
*/
-class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess
-{
+class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
public:
/// The default class constructor.
RemoveRedundantMatsProcess();
@@ -66,7 +65,6 @@ public:
/// The class destructor.
~RemoveRedundantMatsProcess();
-public:
// -------------------------------------------------------------------
// Check whether step is active
bool IsActive( unsigned int pFlags) const;
@@ -79,27 +77,25 @@ public:
// Setup import settings
void SetupProperties(const Importer* pImp);
-
// -------------------------------------------------------------------
- /** @brief Set list of fixed (unmutable) materials
+ /** @brief Set list of fixed (inmutable) materials
* @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
*/
void SetFixedMaterialsString(const std::string& fixed = "") {
- configFixedMaterials = fixed;
+ mConfigFixedMaterials = fixed;
}
// -------------------------------------------------------------------
- /** @brief Get list of fixed (unmutable) materials
+ /** @brief Get list of fixed (inmutable) materials
* @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
*/
const std::string& GetFixedMaterialsString() const {
- return configFixedMaterials;
+ return mConfigFixedMaterials;
}
private:
-
//! Configuration option: list of all fixed materials
- std::string configFixedMaterials;
+ std::string mConfigFixedMaterials;
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/RemoveVCProcess.cpp b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp
index 99fd47a3aa..99fd47a3aa 100644
--- a/thirdparty/assimp/code/RemoveVCProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp
diff --git a/thirdparty/assimp/code/RemoveVCProcess.h b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h
index 617d7b9b20..7bb21a8330 100644
--- a/thirdparty/assimp/code/RemoveVCProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h
@@ -44,7 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
#define AI_REMOVEVCPROCESS_H_INCLUDED
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
class RemoveVCProcessTest;
diff --git a/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
new file mode 100644
index 0000000000..ac770c41f2
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
@@ -0,0 +1,208 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+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.
+
+----------------------------------------------------------------------
+*/
+#include "ScaleProcess.h"
+
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+#include <assimp/BaseImporter.h>
+
+namespace Assimp {
+
+ScaleProcess::ScaleProcess()
+: BaseProcess()
+, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
+}
+
+ScaleProcess::~ScaleProcess() {
+ // empty
+}
+
+void ScaleProcess::setScale( ai_real scale ) {
+ mScale = scale;
+}
+
+ai_real ScaleProcess::getScale() const {
+ return mScale;
+}
+
+bool ScaleProcess::IsActive( unsigned int pFlags ) const {
+ return ( pFlags & aiProcess_GlobalScale ) != 0;
+}
+
+void ScaleProcess::SetupProperties( const Importer* pImp ) {
+ // User scaling
+ mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
+
+ // File scaling * Application Scaling
+ float importerScale = pImp->GetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, 1.0f );
+
+ // apply scale to the scale
+ // helps prevent bugs with backward compatibility for anyone using normal scaling.
+ mScale *= importerScale;
+}
+
+void ScaleProcess::Execute( aiScene* pScene ) {
+ if(mScale == 1.0f) {
+ return; // nothing to scale
+ }
+
+ ai_assert( mScale != 0 );
+ ai_assert( nullptr != pScene );
+ ai_assert( nullptr != pScene->mRootNode );
+
+ if ( nullptr == pScene ) {
+ return;
+ }
+
+ if ( nullptr == pScene->mRootNode ) {
+ return;
+ }
+
+ // Process animations and update position transform to new unit system
+ for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ )
+ {
+ aiAnimation* animation = pScene->mAnimations[animationID];
+
+ for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++)
+ {
+ aiNodeAnim* anim = animation->mChannels[animationChannel];
+
+ for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++)
+ {
+ aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
+ vectorKey.mValue *= mScale;
+ }
+ }
+ }
+
+ for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++)
+ {
+ aiMesh *mesh = pScene->mMeshes[meshID];
+
+ // Reconstruct mesh vertexes to the new unit system
+ for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++)
+ {
+ aiVector3D& vertex = mesh->mVertices[vertexID];
+ vertex *= mScale;
+ }
+
+
+ // bone placement / scaling
+ for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++)
+ {
+ // Reconstruct matrix by transform rather than by scale
+ // This prevent scale values being changed which can
+ // be meaningful in some cases
+ // like when you want the modeller to see 1:1 compatibility.
+ aiBone* bone = mesh->mBones[boneID];
+
+ aiVector3D pos, scale;
+ aiQuaternion rotation;
+
+ bone->mOffsetMatrix.Decompose( scale, rotation, pos);
+
+ aiMatrix4x4 translation;
+ aiMatrix4x4::Translation( pos * mScale, translation );
+
+ aiMatrix4x4 scaling;
+ aiMatrix4x4::Scaling( aiVector3D(scale), scaling );
+
+ aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
+
+ bone->mOffsetMatrix = translation * RotMatrix * scaling;
+ }
+
+
+ // animation mesh processing
+ // convert by position rather than scale.
+ for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++)
+ {
+ aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
+
+ for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++)
+ {
+ aiVector3D& vertex = animMesh->mVertices[vertexID];
+ vertex *= mScale;
+ }
+ }
+ }
+
+ traverseNodes( pScene->mRootNode );
+}
+
+void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
+ applyScaling( node );
+
+ for( size_t i = 0; i < node->mNumChildren; i++)
+ {
+ // recurse into the tree until we are done!
+ traverseNodes( node->mChildren[i], nested_node_id+1 );
+ }
+}
+
+void ScaleProcess::applyScaling( aiNode *currentNode ) {
+ if ( nullptr != currentNode ) {
+ // Reconstruct matrix by transform rather than by scale
+ // This prevent scale values being changed which can
+ // be meaningful in some cases
+ // like when you want the modeller to
+ // see 1:1 compatibility.
+
+ aiVector3D pos, scale;
+ aiQuaternion rotation;
+ currentNode->mTransformation.Decompose( scale, rotation, pos);
+
+ aiMatrix4x4 translation;
+ aiMatrix4x4::Translation( pos * mScale, translation );
+
+ aiMatrix4x4 scaling;
+
+ // note: we do not use mScale here, this is on purpose.
+ aiMatrix4x4::Scaling( scale, scaling );
+
+ aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
+
+ currentNode->mTransformation = translation * RotMatrix * scaling;
+ }
+}
+
+} // Namespace Assimp
diff --git a/thirdparty/assimp/code/ScaleProcess.h b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
index 55146ae064..468a216736 100644
--- a/thirdparty/assimp/code/ScaleProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
@@ -39,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-#pragma once
+#ifndef SCALE_PROCESS_H_
+#define SCALE_PROCESS_H_
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiNode;
@@ -53,6 +54,11 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/** ScaleProcess: Class to rescale the whole model.
+ * Now rescales animations, bones, and blend shapes properly.
+ * Please note this will not write to 'scale' transform it will rewrite mesh
+ * and matrixes so that your scale values
+ * from your model package are preserved, so this is completely intentional
+ * bugs should be reported as soon as they are found.
*/
class ASSIMP_API ScaleProcess : public BaseProcess {
public:
@@ -78,7 +84,7 @@ public:
virtual void Execute( aiScene* pScene );
private:
- void traverseNodes( aiNode *currentNode );
+ void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 );
void applyScaling( aiNode *currentNode );
private:
@@ -86,3 +92,6 @@ private:
};
} // Namespace Assimp
+
+
+#endif // SCALE_PROCESS_H_ \ No newline at end of file
diff --git a/thirdparty/assimp/code/SortByPTypeProcess.cpp b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp
index 2e0cc54004..be8405a17b 100644
--- a/thirdparty/assimp/code/SortByPTypeProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp
@@ -57,8 +57,8 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess()
-{
- configRemoveMeshes = 0;
+: mConfigRemoveMeshes( 0 ) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
@@ -78,7 +78,7 @@ bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
// ------------------------------------------------------------------------------------------------
void SortByPTypeProcess::SetupProperties(const Importer* pImp)
{
- configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
+ mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
}
// ------------------------------------------------------------------------------------------------
@@ -172,7 +172,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
}
if (1 == num) {
- if (!(configRemoveMeshes & mesh->mPrimitiveTypes)) {
+ if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
*meshIdx = static_cast<unsigned int>( outMeshes.size() );
outMeshes.push_back(mesh);
} else {
@@ -206,7 +206,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
for (unsigned int real = 0; real < 4; ++real,++meshIdx)
{
- if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
+ if ( !aiNumPerPType[real] || mConfigRemoveMeshes & (1u << real))
{
continue;
}
@@ -392,10 +392,10 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
{
char buffer[1024];
::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
- aiNumMeshesPerPType[0], ((configRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
- aiNumMeshesPerPType[1], ((configRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
- aiNumMeshesPerPType[2], ((configRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
- aiNumMeshesPerPType[3], ((configRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
+ aiNumMeshesPerPType[0], ((mConfigRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
+ aiNumMeshesPerPType[1], ((mConfigRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
+ aiNumMeshesPerPType[2], ((mConfigRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
+ aiNumMeshesPerPType[3], ((mConfigRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
ASSIMP_LOG_INFO(buffer);
ASSIMP_LOG_DEBUG("SortByPTypeProcess finished");
}
diff --git a/thirdparty/assimp/code/SortByPTypeProcess.h b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h
index c9d9924d8f..1d7ccfc152 100644
--- a/thirdparty/assimp/code/SortByPTypeProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h
@@ -45,10 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SORTBYPTYPEPROCESS_H_INC
#define AI_SORTBYPTYPEPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
class SortByPTypeProcessTest;
+
namespace Assimp {
@@ -57,14 +58,11 @@ namespace Assimp {
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
* submeshes.
*/
-class ASSIMP_API SortByPTypeProcess : public BaseProcess
-{
+class ASSIMP_API SortByPTypeProcess : public BaseProcess {
public:
-
SortByPTypeProcess();
~SortByPTypeProcess();
-public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
@@ -75,8 +73,7 @@ public:
void SetupProperties(const Importer* pImp);
private:
-
- int configRemoveMeshes;
+ int mConfigRemoveMeshes;
};
diff --git a/thirdparty/assimp/code/SplitLargeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp
index 1797b28d5a..1797b28d5a 100644
--- a/thirdparty/assimp/code/SplitLargeMeshes.cpp
+++ b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp
diff --git a/thirdparty/assimp/code/SplitLargeMeshes.h b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h
index 77f089ce7e..3f90576ea9 100644
--- a/thirdparty/assimp/code/SplitLargeMeshes.h
+++ b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -40,21 +39,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-/** @file Defines a post processing step to split large meshes into submeshes
+/** @file Defines a post processing step to split large meshes into sub-meshes
*/
#ifndef AI_SPLITLARGEMESHES_H_INC
#define AI_SPLITLARGEMESHES_H_INC
#include <vector>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
#include <assimp/scene.h>
+// Forward declarations
class SplitLargeMeshesTest;
-namespace Assimp
-{
+namespace Assimp {
class SplitLargeMeshesProcess_Triangle;
class SplitLargeMeshesProcess_Vertex;
diff --git a/thirdparty/assimp/code/TextureTransform.cpp b/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp
index 8ae2ba7218..8ae2ba7218 100644
--- a/thirdparty/assimp/code/TextureTransform.cpp
+++ b/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp
diff --git a/thirdparty/assimp/code/TextureTransform.h b/thirdparty/assimp/code/PostProcessing/TextureTransform.h
index c556ff5d8c..2a5d623d7f 100644
--- a/thirdparty/assimp/code/TextureTransform.h
+++ b/thirdparty/assimp/code/PostProcessing/TextureTransform.h
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_TEXTURE_TRANSFORM_H_INCLUDED
#include <assimp/BaseImporter.h>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/material.h>
#include <list>
diff --git a/thirdparty/assimp/code/TriangulateProcess.cpp b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp
index 0f68f47ddb..1040836bbe 100644
--- a/thirdparty/assimp/code/TriangulateProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -60,9 +58,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* a file
*/
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-#include "TriangulateProcess.h"
-#include "ProcessHelper.h"
-#include "PolyTools.h"
+
+#include "PostProcessing/TriangulateProcess.h"
+#include "PostProcessing/ProcessHelper.h"
+#include "Common/PolyTools.h"
+
#include <memory>
//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
diff --git a/thirdparty/assimp/code/TriangulateProcess.h b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h
index 47bd2115ad..916b5103dd 100644
--- a/thirdparty/assimp/code/TriangulateProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TRIANGULATEPROCESS_H_INC
#define AI_TRIANGULATEPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
@@ -59,14 +59,11 @@ namespace Assimp {
* into triangles. You usually want this to happen because the graphics cards
* need their data as triangles.
*/
-class ASSIMP_API TriangulateProcess : public BaseProcess
-{
+class ASSIMP_API TriangulateProcess : public BaseProcess {
public:
-
TriangulateProcess();
~TriangulateProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
@@ -82,7 +79,6 @@ public:
*/
void Execute( aiScene* pScene);
-public:
// -------------------------------------------------------------------
/** Triangulates the given mesh.
* @param pMesh The mesh to triangulate.
diff --git a/thirdparty/assimp/code/ValidateDataStructure.cpp b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
index 657b0361b7..712fd6943d 100644
--- a/thirdparty/assimp/code/ValidateDataStructure.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
@@ -46,8 +46,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* the data structure returned by Assimp.
*/
-
-
// internal headers
#include "ValidateDataStructure.h"
#include <assimp/BaseImporter.h>
@@ -110,8 +108,8 @@ void ValidateDSProcess::ReportWarning(const char* msg,...)
}
// ------------------------------------------------------------------------------------------------
-inline int HasNameMatch(const aiString& in, aiNode* node)
-{
+inline
+int HasNameMatch(const aiString& in, aiNode* node) {
int result = (node->mName == in ? 1 : 0 );
for (unsigned int i = 0; i < node->mNumChildren;++i) {
result += HasNameMatch(in,node->mChildren[i]);
@@ -121,9 +119,8 @@ inline int HasNameMatch(const aiString& in, aiNode* node)
// ------------------------------------------------------------------------------------------------
template <typename T>
-inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
+inline
+void ValidateDSProcess::DoValidation(T** parray, unsigned int size, const char* firstName, const char* secondName) {
// validate all entries
if (size)
{
@@ -181,7 +178,8 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
// ------------------------------------------------------------------------------------------------
template <typename T>
inline
-void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size, const char* firstName, const char* secondName) {
+void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size, const char* firstName,
+ const char* secondName) {
// validate all entries
DoValidationEx(array,size,firstName,secondName);
@@ -201,9 +199,8 @@ void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size,
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
-void ValidateDSProcess::Execute( aiScene* pScene)
-{
- this->mScene = pScene;
+void ValidateDSProcess::Execute( aiScene* pScene) {
+ mScene = pScene;
ASSIMP_LOG_DEBUG("ValidateDataStructureProcess begin");
// validate the node graph of the scene
@@ -516,13 +513,11 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
}
// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh,
- const aiBone* pBone,float* afSum)
-{
+void ValidateDSProcess::Validate( const aiMesh* pMesh, const aiBone* pBone,float* afSum) {
this->Validate(&pBone->mName);
if (!pBone->mNumWeights) {
- ReportError("aiBone::mNumWeights is zero");
+ //ReportError("aiBone::mNumWeights is zero");
}
// check whether all vertices affected by this bone are valid
@@ -563,9 +558,6 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
}
-
- // Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
- // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
}
// ------------------------------------------------------------------------------------------------
@@ -746,8 +738,9 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
"AI_MATKEY_SHININESS_STRENGTH key is 0.0");
}
break;
- default: ;
- };
+ default:
+ break;
+ }
}
if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) {
diff --git a/thirdparty/assimp/code/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
index bd21e88545..0b891ef414 100644
--- a/thirdparty/assimp/code/ValidateDataStructure.h
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
@@ -48,7 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <assimp/material.h>
-#include "BaseProcess.h"
+
+#include "Common/BaseProcess.h"
struct aiBone;
struct aiMesh;
diff --git a/thirdparty/assimp/code/RawLoader.cpp b/thirdparty/assimp/code/RawLoader.cpp
deleted file mode 100644
index d0da247e47..0000000000
--- a/thirdparty/assimp/code/RawLoader.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-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.
----------------------------------------------------------------------------
-*/
-
-/** @file RawLoader.cpp
- * @brief Implementation of the RAW importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-
-// internal headers
-#include "RawLoader.h"
-#include <assimp/ParsingUtils.h>
-#include <assimp/fast_atof.h>
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Raw Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "raw"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RAWImporter::RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RAWImporter::~RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"raw");
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* RAWImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void RAWImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // list of groups loaded from the file
- std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
- std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
-
- // now read all lines
- char line[4096];
- while (GetNextLine(buffer,line))
- {
- // if the line starts with a non-numeric identifier, it marks
- // the beginning of a new group
- const char* sz = line;SkipSpaces(&sz);
- if (IsLineEnd(*sz))continue;
- if (!IsNumeric(*sz))
- {
- const char* sz2 = sz;
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- const unsigned int length = (unsigned int)(sz2-sz);
-
- // find an existing group with this name
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
- {
- curGroup = it;sz2 = NULL;
- break;
- }
- }
- if (sz2)
- {
- outGroups.push_back(GroupInformation(std::string(sz,length)));
- curGroup = outGroups.end()-1;
- }
- }
- else
- {
- // there can be maximally 12 floats plus an extra texture file name
- float data[12];
- unsigned int num;
- for (num = 0; num < 12;++num)
- {
- if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
- sz = fast_atoreal_move<float>(sz,data[num]);
- }
- if (num != 12 && num != 9)
- {
- ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
- continue;
- }
-
- MeshInformation* output = NULL;
-
- const char* sz2 = sz;
- unsigned int length;
- if (!IsLineEnd(*sz))
- {
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- length = (unsigned int)(sz2-sz);
- }
- else if (9 == num)
- {
- sz = "%default%";
- length = 9;
- }
- else
- {
- sz = "";
- length = 0;
- }
-
- // search in the list of meshes whether we have one with this texture
- for (auto &mesh : (*curGroup).meshes)
- {
- if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true))
- {
- output = &mesh;
- break;
- }
- }
- // if we don't have the mesh, create it
- if (!output)
- {
- (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
- output = &((*curGroup).meshes.back());
- }
- if (12 == num)
- {
- aiColor4D v(data[0],data[1],data[2],1.0f);
- output->colors.push_back(v);
- output->colors.push_back(v);
- output->colors.push_back(v);
-
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
- }
- else
- {
- output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- }
- }
- }
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<RawRoot>");
-
- // count the number of valid groups
- // (meshes can't be empty)
- for (auto & outGroup : outGroups)
- {
- if (!outGroup.meshes.empty())
- {
- ++pScene->mRootNode->mNumChildren;
- pScene->mNumMeshes += (unsigned int) outGroup.meshes.size();
- }
- }
-
- if (!pScene->mNumMeshes)
- {
- throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- aiNode** cc;
- if (1 == pScene->mRootNode->mNumChildren)
- {
- cc = &pScene->mRootNode;
- pScene->mRootNode->mNumChildren = 0;
- } else {
- cc = new aiNode*[pScene->mRootNode->mNumChildren];
- memset(cc, 0, sizeof(aiNode*) * pScene->mRootNode->mNumChildren);
- pScene->mRootNode->mChildren = cc;
- }
-
- pScene->mNumMaterials = pScene->mNumMeshes;
- aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
-
- unsigned int meshIdx = 0;
- for (auto & outGroup : outGroups)
- {
- if (outGroup.meshes.empty())continue;
-
- aiNode* node;
- if (pScene->mRootNode->mNumChildren)
- {
- node = *cc = new aiNode();
- node->mParent = pScene->mRootNode;
- }
- else node = *cc;
- node->mName.Set(outGroup.name);
-
- // add all meshes
- node->mNumMeshes = (unsigned int) outGroup.meshes.size();
- unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
- for (std::vector< MeshInformation >::iterator it2 = outGroup.meshes.begin(),
- end2 = outGroup.meshes.end(); it2 != end2; ++it2)
- {
- ai_assert(!(*it2).vertices.empty());
-
- // allocate the mesh
- *pi++ = meshIdx;
- aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
- mesh->mMaterialIndex = meshIdx++;
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for the vertex components and copy them
- mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
- mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
- ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
-
- if ((*it2).colors.size())
- {
- ai_assert((*it2).colors.size() == mesh->mNumVertices);
-
- mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
- ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- // generate triangles
- ai_assert(0 == mesh->mNumVertices % 3);
- aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
- aiFace* const fcEnd = fc + mesh->mNumFaces;
- unsigned int n = 0;
- while (fc != fcEnd)
- {
- aiFace& f = *fc++;
- f.mIndices = new unsigned int[f.mNumIndices = 3];
- for (unsigned int m = 0; m < 3;++m)
- f.mIndices[m] = n++;
- }
-
- // generate a material for the mesh
- aiMaterial* mat = new aiMaterial();
-
- aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
- if ("%default%" == (*it2).name) // a gray default material
- {
- clr.r = clr.g = clr.b = 0.6f;
- }
- else if ((*it2).name.length() > 0) // a texture
- {
- aiString s;
- s.Set((*it2).name);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- *mats++ = mat;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
diff --git a/thirdparty/assimp/code/ScaleProcess.cpp b/thirdparty/assimp/code/ScaleProcess.cpp
deleted file mode 100644
index 6d458c4b11..0000000000
--- a/thirdparty/assimp/code/ScaleProcess.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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.
-
-----------------------------------------------------------------------
-*/
-#ifndef ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
-
-#include "ScaleProcess.h"
-
-#include <assimp/scene.h>
-#include <assimp/postprocess.h>
-
-namespace Assimp {
-
-ScaleProcess::ScaleProcess()
-: BaseProcess()
-, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
- // empty
-}
-
-ScaleProcess::~ScaleProcess() {
- // empty
-}
-
-void ScaleProcess::setScale( ai_real scale ) {
- mScale = scale;
-}
-
-ai_real ScaleProcess::getScale() const {
- return mScale;
-}
-
-bool ScaleProcess::IsActive( unsigned int pFlags ) const {
- return ( pFlags & aiProcess_GlobalScale ) != 0;
-}
-
-void ScaleProcess::SetupProperties( const Importer* pImp ) {
- mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 );
-}
-
-void ScaleProcess::Execute( aiScene* pScene ) {
- if ( nullptr == pScene ) {
- return;
- }
-
- if ( nullptr == pScene->mRootNode ) {
- return;
- }
-
- traverseNodes( pScene->mRootNode );
-}
-
-void ScaleProcess::traverseNodes( aiNode *node ) {
- applyScaling( node );
-}
-
-void ScaleProcess::applyScaling( aiNode *currentNode ) {
- if ( nullptr != currentNode ) {
- currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale;
- currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale;
- currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale;
- }
-}
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
diff --git a/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes b/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
new file mode 100644
index 0000000000..364411a23d
--- /dev/null
+++ b/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
@@ -0,0 +1,12 @@
+utf8 cpp library
+Release 2.3.4
+
+A minor bug fix release. Thanks to all who reported bugs.
+
+Note: Version 2.3.3 contained a regression, and therefore was removed.
+
+Changes from version 2.3.2
+- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
+- Bug fix [36]: replace_invalid() only works with back_inserter
+
+Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
diff --git a/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html b/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
new file mode 100644
index 0000000000..6f2aacbe7b
--- /dev/null
+++ b/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
@@ -0,0 +1,1789 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st November 2002), see www.w3.org">
+ <meta name="description" content=
+ "A simple, portable and lightweigt C++ library for easy handling of UTF-8 encoded strings">
+ <meta name="keywords" content="UTF-8 C++ portable utf8 unicode generic templates">
+ <meta name="author" content="Nemanja Trifunovic">
+ <title>
+ UTF8-CPP: UTF-8 with C++ in a Portable Way
+ </title>
+ <style type="text/css">
+ <!--
+ span.return_value {
+ color: brown;
+ }
+ span.keyword {
+ color: blue;
+ }
+ span.preprocessor {
+ color: navy;
+ }
+ span.literal {
+ color: olive;
+ }
+ span.comment {
+ color: green;
+ }
+ code {
+ font-weight: bold;
+ }
+ ul.toc {
+ list-style-type: none;
+ }
+ p.version {
+ font-size: small;
+ font-style: italic;
+ }
+ -->
+ </style>
+ </head>
+ <body>
+ <h1>
+ UTF8-CPP: UTF-8 with C++ in a Portable Way
+ </h1>
+ <p>
+ <a href="https://sourceforge.net/projects/utfcpp">The Sourceforge project page</a>
+ </p>
+ <div id="toc">
+ <h2>
+ Table of Contents
+ </h2>
+ <ul class="toc">
+ <li>
+ <a href="#introduction">Introduction</a>
+ </li>
+ <li>
+ <a href="#examples">Examples of Use</a>
+ <ul class="toc">
+ <li>
+ <a href=#introsample>Introductionary Sample </a>
+ </li>
+ <li>
+ <a href=#validfile>Checking if a file contains valid UTF-8 text</a>
+ </li>
+ <li>
+ <a href=#fixinvalid>Ensure that a string contains valid UTF-8 text</a>
+ </li>
+ </ul>
+ <li>
+ <a href="#reference">Reference</a>
+ <ul class="toc">
+ <li>
+ <a href="#funutf8">Functions From utf8 Namespace </a>
+ </li>
+ <li>
+ <a href="#typesutf8">Types From utf8 Namespace </a>
+ </li>
+ <li>
+ <a href="#fununchecked">Functions From utf8::unchecked Namespace </a>
+ </li>
+ <li>
+ <a href="#typesunchecked">Types From utf8::unchecked Namespace </a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <a href="#points">Points of Interest</a>
+ </li>
+ <li>
+ <a href="#links">Links</a>
+ </li>
+ </ul>
+ </div>
+ <h2 id="introduction">
+ Introduction
+ </h2>
+ <p>
+ Many C++ developers miss an easy and portable way of handling Unicode encoded
+ strings. The original C++ Standard (known as C++98 or C++03) is Unicode agnostic.
+ C++11 provides some support for Unicode on core language and library level:
+ u8, u, and U character and string literals, char16_t and char32_t character types,
+ u16string and u32string library classes, and codecvt support for conversions
+ between Unicode encoding forms.
+ In the meantime, developers use third party libraries like ICU, OS specific capabilities, or simply
+ roll out their own solutions.
+ </p>
+ <p>
+ In order to easily handle UTF-8 encoded Unicode strings, I came up with a small
+ generic library. For anybody used to work with STL algorithms and iterators, it should be
+ easy and natural to use. The code is freely available for any purpose - check out
+ the license at the beginning of the utf8.h file. If you run into
+ bugs or performance issues, please let me know and I'll do my best to address them.
+ </p>
+ <p>
+ The purpose of this article is not to offer an introduction to Unicode in general,
+ and UTF-8 in particular. If you are not familiar with Unicode, be sure to check out
+ <a href="http://www.unicode.org/">Unicode Home Page</a> or some other source of
+ information for Unicode. Also, it is not my aim to advocate the use of UTF-8
+ encoded strings in C++ programs; if you want to handle UTF-8 encoded strings from
+ C++, I am sure you have good reasons for it.
+ </p>
+ <h2 id="examples">
+ Examples of use
+ </h2>
+ <h3 id="introsample">
+ Introductionary Sample
+ </h3>
+ <p>
+ To illustrate the use of the library, let's start with a small but complete program
+ that opens a file containing UTF-8 encoded text, reads it line by line, checks each line
+ for invalid UTF-8 byte sequences, and converts it to UTF-16 encoding and back to UTF-8:
+ </p>
+<pre>
+<span class="preprocessor">#include &lt;fstream&gt;</span>
+<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;string&gt;</span>
+<span class="preprocessor">#include &lt;vector&gt;</span>
+<span class="preprocessor">#include "utf8.h"</span>
+<span class="keyword">using namespace</span> std;
+<span class="keyword">int</span> main(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)
+{
+ <span class="keyword">if</span> (argc != <span class="literal">2</span>) {
+ cout &lt;&lt; <span class="literal">"\nUsage: docsample filename\n"</span>;
+ <span class="keyword">return</span> <span class="literal">0</span>;
+ }
+
+ <span class="keyword">const char</span>* test_file_path = argv[1];
+ <span class="comment">// Open the test file (contains UTF-8 encoded text)</span>
+ ifstream fs8(test_file_path);
+ <span class="keyword">if</span> (!fs8.is_open()) {
+ cout &lt;&lt; <span class=
+"literal">"Could not open "</span> &lt;&lt; test_file_path &lt;&lt; endl;
+ <span class="keyword">return</span> <span class="literal">0</span>;
+ }
+
+ <span class="keyword">unsigned</span> line_count = <span class="literal">1</span>;
+ string line;
+ <span class="comment">// Play with all the lines in the file</span>
+ <span class="keyword">while</span> (getline(fs8, line)) {
+ <span class="comment">// check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)</span>
+ string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
+ <span class="keyword">if</span> (end_it != line.end()) {
+ cout &lt;&lt; <span class=
+"literal">"Invalid UTF-8 encoding detected at line "</span> &lt;&lt; line_count &lt;&lt; <span
+ class="literal">"\n"</span>;
+ cout &lt;&lt; <span class=
+"literal">"This part is fine: "</span> &lt;&lt; string(line.begin(), end_it) &lt;&lt; <span
+ class="literal">"\n"</span>;
+ }
+
+ <span class="comment">// Get the line length (at least for the valid part)</span>
+ <span class="keyword">int</span> length = utf8::distance(line.begin(), end_it);
+ cout &lt;&lt; <span class=
+"literal">"Length of line "</span> &lt;&lt; line_count &lt;&lt; <span class=
+"literal">" is "</span> &lt;&lt; length &lt;&lt; <span class="literal">"\n"</span>;
+
+ <span class="comment">// Convert it to utf-16</span>
+ vector&lt;unsigned short&gt; utf16line;
+ utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+
+ <span class="comment">// And back to utf-8</span>
+ string utf8line;
+ utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
+
+ <span class="comment">// Confirm that the conversion went OK:</span>
+ <span class="keyword">if</span> (utf8line != string(line.begin(), end_it))
+ cout &lt;&lt; <span class=
+"literal">"Error in UTF-16 conversion at line: "</span> &lt;&lt; line_count &lt;&lt; <span
+ class="literal">"\n"</span>;
+
+ line_count++;
+ }
+ <span class="keyword">return</span> <span class="literal">0</span>;
+}
+</pre>
+ <p>
+ In the previous code sample, for each line we performed
+ a detection of invalid UTF-8 sequences with <code>find_invalid</code>; the number
+ of characters (more precisely - the number of Unicode code points, including the end
+ of line and even BOM if there is one) in each line was
+ determined with a use of <code>utf8::distance</code>; finally, we have converted
+ each line to UTF-16 encoding with <code>utf8to16</code> and back to UTF-8 with
+ <code>utf16to8</code>.
+ </p>
+ <h3 id="validfile">Checking if a file contains valid UTF-8 text</h3>
+<p>
+Here is a function that checks whether the content of a file is valid UTF-8 encoded text without
+reading the content into the memory:
+</p>
+<pre>
+<span class="keyword">bool</span> valid_utf8_file(i<span class="keyword">const char</span>* file_name)
+{
+ ifstream ifs(file_name);
+ <span class="keyword">if</span> (!ifs)
+ <span class="keyword">return false</span>; <span class="comment">// even better, throw here</span>
+
+ istreambuf_iterator&lt;<span class="keyword">char</span>&gt; it(ifs.rdbuf());
+ istreambuf_iterator&lt;<span class="keyword">char</span>&gt; eos;
+
+ <span class="keyword">return</span> utf8::is_valid(it, eos);
+}
+</pre>
+<p>
+Because the function <code>utf8::is_valid()</code> works with input iterators, we were able
+to pass an <code>istreambuf_iterator</code> to it and read the content of the file directly
+without loading it to the memory first.</p>
+<p>
+Note that other functions that take input iterator arguments can be used in a similar way. For
+instance, to read the content of a UTF-8 encoded text file and convert the text to UTF-16, just
+do something like:
+</p>
+<pre>
+ utf8::utf8to16(it, eos, back_inserter(u16string));
+</pre>
+ <h3 id="fixinvalid">Ensure that a string contains valid UTF-8 text</h3>
+<p>
+If we have some text that "probably" contains UTF-8 encoded text and we want to
+replace any invalid UTF-8 sequence with a replacement character, something like
+the following function may be used:
+</p>
+<pre>
+<span class="keyword">void</span> fix_utf8_string(std::string&amp; str)
+{
+ std::string temp;
+ utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp));
+ str = temp;
+}
+</pre>
+<p>The function will replace any invalid UTF-8 sequence with a Unicode replacement character.
+There is an overloaded function that enables the caller to supply their own replacement character.
+</p>
+ <h2 id="reference">
+ Reference
+ </h2>
+ <h3 id="funutf8">
+ Functions From utf8 Namespace
+ </h3>
+ <h4>
+ utf8::append
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
+ to a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator append(uint32_t cp, octet_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>cp</code>: a 32 bit integer representing a code point to append to the
+ sequence.<br>
+ <code>result</code>: an output iterator to the place in the sequence where to
+ append the code point.<br>
+ <span class="return_value">Return value</span>: an iterator pointing to the place
+ after the newly appended sequence.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
+class="literal">0</span>,<span class="literal">0</span>,<span class=
+"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
+<span class="keyword">unsigned char</span>* end = append(<span class=
+"literal">0x0448</span>, u);
+assert (u[<span class="literal">0</span>] == <span class=
+"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
+"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
+"literal">0</span>);
+</pre>
+ <p>
+ Note that <code>append</code> does not allocate any memory - it is the burden of
+ the caller to make sure there is enough memory allocated for the operation. To make
+ things more interesting, <code>append</code> can add anywhere between 1 and 4
+ octets to the sequence. In practice, you would most often want to use
+ <code>std::back_inserter</code> to ensure that the necessary memory is allocated.
+ </p>
+ <p>
+ In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::next
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code
+ point and moves the iterator to the next position.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t next(octet_iterator&amp; it, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ beginning of the next code point.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = next(w, twochars + <span class="literal">6</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars + <span class="literal">3</span>);
+</pre>
+ <p>
+ This function is typically used to iterate through a UTF-8 encoded string.
+ </p>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::peek_next
+ </h4>
+ <p class="version">
+ Available in version 2.1 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code
+ point for the following sequence without changing the value of the iterator.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t peek_next(octet_iterator it, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: an iterator pointing to the beginning of an UTF-8
+ encoded code point.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = peek_next(w, twochars + <span class="literal">6</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::prior
+ </h4>
+ <p class="version">
+ Available in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t prior(octet_iterator&amp; it, octet_iterator start);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: a bidirectional iterator.<br>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <code>start</code>: an iterator to the beginning of the sequence where the search
+ for the beginning of a code point is performed. It is a
+ safety measure to prevent passing the beginning of the string in the search for a
+ UTF-8 lead octet.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars + <span class=
+"literal">3</span>;
+<span class="keyword">int</span> cp = prior (w, twochars);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This function has two purposes: one is two iterate backwards through a UTF-8
+ encoded string. Note that it is usually a better idea to iterate forward instead,
+ since <code>utf8::next</code> is faster. The second purpose is to find a beginning
+ of a UTF-8 sequence if we have a random position within a string. Note that in that
+ case <code>utf8::prior</code> may not detect an invalid UTF-8 sequence in some scenarios:
+ for instance if there are superfluous trail octets, it will just skip them.
+ </p>
+ <p>
+ <code>it</code> will typically point to the beginning of
+ a code point, and <code>start</code> will point to the
+ beginning of the string to ensure we don't go backwards too far. <code>it</code> is
+ decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
+ beginning with that octet is decoded to a 32 bit representation and returned.
+ </p>
+ <p>
+ In case <code>start</code> is reached before a UTF-8 lead octet is hit, or if an
+ invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
+ exception is thrown.
+ </p>
+ <p>In case <code>start</code> equals <code>it</code>, a <code>not_enough_room</code>
+ exception is thrown.
+ <h4>
+ utf8::previous
+ </h4>
+ <p class="version">
+ Deprecated in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t previous(octet_iterator&amp; it, octet_iterator pass_start);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: a random access iterator.<br>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <code>pass_start</code>: an iterator to the point in the sequence where the search
+ for the beginning of a code point is aborted if no result was reached. It is a
+ safety measure to prevent passing the beginning of the string in the search for a
+ UTF-8 lead octet.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars + <span class=
+"literal">3</span>;
+<span class="keyword">int</span> cp = previous (w, twochars - <span class=
+"literal">1</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ <code>utf8::previous</code> is deprecated, and <code>utf8::prior</code> should
+ be used instead, although the existing code can continue using this function.
+ The problem is the parameter <code>pass_start</code> that points to the position
+ just before the beginning of the sequence. Standard containers don't have the
+ concept of "pass start" and the function can not be used with their iterators.
+ </p>
+ <p>
+ <code>it</code> will typically point to the beginning of
+ a code point, and <code>pass_start</code> will point to the octet just before the
+ beginning of the string to ensure we don't go backwards too far. <code>it</code> is
+ decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
+ beginning with that octet is decoded to a 32 bit representation and returned.
+ </p>
+ <p>
+ In case <code>pass_start</code> is reached before a UTF-8 lead octet is hit, or if an
+ invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
+ exception is thrown
+ </p>
+ <h4>
+ utf8::advance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Advances an iterator by the specified number of code points within an UTF-8
+ sequence.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename distance_type&gt;
+<span class=
+"keyword">void</span> advance (octet_iterator&amp; it, distance_type n, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>distance_type</code>: an integral type convertible to <code>octet_iterator</code>'s difference type.<br>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ nth following code point.<br>
+ <code>n</code>: a positive integer that shows how many code points we want to
+ advance.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars;
+advance (w, <span class="literal">2</span>, twochars + <span class="literal">6</span>);
+assert (w == twochars + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function works only "forward". In case of a negative <code>n</code>, there is
+ no effect.
+ </p>
+ <p>
+ In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::distance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the
+ number of code points between them.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class=
+"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
+ <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
+ point in the sequence we are trying to determine the length. It can be the
+ beginning of a new code point, or not.<br>
+ <span class="return_value">Return value</span> the distance between the iterators,
+ in code points.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+size_t dist = utf8::distance(twochars, twochars + <span class="literal">5</span>);
+assert (dist == <span class="literal">2</span>);
+</pre>
+ <p>
+ This function is used to find the length (in code points) of a UTF-8 encoded
+ string. The reason it is called <em>distance</em>, rather than, say,
+ <em>length</em> is mainly because developers are used that <em>length</em> is an
+ O(1) function. Computing the length of an UTF-8 string is a linear operation, and
+ it looked better to model it after <code>std::distance</code> algorithm.
+ </p>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>last</code> does not point to the past-of-end of a UTF-8 seqence,
+ a <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::utf16to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-16 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, <span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>u16bit_iterator</code>: an input iterator.<br>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned short</span> utf16string[] = {<span class=
+"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
+"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
+"literal">0xdd1e</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf16to8(utf16string, utf16string + <span class=
+"literal">5</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">10</span>);
+</pre>
+ <p>
+ In case of invalid UTF-16 sequence, a <code>utf8::invalid_utf16</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::utf8to16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts an UTF-8 encoded string to UTF-16
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>u16bit_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
+ pass-the-end of the UTF-8 encoded string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-16 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-16 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
+vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
+utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
+"literal">9</span>, back_inserter(utf16result));
+assert (utf16result.size() == <span class="literal">4</span>);
+assert (utf16result[<span class="literal">2</span>] == <span class=
+"literal">0xd834</span>);
+assert (utf16result[<span class="literal">3</span>] == <span class=
+"literal">0xdd1e</span>);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::utf32to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-32 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>u32bit_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">int</span> utf32string[] = {<span class=
+"literal">0x448</span>, <span class="literal">0x65E5</span>, <span class=
+"literal">0x10346</span>, <span class="literal">0</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf32to8(utf32string, utf32string + <span class=
+"literal">3</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">9</span>);
+</pre>
+ <p>
+ In case of invalid UTF-32 string, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::utf8to32
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-8 encoded string to UTF-32.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> u32bit_iterator&gt;
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>u32bit_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
+ to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-32 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-32 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+vector&lt;<span class="keyword">int</span>&gt; utf32result;
+utf8to32(twochars, twochars + <span class=
+"literal">5</span>, back_inserter(utf32result));
+assert (utf32result.size() == <span class="literal">2</span>);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::find_invalid
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Detects an invalid sequence within a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator find_invalid(octet_iterator start, octet_iterator end);
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ test for validity.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
+ for validity.<br>
+ <span class="return_value">Return value</span>: an iterator pointing to the first
+ invalid octet in the UTF-8 string. In case none were found, equals
+ <code>end</code>.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf_invalid[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
+<span class=
+"keyword">char</span>* invalid = find_invalid(utf_invalid, utf_invalid + <span class=
+"literal">6</span>);
+assert (invalid == utf_invalid + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function is typically used to make sure a UTF-8 string is valid before
+ processing it with other functions. It is especially important to call it if before
+ doing any of the <em>unchecked</em> operations on it.
+ </p>
+ <h4>
+ utf8::is_valid
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Checks whether a sequence of octets is a valid UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> is_valid(octet_iterator start, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ test for validity.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
+ for validity.<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ is a valid UTF-8 string; <code>false</code> if not.
+ </p>
+ Example of use:
+<pre>
+<span class="keyword">char</span> utf_invalid[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
+<span class="keyword">bool</span> bvalid = is_valid(utf_invalid, utf_invalid + <span
+class="literal">6</span>);
+assert (bvalid == false);
+</pre>
+ <p>
+ <code>is_valid</code> is a shorthand for <code>find_invalid(start, end) ==
+ end;</code>. You may want to use it to make sure that a byte seqence is a valid
+ UTF-8 string without the need to know where it fails if it is not valid.
+ </p>
+ <h4>
+ utf8::replace_invalid
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> output_iterator&gt;
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> output_iterator&gt;
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>output_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ look for invalid UTF-8 sequences.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to look
+ for invalid UTF-8 sequences.<br>
+ <code>out</code>: An output iterator to the range where the result of replacement
+ is stored.<br>
+ <code>replacement</code>: A Unicode code point for the replacement marker. The
+ version without this parameter assumes the value <code>0xfffd</code><br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the UTF-8 string with replaced invalid sequences.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> invalid_sequence[] = <span class=
+"literal">"a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"</span>;
+vector&lt;<span class="keyword">char</span>&gt; replace_invalid_result;
+replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), <span
+ class="literal">'?'</span>);
+bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+assert (bvalid);
+<span class="keyword">char</span>* fixed_invalid_sequence = <span class=
+"literal">"a????z"</span>;
+assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
+</pre>
+ <p>
+ <code>replace_invalid</code> does not perform in-place replacement of invalid
+ sequences. Rather, it produces a copy of the original string with the invalid
+ sequences replaced with a replacement marker. Therefore, <code>out</code> must not
+ be in the <code>[start, end]</code> range.
+ </p>
+ <p>
+ If <code>end</code> does not point to the past-of-end of a UTF-8 sequence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::starts_with_bom
+ </h4>
+ <p class="version">
+ Available in version 2.3 and later. Relaces deprecated <code>is_bom()</code> function.
+ </p>
+ <p>
+ Checks whether an octet sequence starts with a UTF-8 byte order mark (BOM)
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> starts_with_bom (octet_iterator it, octet_iterator end);
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: beginning of the octet sequence to check<br>
+ <code>end</code>: pass-end of the sequence to check<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ starts with a UTF-8 byte order mark; <code>false</code> if not.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
+"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
+"literal">0xbf</span>};
+<span class="keyword">bool</span> bbom = starts_with_bom(byte_order_mark, byte_order_mark + <span class="keyword">sizeof</span>(byte_order_mark));
+assert (bbom == <span class="literal">true</span>);
+</pre>
+ <p>
+ The typical use of this function is to check the first three bytes of a file. If
+ they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
+ encoded text.
+ </p>
+ <h4>
+ utf8::is_bom
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later. Deprecated in version 2.3. <code>starts_with_bom()</code> should be used
+ instead.
+ </p>
+ <p>
+ Checks whether a sequence of three octets is a UTF-8 byte order mark (BOM)
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> is_bom (octet_iterator it); <span class="comment"> // Deprecated</span>
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: beginning of the 3-octet sequence to check<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ is UTF-8 byte order mark; <code>false</code> if not.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
+"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
+"literal">0xbf</span>};
+<span class="keyword">bool</span> bbom = is_bom(byte_order_mark);
+assert (bbom == <span class="literal">true</span>);
+</pre>
+ <p>
+ The typical use of this function is to check the first three bytes of a file. If
+ they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
+ encoded text.
+ </p>
+ <p>
+ If a sequence is
+ shorter than three bytes, an invalid iterator will be dereferenced. Therefore, this function is deprecated
+ in favor of <code>starts_with_bom()</code>that takes the end of sequence as an argument.
+ </p>
+ <h3 id="typesutf8">
+ Types From utf8 Namespace
+ </h3>
+ <h4>utf8::exception
+ </h4>
+ <p class="version">
+ Available in version 2.3 and later.
+ </p>
+ <p>
+ Base class for the exceptions thrown by UTF CPP library functions.
+ </p>
+<pre>
+<span class="keyword">class</span> exception : <span class="keyword">public</span> std::exception {};
+</pre>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">try</span> {
+ code_that_uses_utf_cpp_library();
+}
+<span class="keyword">catch</span>(<span class="keyword">const</span> utf8::exception&amp; utfcpp_ex) {
+ cerr &lt;&lt; utfcpp_ex.what();
+}
+</pre>
+
+ <h4>utf8::invalid_code_point
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>advance</code> and <code>next</code> if an UTF-8 sequence represents and invalid code point.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_code_point : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint32_t code_point() <span class="keyword">const</span>;
+};
+
+</pre>
+ <p>
+ Member function <code>code_point()</code> can be used to determine the invalid code point that
+ caused the exception to be thrown.
+ </p>
+ <h4>utf8::invalid_utf8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>next</code> and <code>prior</code> if an invalid UTF-8 sequence
+ is detected during decoding.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_utf8 : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint8_t utf8_octet() <span class="keyword">const</span>;
+};
+</pre>
+
+ <p>
+ Member function <code>utf8_octet()</code> can be used to determine the beginning of the byte
+ sequence that caused the exception to be thrown.
+ </p>
+</pre>
+ <h4>utf8::invalid_utf16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP function <code>utf16to8</code> if an invalid UTF-16 sequence
+ is detected during decoding.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_utf16 : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint16_t utf16_word() <span class="keyword">const</span>;
+};
+</pre>
+
+ <p>
+ Member function <code>utf16_word()</code> can be used to determine the UTF-16 code unit
+ that caused the exception to be thrown.
+ </p>
+ <h4>utf8::not_enough_room
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>next</code> if the end of the decoded UTF-8 sequence
+ was reached before the code point was decoded.
+ </p>
+
+<pre>
+<span class="keyword">class</span> not_enough_room : <span class="keyword">public</span> exception {};
+</pre>
+ <h4>
+ utf8::iterator
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Adapts the underlying octet iterator to iterate over the sequence of code points,
+ rather than raw octets.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
+<span class="keyword">class</span> iterator;
+</pre>
+
+ <h5>Member functions</h5>
+ <dl>
+ <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
+ constructed with its default constructor.
+ <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it,
+ const octet_iterator&amp; range_start,
+ const octet_iterator&amp; range_end);</code> <dd> a constructor
+ that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
+ and sets the range in which the iterator is considered valid.
+ <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
+ underlying <code>octet_iterator</code>.
+ <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
+ the underlying <code>octet_iterator</code> is pointing to and returns the code point.
+ <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are equal.
+ <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are not equal.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
+ the iterator to the next UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
+ the iterator to the previous UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+ </dl>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; it(threechars, threechars, threechars + <span class="literal">9</span>);
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; it2 = it;
+assert (it2 == it);
+assert (*it == <span class="literal">0x10346</span>);
+assert (*(++it) == <span class="literal">0x65e5</span>);
+assert ((*it++) == <span class="literal">0x65e5</span>);
+assert (*it == <span class="literal">0x0448</span>);
+assert (it != it2);
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; endit (threechars + <span class="literal">9</span>, threechars, threechars + <span class="literal">9</span>);
+assert (++it == endit);
+assert (*(--it) == <span class="literal">0x0448</span>);
+assert ((*it--) == <span class="literal">0x0448</span>);
+assert (*it == <span class="literal">0x65e5</span>);
+assert (--it == utf8::iterator&lt;<span class="keyword">char</span>*&gt;(threechars, threechars, threechars + <span class="literal">9</span>));
+assert (*it == <span class="literal">0x10346</span>);
+</pre>
+ <p>
+ The purpose of <code>utf8::iterator</code> adapter is to enable easy iteration as well as the use of STL
+ algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of
+ <code>utf8::next()</code> and <code>utf8::prior()</code> functions.
+ </p>
+ <p>
+ Note that <code>utf8::iterator</code> adapter is a checked iterator. It operates on the range specified in
+ the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators
+ require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically,
+ the range will be determined by sequence container functions <code>begin</code> and <code>end</code>, i.e.:
+ </p>
+<pre>
+std::string s = <span class="literal">"example"</span>;
+utf8::iterator i (s.begin(), s.begin(), s.end());
+</pre>
+ <h3 id="fununchecked">
+ Functions From utf8::unchecked Namespace
+ </h3>
+ <h4>
+ utf8::unchecked::append
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
+ to a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator append(uint32_t cp, octet_iterator result);
+
+</pre>
+ <p>
+ <code>cp</code>: A 32 bit integer representing a code point to append to the
+ sequence.<br>
+ <code>result</code>: An output iterator to the place in the sequence where to
+ append the code point.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the newly appended sequence.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
+class="literal">0</span>,<span class="literal">0</span>,<span class=
+"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
+<span class="keyword">unsigned char</span>* end = unchecked::append(<span class=
+"literal">0x0448</span>, u);
+assert (u[<span class="literal">0</span>] == <span class=
+"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
+"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
+"literal">0</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::append</code>. It does not
+ check for validity of the supplied code point, and may produce an invalid UTF-8
+ sequence.
+ </p>
+ <h4>
+ utf8::unchecked::next
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point
+ and moves the iterator to the next position.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t next(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ beginning of the next code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = unchecked::next(w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars + <span class="literal">3</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::next</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::peek_next
+ </h4>
+ <p class="version">
+ Available in version 2.1 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t peek_next(octet_iterator it);
+
+</pre>
+ <p>
+ <code>it</code>: an iterator pointing to the beginning of an UTF-8
+ encoded code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = unchecked::peek_next(w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::peek_next</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::prior
+ </h4>
+ <p class="version">
+ Available in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t prior(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
+<span class="keyword">int</span> cp = unchecked::prior (w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::prior</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::previous (deprecated, see utf8::unchecked::prior)
+ </h4>
+ <p class="version">
+ Deprecated in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t previous(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
+<span class="keyword">int</span> cp = unchecked::previous (w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ The reason this function is deprecated is just the consistency with the "checked"
+ versions, where <code>prior</code> should be used instead of <code>previous</code>.
+ In fact, <code>unchecked::previous</code> behaves exactly the same as <code>
+ unchecked::prior</code>
+ </p>
+ <p>
+ This is a faster but less safe version of <code>utf8::previous</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::advance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Advances an iterator by the specified number of code points within an UTF-8
+ sequence.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename distance_type&gt;
+<span class="keyword">void</span> advance (octet_iterator&amp; it, distance_type n);
+
+</pre>
+ <p>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ nth following code point.<br>
+ <code>n</code>: a positive integer that shows how many code points we want to
+ advance.<br>
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+unchecked::advance (w, <span class="literal">2</span>);
+assert (w == twochars + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function works only "forward". In case of a negative <code>n</code>, there is
+ no effect.
+ </p>
+ <p>
+ This is a faster but less safe version of <code>utf8::advance</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::distance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the
+ number of code points between them.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class=
+"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
+</pre>
+ <p>
+ <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
+ <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
+ point in the sequence we are trying to determine the length. It can be the
+ beginning of a new code point, or not.<br>
+ <span class="return_value">Return value</span> the distance between the iterators,
+ in code points.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+size_t dist = utf8::unchecked::distance(twochars, twochars + <span class=
+"literal">5</span>);
+assert (dist == <span class="literal">2</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::distance</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf16to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-16 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, <span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned short</span> utf16string[] = {<span class=
+"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
+"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
+"literal">0xdd1e</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+unchecked::utf16to8(utf16string, utf16string + <span class=
+"literal">5</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">10</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf16to8</code>. It does not
+ check for validity of the supplied UTF-16 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf8to16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts an UTF-8 encoded string to UTF-16
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
+ pass-the-end of the UTF-8 encoded string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-16 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-16 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
+vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
+unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
+"literal">9</span>, back_inserter(utf16result));
+assert (utf16result.size() == <span class="literal">4</span>);
+assert (utf16result[<span class="literal">2</span>] == <span class=
+"literal">0xd834</span>);
+assert (utf16result[<span class="literal">3</span>] == <span class=
+"literal">0xdd1e</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf8to16</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf32to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-32 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> u32bit_iterator&gt;
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">int</span> utf32string[] = {<span class=
+"literal">0x448</span>, <span class="literal">0x65e5</span>, <span class=
+"literal">0x10346</span>, <span class="literal">0</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf32to8(utf32string, utf32string + <span class=
+"literal">3</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">9</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf32to8</code>. It does not
+ check for validity of the supplied UTF-32 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf8to32
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-8 encoded string to UTF-32.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
+ to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-32 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-32 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+vector&lt;<span class="keyword">int</span>&gt; utf32result;
+unchecked::utf8to32(twochars, twochars + <span class=
+"literal">5</span>, back_inserter(utf32result));
+assert (utf32result.size() == <span class="literal">2</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf8to32</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h3 id="typesunchecked">
+ Types From utf8::unchecked Namespace
+ </h3>
+ <h4>
+ utf8::iterator
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Adapts the underlying octet iterator to iterate over the sequence of code points,
+ rather than raw octets.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
+<span class="keyword">class</span> iterator;
+</pre>
+
+ <h5>Member functions</h5>
+ <dl>
+ <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
+ constructed with its default constructor.
+ <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it);
+ </code> <dd> a constructor
+ that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
+ <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
+ underlying <code>octet_iterator</code>.
+ <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
+ the underlying <code>octet_iterator</code> is pointing to and returns the code point.
+ <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are equal.
+ <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are not equal.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
+ the iterator to the next UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
+ the iterator to the previous UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+ </dl>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
+utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it(threechars);
+utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it2 = un_it;
+assert (un_it2 == un_it);
+assert (*un_it == <span class="literal">0x10346</span>);
+assert (*(++un_it) == <span class="literal">0x65e5</span>);
+assert ((*un_it++) == <span class="literal">0x65e5</span>);
+assert (*un_it == <span class="literal">0x0448</span>);
+assert (un_it != un_it2);
+utf8::::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_endit (threechars + <span class="literal">9</span>);
+assert (++un_it == un_endit);
+assert (*(--un_it) == <span class="literal">0x0448</span>);
+assert ((*un_it--) == <span class="literal">0x0448</span>);
+assert (*un_it == <span class="literal">0x65e5</span>);
+assert (--un_it == utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt;(threechars));
+assert (*un_it == <span class="literal">0x10346</span>);
+</pre>
+ <p>
+ This is an unchecked version of <code>utf8::iterator</code>. It is faster in many cases, but offers
+ no validity or range checks.
+ </p>
+ <h2 id="points">
+ Points of interest
+ </h2>
+ <h4>
+ Design goals and decisions
+ </h4>
+ <p>
+ The library was designed to be:
+ </p>
+ <ol>
+ <li>
+ Generic: for better or worse, there are many C++ string classes out there, and
+ the library should work with as many of them as possible.
+ </li>
+ <li>
+ Portable: the library should be portable both accross different platforms and
+ compilers. The only non-portable code is a small section that declares unsigned
+ integers of different sizes: three typedefs. They can be changed by the users of
+ the library if they don't match their platform. The default setting should work
+ for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives.
+ </li>
+ <li>
+ Lightweight: follow the "pay only for what you use" guideline.
+ </li>
+ <li>
+ Unintrusive: avoid forcing any particular design or even programming style on the
+ user. This is a library, not a framework.
+ </li>
+ </ol>
+ <h4>
+ Alternatives
+ </h4>
+ <p>
+ In case you want to look into other means of working with UTF-8 strings from C++,
+ here is the list of solutions I am aware of:
+ </p>
+ <ol>
+ <li>
+ <a href="http://icu.sourceforge.net/">ICU Library</a>. It is very powerful,
+ complete, feature-rich, mature, and widely used. Also big, intrusive,
+ non-generic, and doesn't play well with the Standard Library. I definitelly
+ recommend looking at ICU even if you don't plan to use it.
+ </li>
+ <li>
+ C++11 language and library features. Still far from complete, and not widely
+ supported by compiler vendors.
+ </li>
+ <li>
+ <a href=
+ "http://www.gtkmm.org/gtkmm2/docs/tutorial/html/ch03s04.html">Glib::ustring</a>.
+ A class specifically made to work with UTF-8 strings, and also feel like
+ <code>std::string</code>. If you prefer to have yet another string class in your
+ code, it may be worth a look. Be aware of the licensing issues, though.
+ </li>
+ <li>
+ Platform dependent solutions: Windows and POSIX have functions to convert strings
+ from one encoding to another. That is only a subset of what my library offers,
+ but if that is all you need it may be good enough.
+ </li>
+ </ol>
+ <h2 id="links">
+ Links
+ </h2>
+ <ol>
+ <li>
+ <a href="http://www.unicode.org/">The Unicode Consortium</a>.
+ </li>
+ <li>
+ <a href="http://icu.sourceforge.net/">ICU Library</a>.
+ </li>
+ <li>
+ <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8 at Wikipedia</a>
+ </li>
+ <li>
+ <a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html">UTF-8 and Unicode FAQ for
+ Unix/Linux</a>
+ </li>
+ </ol>
+ </body>
+</html>
diff --git a/thirdparty/assimp/include/assimp/.editorconfig b/thirdparty/assimp/include/assimp/.editorconfig
deleted file mode 100644
index 9ea66423ad..0000000000
--- a/thirdparty/assimp/include/assimp/.editorconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-# See <http://EditorConfig.org> for details
-
-[*.{h,hpp,inl}]
-end_of_line = lf
-insert_final_newline = true
-trim_trailing_whitespace = true
-indent_size = 4
-indent_style = space
diff --git a/thirdparty/assimp/include/assimp/BaseImporter.h b/thirdparty/assimp/include/assimp/BaseImporter.h
index 48dfc8ed8b..55f7fe3754 100644
--- a/thirdparty/assimp/include/assimp/BaseImporter.h
+++ b/thirdparty/assimp/include/assimp/BaseImporter.h
@@ -48,8 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <set>
+#include <map>
#include <assimp/types.h>
#include <assimp/ProgressHandler.hpp>
+#include <assimp/ai_assert.h>
struct aiScene;
struct aiImporterDesc;
@@ -80,6 +82,10 @@ class IOStream;
class ASSIMP_API BaseImporter {
friend class Importer;
+private:
+ /* Pushes state into importer for the importer scale */
+ virtual void UpdateImporterScale( Importer* pImp );
+
public:
/** Constructor to be privately used by #Importer */
@@ -132,7 +138,7 @@ public:
* a suitable response to the caller.
*/
aiScene* ReadFile(
- const Importer* pImp,
+ Importer* pImp,
const std::string& pFile,
IOSystem* pIOHandler
);
@@ -161,14 +167,65 @@ public:
* some loader features. Importers must provide this information. */
virtual const aiImporterDesc* GetInfo() const = 0;
+ /**
+ * Will be called only by scale process when scaling is requested.
+ */
+ virtual void SetFileScale(double scale)
+ {
+ fileScale = scale;
+ }
+
+ virtual double GetFileScale() const
+ {
+ return fileScale;
+ }
+
+ enum ImporterUnits {
+ M,
+ MM,
+ CM,
+ INCHES,
+ FEET
+ };
+
+ /**
+ * Assimp Importer
+ * unit conversions available
+ * if you need another measurment unit add it below.
+ * it's currently defined in assimp that we prefer meters.
+ * */
+ std::map<ImporterUnits, double> importerUnits = {
+ {ImporterUnits::M, 1},
+ {ImporterUnits::CM, 0.01},
+ {ImporterUnits::MM, 0.001},
+ {ImporterUnits::INCHES, 0.0254},
+ {ImporterUnits::FEET, 0.3048}
+ };
+
+ virtual void SetApplicationUnits( const ImporterUnits& unit )
+ {
+ importerScale = importerUnits[unit];
+ applicationUnits = unit;
+ }
+
+ virtual const ImporterUnits& GetApplicationUnits()
+ {
+ return applicationUnits;
+ }
+
// -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by
* #GetInfo and insert all file extensions into the given set.
* @param extension set to collect file extensions in*/
void GetExtensionList(std::set<std::string>& extensions);
+
+protected:
+ ImporterUnits applicationUnits = ImporterUnits::M;
+ double importerScale = 1.0;
+ double fileScale = 1.0;
+
-protected:
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure. The
diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp
index bf0096e7e9..ea0303e804 100644
--- a/thirdparty/assimp/include/assimp/Exporter.hpp
+++ b/thirdparty/assimp/include/assimp/Exporter.hpp
@@ -190,7 +190,7 @@ public:
* @note Use aiCopyScene() to get a modifiable copy of a previously
* imported scene. */
const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId,
- unsigned int pPreprocessing = 0u, const ExportProperties* = nullptr);
+ unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h
index ca30ce13b0..6b9574fc67 100644
--- a/thirdparty/assimp/include/assimp/ParsingUtils.h
+++ b/thirdparty/assimp/include/assimp/ParsingUtils.h
@@ -196,8 +196,7 @@ bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) {
// ---------------------------------------------------------------------------------
template <class char_t>
-AI_FORCE_INLINE bool IsNumeric( char_t in)
-{
+AI_FORCE_INLINE bool IsNumeric( char_t in) {
return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
}
diff --git a/thirdparty/assimp/include/assimp/aabb.h b/thirdparty/assimp/include/assimp/aabb.h
new file mode 100644
index 0000000000..a20f317424
--- /dev/null
+++ b/thirdparty/assimp/include/assimp/aabb.h
@@ -0,0 +1,76 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+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.
+---------------------------------------------------------------------------
+*/
+
+#pragma once
+#ifndef AI_AABB_H_INC
+#define AI_AABB_H_INC
+
+#include <assimp/vector3.h>
+
+struct aiAABB {
+ C_STRUCT aiVector3D mMin;
+ C_STRUCT aiVector3D mMax;
+
+#ifdef __cplusplus
+
+ aiAABB()
+ : mMin()
+ , mMax() {
+ // empty
+ }
+
+ aiAABB(const aiVector3D &min, const aiVector3D &max )
+ : mMin(min)
+ , mMax(max) {
+ // empty
+ }
+
+ ~aiAABB() {
+ // empty
+ }
+
+#endif
+};
+
+
+#endif
diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h
index 99daf69934..e573eea5d1 100644
--- a/thirdparty/assimp/include/assimp/camera.h
+++ b/thirdparty/assimp/include/assimp/camera.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -60,7 +58,7 @@ extern "C" {
*
* Cameras have a representation in the node graph and can be animated.
* An important aspect is that the camera itself is also part of the
- * scenegraph. This means, any values such as the look-at vector are not
+ * scene-graph. This means, any values such as the look-at vector are not
* *absolute*, they're <b>relative</b> to the coordinate system defined
* by the node which corresponds to the camera. This allows for camera
* animations. For static cameras parameters like the 'look-at' or 'up' vectors
@@ -162,7 +160,6 @@ struct aiCamera
*/
float mClipPlaneFar;
-
/** Screen aspect ratio.
*
* This is the ration between the width and the height of the
diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl
index 3192d55f39..afa53dcb5b 100644
--- a/thirdparty/assimp/include/assimp/color4.inl
+++ b/thirdparty/assimp/include/assimp/color4.inl
@@ -85,6 +85,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
@@ -100,6 +102,8 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
diff --git a/thirdparty/assimp/include/assimp/config.h.in b/thirdparty/assimp/include/assimp/config.h.in
index a37ff0b8c8..3a6379bf40 100644
--- a/thirdparty/assimp/include/assimp/config.h.in
+++ b/thirdparty/assimp/include/assimp/config.h.in
@@ -651,13 +651,28 @@ enum aiComponent
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will use the legacy embedded texture naming.
-*
-* The default value is false (0)
-* Property type: bool
-*/
+ *
+ * The default value is false (0)
+ * Property type: bool
+ */
#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
-
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the importer shall not remove empty bones.
+ *
+ * Empty bone are often used to define connections for other models.
+ */
+#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
+ "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+ "AI_CONFIG_FBX_CONVERT_TO_M"
+
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
@@ -966,8 +981,12 @@ enum aiComponent
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
-/**
- *
+/** @brief Specifies whether the assimp export shall be able to export point clouds
+ *
+ * When this flag is not defined the render data has to contain valid faces.
+ * Point clouds are only a collection of vertices which have nor spatial organization
+ * by a face and the validation process will remove them. Enabling this feature will
+ * switch off the flag and enable the functionality to export pure point clouds.
*/
#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
@@ -980,6 +999,13 @@ enum aiComponent
# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
#endif // !! AI_DEBONE_THRESHOLD
+#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_APP_SCALE_KEY)
+# define AI_CONFIG_APP_SCALE_KEY 1.0
+#endif // AI_CONFIG_APP_SCALE_KEY
+
+
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h
index 4a177e3c3e..05a5e3fd4b 100644
--- a/thirdparty/assimp/include/assimp/defs.h
+++ b/thirdparty/assimp/include/assimp/defs.h
@@ -122,7 +122,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* OPTIMIZEANIMS
* OPTIMIZEGRAPH
* GENENTITYMESHES
- * FIXTEXTUREPATHS */
+ * FIXTEXTUREPATHS
+ * GENBOUNDINGBOXES */
//////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
@@ -214,10 +215,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
-#error Currently, Borland is unsupported. Feel free to port Assimp.
-
-// "W8059 Packgröße der Struktur geändert"
-
+# error Currently, Borland is unsupported. Feel free to port Assimp.
#endif
@@ -243,10 +241,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef double ai_real;
typedef signed long long int ai_int;
typedef unsigned long long int ai_uint;
+#ifndef ASSIMP_AI_REAL_TEXT_PRECISION
+#define ASSIMP_AI_REAL_TEXT_PRECISION 16
+#endif // ASSIMP_AI_REAL_TEXT_PRECISION
#else // ASSIMP_DOUBLE_PRECISION
typedef float ai_real;
typedef signed int ai_int;
typedef unsigned int ai_uint;
+#ifndef ASSIMP_AI_REAL_TEXT_PRECISION
+#define ASSIMP_AI_REAL_TEXT_PRECISION 8
+#endif // ASSIMP_AI_REAL_TEXT_PRECISION
#endif // ASSIMP_DOUBLE_PRECISION
//////////////////////////////////////////////////////////////////////////
@@ -267,6 +271,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_DEG_TO_RAD(x) ((x)*(ai_real)0.0174532925)
#define AI_RAD_TO_DEG(x) ((x)*(ai_real)57.2957795)
+/* Numerical limits */
+static const ai_real ai_epsilon = (ai_real) 0.00001;
+
/* Support for big-endian builds */
#if defined(__BYTE_ORDER__)
# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@@ -293,11 +300,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _MSC_VER
# define AI_NO_EXCEPT noexcept
#else
-# if (_MSC_VER == 1915 )
+# if (_MSC_VER >= 1915 )
# define AI_NO_EXCEPT noexcept
# else
# define AI_NO_EXCEPT
# endif
-#endif
+#endif // _MSC_VER
#endif // !! AI_DEFINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/irrXMLWrapper.h b/thirdparty/assimp/include/assimp/irrXMLWrapper.h
deleted file mode 100644
index ec8ee7c76e..0000000000
--- a/thirdparty/assimp/include/assimp/irrXMLWrapper.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef INCLUDED_AI_IRRXML_WRAPPER
-#define INCLUDED_AI_IRRXML_WRAPPER
-
-// some long includes ....
-#include <irrXML.h>
-#include "IOStream.hpp"
-#include "BaseImporter.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-/** @brief Utility class to make IrrXML work together with our custom IO system
- * See the IrrXML docs for more details.
- *
- * Construct IrrXML-Reader in BaseImporter::InternReadFile():
- * @code
- * // open the file
- * std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
- * if( file.get() == NULL) {
- * throw DeadlyImportError( "Failed to open file " + pFile + ".");
- * }
- *
- * // generate a XML reader for it
- * std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- * if( !mReader) {
- * ThrowException( "xxxx: Unable to open file.");
- * }
- * @endcode
- **/
-class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack {
-public:
-
- // ----------------------------------------------------------------------------------
- //! Construction from an existing IOStream
- explicit CIrrXML_IOStreamReader(IOStream* _stream)
- : stream (_stream)
- , t (0)
- {
-
- // Map the buffer into memory and convert it to UTF8. IrrXML provides its
- // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
- // it is not suitable for our purposes and we have to do it BEFORE IrrXML
- // gets the buffer. Sadly, this forces us to map the whole file into
- // memory.
-
- data.resize(stream->FileSize());
- stream->Read(&data[0],data.size(),1);
-
- // Remove null characters from the input sequence otherwise the parsing will utterly fail
- unsigned int size = 0;
- unsigned int size_max = static_cast<unsigned int>(data.size());
- for(unsigned int i = 0; i < size_max; i++) {
- if(data[i] != '\0') {
- data[size++] = data[i];
- }
- }
- data.resize(size);
-
- BaseImporter::ConvertToUTF8(data);
- }
-
- // ----------------------------------------------------------------------------------
- //! Virtual destructor
- virtual ~CIrrXML_IOStreamReader() {}
-
- // ----------------------------------------------------------------------------------
- //! Reads an amount of bytes from the file.
- /** @param buffer: Pointer to output buffer.
- * @param sizeToRead: Amount of bytes to read
- * @return Returns how much bytes were read. */
- virtual int read(void* buffer, int sizeToRead) {
- if(sizeToRead<0) {
- return 0;
- }
- if(t+sizeToRead>data.size()) {
- sizeToRead = static_cast<int>(data.size()-t);
- }
-
- memcpy(buffer,&data.front()+t,sizeToRead);
-
- t += sizeToRead;
- return sizeToRead;
- }
-
- // ----------------------------------------------------------------------------------
- //! Returns size of file in bytes
- virtual int getSize() {
- return (int)data.size();
- }
-
-private:
- IOStream* stream;
- std::vector<char> data;
- size_t t;
-
-}; // ! class CIrrXML_IOStreamReader
-
-} // ! Assimp
-
-#endif // !! INCLUDED_AI_IRRXML_WRAPPER
diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h
index 4b5a1293dd..206eb2a2b0 100644
--- a/thirdparty/assimp/include/assimp/material.h
+++ b/thirdparty/assimp/include/assimp/material.h
@@ -196,34 +196,40 @@ enum aiTextureType
* (#aiMaterialProperty::mSemantic) for all material properties
* *not* related to textures.
*/
- aiTextureType_NONE = 0x0,
+ aiTextureType_NONE = 0,
+
+ /** LEGACY API MATERIALS
+ * Legacy refers to materials which
+ * Were originally implemented in the specifications around 2000.
+ * These must never be removed, as most engines support them.
+ */
/** The texture is combined with the result of the diffuse
* lighting equation.
*/
- aiTextureType_DIFFUSE = 0x1,
+ aiTextureType_DIFFUSE = 1,
/** The texture is combined with the result of the specular
* lighting equation.
*/
- aiTextureType_SPECULAR = 0x2,
+ aiTextureType_SPECULAR = 2,
/** The texture is combined with the result of the ambient
* lighting equation.
*/
- aiTextureType_AMBIENT = 0x3,
+ aiTextureType_AMBIENT = 3,
/** The texture is added to the result of the lighting
* calculation. It isn't influenced by incoming light.
*/
- aiTextureType_EMISSIVE = 0x4,
+ aiTextureType_EMISSIVE = 4,
/** The texture is a height map.
*
* By convention, higher gray-scale values stand for
* higher elevations from the base height.
*/
- aiTextureType_HEIGHT = 0x5,
+ aiTextureType_HEIGHT = 5,
/** The texture is a (tangent space) normal-map.
*
@@ -231,7 +237,7 @@ enum aiTextureType
* normal maps. Assimp does (intentionally) not
* distinguish here.
*/
- aiTextureType_NORMALS = 0x6,
+ aiTextureType_NORMALS = 6,
/** The texture defines the glossiness of the material.
*
@@ -240,21 +246,21 @@ enum aiTextureType
* function defined to map the linear color values in the
* texture to a suitable exponent. Have fun.
*/
- aiTextureType_SHININESS = 0x7,
+ aiTextureType_SHININESS = 7,
/** The texture defines per-pixel opacity.
*
* Usually 'white' means opaque and 'black' means
* 'transparency'. Or quite the opposite. Have fun.
*/
- aiTextureType_OPACITY = 0x8,
+ aiTextureType_OPACITY = 8,
/** Displacement texture
*
* The exact purpose and format is application-dependent.
* Higher color values stand for higher vertex displacements.
*/
- aiTextureType_DISPLACEMENT = 0x9,
+ aiTextureType_DISPLACEMENT = 9,
/** Lightmap texture (aka Ambient Occlusion)
*
@@ -263,14 +269,28 @@ enum aiTextureType
* scaling value for the final color value of a pixel. Its
* intensity is not affected by incoming light.
*/
- aiTextureType_LIGHTMAP = 0xA,
+ aiTextureType_LIGHTMAP = 10,
/** Reflection texture
*
* Contains the color of a perfect mirror reflection.
* Rarely used, almost never for real-time applications.
*/
- aiTextureType_REFLECTION = 0xB,
+ aiTextureType_REFLECTION = 11,
+
+ /** PBR Materials
+ * PBR definitions from maya and other modelling packages now use this standard.
+ * This was originally introduced around 2012.
+ * Support for this is in game engines like Godot, Unreal or Unity3D.
+ * Modelling packages which use this are very common now.
+ */
+
+ aiTextureType_BASE_COLOR = 12,
+ aiTextureType_NORMAL_CAMERA = 13,
+ aiTextureType_EMISSION_COLOR = 14,
+ aiTextureType_METALNESS = 15,
+ aiTextureType_DIFFUSE_ROUGHNESS = 16,
+ aiTextureType_AMBIENT_OCCLUSION = 17,
/** Unknown texture
*
@@ -278,7 +298,7 @@ enum aiTextureType
* above is considered to be 'unknown'. It is still imported,
* but is excluded from any further post-processing.
*/
- aiTextureType_UNKNOWN = 0xC,
+ aiTextureType_UNKNOWN = 18,
#ifndef SWIG
diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h
index 36f3ed2afd..f1628f1f54 100644
--- a/thirdparty/assimp/include/assimp/mesh.h
+++ b/thirdparty/assimp/include/assimp/mesh.h
@@ -48,7 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MESH_H_INC
#define AI_MESH_H_INC
-#include "types.h"
+#include <assimp/types.h>
+#include <assimp/aabb.h>
#ifdef __cplusplus
extern "C" {
@@ -714,6 +715,11 @@ struct aiMesh
* Method of morphing when animeshes are specified.
*/
unsigned int mMethod;
+
+ /**
+ *
+ */
+ C_STRUCT aiAABB mAABB;
#ifdef __cplusplus
@@ -735,7 +741,8 @@ struct aiMesh
, mMaterialIndex( 0 )
, mNumAnimMeshes( 0 )
, mAnimMeshes(nullptr)
- , mMethod( 0 ) {
+ , mMethod( 0 )
+ , mAABB() {
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
mNumUVComponents[a] = 0;
mTextureCoords[a] = nullptr;
diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h
index c23a5490a5..2a74414216 100644
--- a/thirdparty/assimp/include/assimp/postprocess.h
+++ b/thirdparty/assimp/include/assimp/postprocess.h
@@ -438,7 +438,7 @@ enum aiPostProcessSteps
aiProcess_FindInstances = 0x100000,
// -------------------------------------------------------------------------
- /** <hr>A postprocessing step to reduce the number of meshes.
+ /** <hr>A post-processing step to reduce the number of meshes.
*
* This will, in fact, reduce the number of draw calls.
*
@@ -450,7 +450,7 @@ enum aiPostProcessSteps
// -------------------------------------------------------------------------
- /** <hr>A postprocessing step to optimize the scene hierarchy.
+ /** <hr>A post-processing step to optimize the scene hierarchy.
*
* Nodes without animations, bones, lights or cameras assigned are
* collapsed and joined.
@@ -514,7 +514,7 @@ enum aiPostProcessSteps
// -------------------------------------------------------------------------
/** <hr>This step splits meshes with many bones into sub-meshes so that each
- * su-bmesh has fewer or as many bones as a given limit.
+ * sub-mesh has fewer or as many bones as a given limit.
*/
aiProcess_SplitByBoneCount = 0x2000000,
@@ -541,7 +541,7 @@ enum aiPostProcessSteps
* global scaling from your importer settings like in FBX. Use the flag
* AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY from the global property table to configure this.
*
- * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to setup the global scaing factor.
+ * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to setup the global scaling factor.
*/
aiProcess_GlobalScale = 0x8000000,
@@ -574,6 +574,11 @@ enum aiPostProcessSteps
* This process gives sense back to aiProcess_JoinIdenticalVertices
*/
aiProcess_DropNormals = 0x40000000,
+
+ // -------------------------------------------------------------------------
+ /**
+ */
+ aiProcess_GenBoundingBoxes = 0x80000000
};
diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h
index de0239702d..2667db85b3 100644
--- a/thirdparty/assimp/include/assimp/scene.h
+++ b/thirdparty/assimp/include/assimp/scene.h
@@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "metadata.h"
#ifdef __cplusplus
+# include <cstdlib>
extern "C" {
#endif
@@ -389,6 +390,14 @@ struct aiScene
//! Returns an embedded texture
const aiTexture* GetEmbeddedTexture(const char* filename) const {
+ // lookup using texture ID (if referenced like: "*1", "*2", etc.)
+ if ('*' == *filename) {
+ int index = std::atoi(filename + 1);
+ if (0 > index || mNumTextures <= static_cast<unsigned>(index))
+ return nullptr;
+ return mTextures[index];
+ }
+ // lookup using filename
const char* shortFilename = GetShortFilename(filename);
for (unsigned int i = 0; i < mNumTextures; i++) {
const char* shortTextureFilename = GetShortFilename(mTextures[i]->mFilename.C_Str());
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/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
index fad9a37a9a..62fbd1b72d 100644
--- a/thirdparty/jpeg-compressor/jpgd.cpp
+++ b/thirdparty/jpeg-compressor/jpgd.cpp
@@ -29,6 +29,10 @@
#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
+// TODO: Move to header and use these constants when declaring the arrays.
+#define JPGD_HUFF_TREE_MAX_LENGTH 512
+#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
+
namespace jpgd {
static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
@@ -491,8 +495,9 @@ inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
// Decodes a Huffman encoded symbol.
inline int jpeg_decoder::huff_decode(huff_tables *pH)
{
- int symbol;
+ JPGD_ASSERT(pH);
+ int symbol;
// Check first 8-bits: do we have a complete symbol?
if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
{
@@ -500,14 +505,19 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH)
int ofs = 23;
do
{
- symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ symbol = pH->tree[idx];
ofs--;
} while (symbol < 0);
get_bits_no_markers(8 + (23 - ofs));
}
else
+ {
+ JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
get_bits_no_markers(pH->code_size[symbol]);
+ }
return symbol;
}
@@ -517,6 +527,8 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
{
int symbol;
+ JPGD_ASSERT(pH);
+
// Check first 8-bits: do we have a complete symbol?
if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
{
@@ -524,7 +536,9 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
int ofs = 23;
do
{
- symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ symbol = pH->tree[idx];
ofs--;
} while (symbol < 0);
@@ -1495,6 +1509,12 @@ void jpeg_decoder::fix_in_buffer()
void jpeg_decoder::transform_mcu(int mcu_row)
{
jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
+ if (m_freq_domain_chroma_upsample) {
+ JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row);
+ }
+ else {
+ JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row);
+ }
uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
@@ -1650,6 +1670,7 @@ void jpeg_decoder::load_next_row()
for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
{
component_id = m_mcu_org[mcu_block];
+ JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
q = m_quant[m_comp_quant[component_id]];
p = m_pMCU_coefficients + 64 * mcu_block;
@@ -1770,6 +1791,7 @@ void jpeg_decoder::decode_next_row()
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
{
int component_id = m_mcu_org[mcu_block];
+ JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
int r, s;
@@ -2229,7 +2251,10 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
for (l = 1; l <= 16; l++)
{
for (i = 1; i <= m_huff_num[index][l]; i++)
+ {
+ JPGD_ASSERT(p < 257);
huffsize[p++] = static_cast<uint8>(l);
+ }
}
huffsize[p] = 0;
@@ -2244,6 +2269,7 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
{
while (huffsize[p] == si)
{
+ JPGD_ASSERT(p < 257);
huffcode[p++] = code;
code++;
}
@@ -2275,7 +2301,8 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
for (l = 1 << (8 - code_size); l > 0; l--)
{
- JPGD_ASSERT(i < 256);
+ JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
pH->look_up[code] = i;
@@ -2325,16 +2352,19 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
if ((code & 0x8000) == 0)
currententry--;
- if (pH->tree[-currententry - 1] == 0)
+ unsigned int idx = -currententry - 1;
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ if (pH->tree[idx] == 0)
{
- pH->tree[-currententry - 1] = nextfreeentry;
+ pH->tree[idx] = nextfreeentry;
currententry = nextfreeentry;
nextfreeentry -= 2;
}
- else
- currententry = pH->tree[-currententry - 1];
+ else {
+ currententry = pH->tree[idx];
+ }
code <<= 1;
}
@@ -2636,7 +2666,9 @@ void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int
for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
{
- s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
r = s >> 4;
s &= 15;
@@ -2679,7 +2711,6 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
int p1 = 1 << pD->m_successive_low;
int m1 = (-1) << pD->m_successive_low;
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-
JPGD_ASSERT(pD->m_spectral_end <= 63);
k = pD->m_spectral_start;
@@ -2688,7 +2719,9 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
{
for ( ; k <= pD->m_spectral_end; k++)
{
- s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
r = s >> 4;
s &= 15;
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/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/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/xatlas/avoid-failing-on-bad-geometry.patch b/thirdparty/xatlas/avoid-failing-on-bad-geometry.patch
deleted file mode 100644
index a28cd9f82b..0000000000
--- a/thirdparty/xatlas/avoid-failing-on-bad-geometry.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-diff --git a/thirdparty/xatlas/xatlas.cpp b/thirdparty/xatlas/xatlas.cpp
-index df5ef94db..eb0824a51 100644
---- a/thirdparty/xatlas/xatlas.cpp
-+++ b/thirdparty/xatlas/xatlas.cpp
-@@ -1276,6 +1276,9 @@ class Vertex
- {
- public:
- uint32_t id;
-+ // -- GODOT start --
-+ uint32_t original_id;
-+ // -- GODOT end --
- Edge *edge;
- Vertex *next;
- Vertex *prev;
-@@ -1283,7 +1286,10 @@ public:
- Vector3 nor;
- Vector2 tex;
-
-- Vertex(uint32_t id) : id(id), edge(NULL), pos(0.0f), nor(0.0f), tex(0.0f)
-+ // -- 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;
-@@ -1934,6 +1940,64 @@ public:
- return f;
- }
-
-+ // -- 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;
-+ }
-+ }
-+
-+ 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;
-+ }
-+ }
-+
-+ //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.
-@@ -2915,6 +2979,14 @@ Mesh *triangulate(const Mesh *inputMesh)
- 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);
-@@ -2938,6 +3010,11 @@ Mesh *triangulate(const Mesh *inputMesh)
- }
- }
- }
-+ // -- GODOT start --
-+ if (!bestIsValid)
-+ break;
-+ // -- GODOT end --
-+
- xaDebugAssert(minAngle <= 2 * PI);
- // Clip best ear:
- uint32_t i0 = (bestEar + size - 1) % size;
-@@ -5606,7 +5683,10 @@ public:
- }
- if (chartMeshIndices[vertex->id] == ~0) {
- chartMeshIndices[vertex->id] = m_chartMesh->vertexCount();
-- m_chartToOriginalMap.push_back(vertex->id);
-+ // -- 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;
-@@ -5699,7 +5779,10 @@ public:
- const halfedge::Vertex *vertex = it.current()->vertex;
- if (chartMeshIndices[vertex->id] == ~0) {
- chartMeshIndices[vertex->id] = m_chartMesh->vertexCount();
-- m_chartToOriginalMap.push_back(vertex->id);
-+ // -- 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.
-@@ -7573,6 +7656,14 @@ AddMeshError AddMesh(Atlas *atlas, const InputMesh &mesh, bool useColocalVertice
- }
- }
- 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;
diff --git a/thirdparty/xatlas/build-fix-limits.patch b/thirdparty/xatlas/build-fix-limits.patch
deleted file mode 100644
index 00d07371c0..0000000000
--- a/thirdparty/xatlas/build-fix-limits.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/thirdparty/xatlas/xatlas.h b/thirdparty/xatlas/xatlas.h
-index 7e556c6c3..dbf8ca08c 100644
---- a/thirdparty/xatlas/xatlas.h
-+++ b/thirdparty/xatlas/xatlas.h
-@@ -3,6 +3,9 @@
- #ifndef XATLAS_H
- #define XATLAS_H
- #include <float.h> // FLT_MAX
-+// -- GODOT start --
-+#include <limits.h> // INT_MAX, UINT_MAX
-+// -- GODOT end --
-
- namespace xatlas {
-
diff --git a/thirdparty/xatlas/xatlas.cpp b/thirdparty/xatlas/xatlas.cpp
index 2cc2905eee..56794211a6 100644
--- a/thirdparty/xatlas/xatlas.cpp
+++ b/thirdparty/xatlas/xatlas.cpp
@@ -1,128 +1,476 @@
-// 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
+
+#ifndef XA_DEBUG_ASSERT
+#define XA_DEBUG_ASSERT(exp) assert(exp)
#endif
+#ifndef XA_PRINT
+#define XA_PRINT(...) \
+ if (xatlas::internal::s_print && xatlas::internal::s_printVerbose) \
+ xatlas::internal::s_print(__VA_ARGS__);
+#endif
+
+#ifndef XA_PRINT_WARNING
+#define XA_PRINT_WARNING(...) \
+ if (xatlas::internal::s_print) \
+ xatlas::internal::s_print(__VA_ARGS__);
+#endif
+
+#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_REALLOC_SIZE(tag, ptr, size) (uint8_t *)internal::Realloc(ptr, size, 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()
+#define XA_NEW_ARGS(tag, type, ...) new (XA_ALLOC(tag, type)) type(__VA_ARGS__)
+
#ifdef _MSC_VER
-#define restrict
-#define NV_FORCEINLINE __forceinline
+#define XA_INLINE __forceinline
#else
-#define restrict __restrict__
-#define NV_FORCEINLINE __attribute__((always_inline)) inline
+#define XA_INLINE inline
#endif
-#define NV_UINT32_MAX 0xffffffff
-#define NV_FLOAT_MAX 3.402823466e+38F
-
-#ifndef PI
-#define PI float(3.1415926535897932384626433833)
+#if defined(__clang__) || defined(__GNUC__)
+#define XA_NODISCARD [[nodiscard]]
+#elif defined(_MSC_VER)
+#define XA_NODISCARD _Check_return_
+#else
+#define XA_NODISCARD
#endif
-#define NV_EPSILON (0.0001f)
-#define NV_NORMAL_EPSILON (0.001f)
+#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_SKIP_PARAMETERIZATION 0 // Use the orthogonal parameterization from segment::Atlas
+#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 FreeFunc s_free = free;
+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;
+ uint32_t id;
+ 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 uint32_t s_allocId =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->id = s_allocId++;
+ 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: ID %u, %zu bytes, %s %d\n", header->id, 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*/)
+{
+ if (ptr && size == 0 && s_free) {
+ s_free(ptr);
+ return nullptr;
+ }
+ 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;
+ clock_t addMeshCopyData;
+ 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> buildAtlas;
+ std::atomic<clock_t> buildAtlasInit;
+ std::atomic<clock_t> buildAtlasPlaceSeeds;
+ std::atomic<clock_t> buildAtlasRelocateSeeds;
+ std::atomic<clock_t> buildAtlasResetCharts;
+ std::atomic<clock_t> buildAtlasGrowCharts;
+ std::atomic<clock_t> buildAtlasMergeCharts;
+ std::atomic<clock_t> buildAtlasFillHoles;
+ 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 packChartsAddCharts;
+ std::atomic<clock_t> packChartsAddChartsThread;
+ std::atomic<clock_t> packChartsAddChartsRestoreTexcoords;
+ clock_t packChartsRasterize;
+ clock_t packChartsDilate;
+ clock_t packChartsFindLocation;
+ std::atomic<clock_t> packChartsFindLocationThread;
+ clock_t packChartsBlit;
+ clock_t buildOutputMeshes;
+};
+
+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 +478,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 +486,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 +497,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 +507,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 +527,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 +554,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)
-{
- return Vector2(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 bool operator!=(const Vector2 &a, const Vector2 &b)
{
- return Vector2(v.x * s, v.y * s);
+ return a.x != b.x || a.y != b.y;
}
-Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2)
+/*static Vector2 operator+(const Vector2 &a, const Vector2 &b)
{
- 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 +659,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 +729,84 @@ 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);
-}
-
-Vector3 sub(Vector3::Arg a, float b)
-{
- return Vector3(a.x - b, a.y - b, a.z - b);
+ return a.x != b.x || a.y != b.y || a.z != b.z;
}
-Vector3 operator-(Vector3::Arg a, Vector3::Arg 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 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)
-{
- return Vector3(v.x * s, v.y * s, v.z * s);
-}
-
-Vector3 operator*(float s, Vector3::Arg v)
+static Vector3 operator*(const Vector3 &v, float s)
{
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,83 +815,369 @@ 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)
-{
- return sdbmFloatHash(v.component, 3, 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
+{
+ 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;
+};
+
+struct ArrayBase
+{
+ ArrayBase(uint32_t elementSize, int memTag = MemTag::Default) : buffer(nullptr), elementSize(elementSize), size(0), capacity(0), memTag(memTag) {}
+
+ ~ArrayBase()
+ {
+ XA_FREE(buffer);
+ }
+
+ XA_INLINE void clear()
+ {
+ size = 0;
+ }
+
+ void copyTo(ArrayBase &other) const
+ {
+ XA_DEBUG_ASSERT(elementSize == other.elementSize);
+ other.resize(size, true);
+ memcpy(other.buffer, buffer, size * elementSize);
+ }
+
+ void destroy()
+ {
+ size = 0;
+ XA_FREE(buffer);
+ buffer = nullptr;
+ capacity = 0;
+ size = 0;
+ }
+
+ // Insert the given element at the given index shifting all the elements up.
+ void insertAt(uint32_t index, const uint8_t *value)
+ {
+ XA_DEBUG_ASSERT(index >= 0 && index <= size);
+ resize(size + 1, false);
+ if (index < size - 1)
+ memmove(buffer + elementSize * (index + 1), buffer + elementSize * index, elementSize * (size - 1 - index));
+ memcpy(&buffer[index * elementSize], value, elementSize);
+ }
+
+ void moveTo(ArrayBase &other)
+ {
+ XA_DEBUG_ASSERT(elementSize == other.elementSize);
+ other.destroy();
+ other.buffer = buffer;
+ other.elementSize = elementSize;
+ other.size = size;
+ other.capacity = capacity;
+ other.memTag = memTag;
+ buffer = nullptr;
+ elementSize = size = capacity = 0;
+ }
+
+ void pop_back()
+ {
+ XA_DEBUG_ASSERT(size > 0);
+ resize(size - 1, false);
+ }
+
+ void push_back(const uint8_t *value)
+ {
+ XA_DEBUG_ASSERT(value < buffer || value >= buffer + size);
+ resize(size + 1, false);
+ memcpy(&buffer[(size - 1) * elementSize], value, elementSize);
+ }
+
+ // Remove the element at the given index. This is an expensive operation!
+ void removeAt(uint32_t index)
+ {
+ XA_DEBUG_ASSERT(index >= 0 && index < size);
+ if (size != 1)
+ memmove(buffer + elementSize * index, buffer + elementSize * (index + 1), elementSize * (size - 1 - index));
+ size--;
+ }
+
+ void reserve(uint32_t desiredSize)
+ {
+ if (desiredSize > capacity)
+ setArrayCapacity(desiredSize);
+ }
+
+ void resize(uint32_t newSize, bool exact)
+ {
+ size = newSize;
+ if (size > capacity) {
+ // First allocation is always exact. Otherwise, following allocations grow array to 150% of desired size.
+ uint32_t newBufferSize;
+ if (capacity == 0 || exact)
+ newBufferSize = size;
+ else
+ newBufferSize = size + (size >> 2);
+ setArrayCapacity(newBufferSize);
+ }
+ }
+
+ void setArrayCapacity(uint32_t newCapacity)
+ {
+ XA_DEBUG_ASSERT(newCapacity >= size);
+ if (newCapacity == 0) {
+ // free the buffer.
+ if (buffer != nullptr) {
+ XA_FREE(buffer);
+ buffer = nullptr;
+ }
+ } else {
+ // realloc the buffer
+ buffer = XA_REALLOC_SIZE(memTag, buffer, newCapacity * elementSize);
+ }
+ capacity = newCapacity;
+ }
+
+ uint8_t *buffer;
+ uint32_t elementSize;
+ uint32_t size;
+ uint32_t capacity;
+ int memTag;
+};
-/// Basis class to compute tangent space basis, ortogonalizations and to
-/// transform vectors from one space to another.
-class Basis
+template<typename T>
+class Array
{
public:
- /// Create a null basis.
- Basis() : tangent(0, 0, 0), bitangent(0, 0, 0), normal(0, 0, 0) {}
+ Array(int memTag = MemTag::Default) : m_base(sizeof(T), memTag) {}
+ Array(const Array&) = delete;
+ const Array &operator=(const Array &) = delete;
+
+ XA_INLINE const T &operator[](uint32_t index) const
+ {
+ XA_DEBUG_ASSERT(index < m_base.size);
+ return ((const T *)m_base.buffer)[index];
+ }
+
+ XA_INLINE T &operator[](uint32_t index)
+ {
+ XA_DEBUG_ASSERT(index < m_base.size);
+ return ((T *)m_base.buffer)[index];
+ }
- void buildFrameForDirection(Vector3::Arg d, float angle = 0)
+ XA_INLINE const T &back() const
{
- xaAssert(isNormalized(d));
- normal = d;
+ XA_DEBUG_ASSERT(!isEmpty());
+ return ((const T *)m_base.buffer)[m_base.size - 1];
+ }
+
+ XA_INLINE T *begin() { return (T *)m_base.buffer; }
+ XA_INLINE void clear() { m_base.clear(); }
+ void copyTo(Array &other) const { m_base.copyTo(other.m_base); }
+ XA_INLINE const T *data() const { return (const T *)m_base.buffer; }
+ XA_INLINE T *data() { return (T *)m_base.buffer; }
+ XA_INLINE T *end() { return (T *)m_base.buffer + m_base.size; }
+ XA_INLINE bool isEmpty() const { return m_base.size == 0; }
+ void insertAt(uint32_t index, const T &value) { m_base.insertAt(index, (const uint8_t *)&value); }
+ void moveTo(Array &other) { m_base.moveTo(other.m_base); }
+ void push_back(const T &value) { m_base.push_back((const uint8_t *)&value); }
+ void pop_back() { m_base.pop_back(); }
+ void removeAt(uint32_t index) { m_base.removeAt(index); }
+ void reserve(uint32_t desiredSize) { m_base.reserve(desiredSize); }
+ void resize(uint32_t newSize) { m_base.resize(newSize, true); }
+
+ void setAll(const T &value)
+ {
+ auto buffer = (T *)m_base.buffer;
+ for (uint32_t i = 0; i < m_base.size; i++)
+ buffer[i] = value;
+ }
+
+ XA_INLINE uint32_t size() const { return m_base.size; }
+ XA_INLINE void zeroOutMemory() { memset(m_base.buffer, 0, m_base.elementSize * m_base.size); }
+
+private:
+ ArrayBase m_base;
+};
+
+/// Basis class to compute tangent space basis, ortogonalizations and to transform vectors from one space to another.
+struct Basis
+{
+ XA_NODISCARD static Vector3 computeTangent(const Vector3 &normal)
+ {
+ XA_ASSERT(isNormalized(normal));
// Choose minimum axis.
- if (fabsf(normal.x) < fabsf(normal.y) && fabsf(normal.x) < fabsf(normal.z)) {
+ Vector3 tangent;
+ if (fabsf(normal.x) < fabsf(normal.y) && fabsf(normal.x) < fabsf(normal.z))
tangent = Vector3(1, 0, 0);
- } else if (fabsf(normal.y) < fabsf(normal.z)) {
+ else if (fabsf(normal.y) < fabsf(normal.z))
tangent = Vector3(0, 1, 0);
- } else {
+ else
tangent = Vector3(0, 0, 1);
- }
// Ortogonalize
tangent -= normal * dot(normal, tangent);
- tangent = normalize(tangent);
- bitangent = cross(normal, tangent);
- // Rotate frame around normal according to angle.
- if (angle != 0.0f) {
- float c = cosf(angle);
- float s = sinf(angle);
- Vector3 tmp = c * tangent - s * bitangent;
- bitangent = s * tangent + c * bitangent;
- tangent = tmp;
- }
+ tangent = normalize(tangent, kEpsilon);
+ return tangent;
}
- Vector3 tangent;
- Vector3 bitangent;
- Vector3 normal;
+ XA_NODISCARD static Vector3 computeBitangent(const Vector3 &normal, const Vector3 &tangent)
+ {
+ return cross(normal, tangent);
+ }
+
+ Vector3 tangent = Vector3(0.0f);
+ Vector3 bitangent = Vector3(0.0f);
+ Vector3 normal = Vector3(0.0f);
};
// Simple bit array.
@@ -724,186 +1185,319 @@ 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;
- m_wordArray.resize( (m_size + 31) >> 5 );
+ m_wordArray.resize((m_size + 31) >> 5);
}
/// 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);
+ m_data.zeroOutMemory();
}
- uint32_t height() const
+
+ BitImage(const BitImage &other) = delete;
+ const BitImage &operator=(const BitImage &other) = delete;
+ uint32_t width() const { return m_width; }
+ uint32_t height() const { return m_height; }
+
+ void copyTo(BitImage &other)
{
- return m_height;
+ other.m_width = m_width;
+ other.m_height = m_height;
+ other.m_rowStride = m_rowStride;
+ m_data.copyTo(other.m_data);
}
- void resize(uint32_t w, uint32_t h, bool initValue)
+ void resize(uint32_t w, uint32_t h, bool discard)
{
- 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);
- }
+ const uint32_t rowStride = (w + 63) >> 6;
+ if (discard) {
+ m_data.resize(rowStride * h);
+ m_data.zeroOutMemory();
+ } 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();
+ m_data.zeroOutMemory();
+ }
+
+ 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);
+ }
+ }
+ tmp.m_data.copyTo(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 ((&centroid.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 +1507,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 +1527,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 +1556,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;
}
@@ -1114,1719 +1695,1700 @@ class FullVector
{
public:
FullVector(uint32_t dim) { m_array.resize(dim); }
- FullVector(const FullVector &v) : m_array(v.m_array) {}
-
- const FullVector &operator=(const FullVector &v)
- {
- xaAssert(dimension() == v.dimension());
- m_array = v.m_array;
- return *this;
- }
-
- uint32_t dimension() const { return m_array.size(); }
- const float &operator[]( uint32_t index ) const { return m_array[index]; }
- float &operator[] ( uint32_t index ) { return m_array[index]; }
+ FullVector(const FullVector &v) { v.m_array.copyTo(m_array); }
+ const FullVector &operator=(const FullVector &v) = delete;
+ XA_INLINE uint32_t dimension() const { return m_array.size(); }
+ XA_INLINE const float &operator[](uint32_t index) const { return m_array[index]; }
+ XA_INLINE float &operator[](uint32_t index) { return m_array[index]; }
void fill(float f)
{
const uint32_t dim = dimension();
- for (uint32_t i = 0; i < dim; i++) {
+ for (uint32_t i = 0; i < dim; i++)
m_array[i] = f;
- }
- }
-
- 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 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_next(memTag)
{
- return vertex;
}
- Vertex *from()
+ ~HashMap()
{
- return vertex;
+ if (m_slots)
+ XA_FREE(m_slots);
}
- const Vertex *to() const
+ void add(const Key &key)
{
- return pair->vertex; // This used to be 'next->vertex', but that changed often when the connectivity of the mesh changes.
+ if (!m_slots)
+ alloc();
+ const uint32_t hash = computeHash(key);
+ m_keys.push_back(key);
+ m_next.push_back(m_slots[hash]);
+ m_slots[hash] = m_next.size() - 1;
}
- Vertex *to()
+ uint32_t get(const Key &key) const
{
- return pair->vertex;
+ 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;
}
- // Edge queries.
- void setNext(Edge *e)
+ uint32_t getNext(uint32_t current) const
{
- next = e;
- if (e != NULL) e->prev = this;
- }
- void setPrev(Edge *e)
- {
- prev = e;
- if (e != NULL) e->next = this;
+ 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;
}
- // @@ It would be more simple to only check m_pair == NULL
- // Face queries.
- bool isBoundary() const
+private:
+ void alloc()
{
- return !(face && pair->face);
+ 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_next.reserve(m_size);
}
- // @@ This is not exactly accurate, we should compare the texture coordinates...
- bool isSeam() const
+ uint32_t computeHash(const Key &key) const
{
- return vertex != pair->next->vertex || next->vertex != pair->vertex;
+ H hash;
+ return hash(key) % m_numSlots;
}
- bool isNormalSeam() const;
- bool isTextureSeam() const;
+ int m_memTag;
+ uint32_t m_size;
+ uint32_t m_numSlots;
+ uint32_t *m_slots;
+ Array<Key> m_keys;
+ Array<uint32_t> m_next;
+};
- bool isValid() 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;
+template<typename T>
+static void insertionSort(T *data, uint32_t length)
+{
+ 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;
}
+}
- float length() const;
-
- // Return angle between this edge and the previous one.
- float angle() const;
-};
-
-class Vertex
+class KISSRng
{
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 --
+ uint32_t getRange(uint32_t range)
{
- next = this;
- prev = this;
+ 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;
}
- // Set first edge of all colocals.
- void setEdge(Edge *e)
- {
- for (VertexIterator it(colocals()); !it.isDone(); it.advance()) {
- it.current()->edge = e;
- }
- }
+private:
+ uint32_t x = 123456789, y = 362436000, z = 521288629, c = 7654321;
+};
- // Update position of all colocals.
- void setPos(const Vector3 &p)
- {
- for (VertexIterator it(colocals()); !it.isDone(); it.advance()) {
- it.current()->pos = p;
- }
- }
+// 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) {}
- bool isFirstColocal() const
+ ~RadixSort()
{
- return firstColocal() == this;
+ // Release everything
+ XA_FREE(m_ranks2);
+ XA_FREE(m_ranks);
}
- const Vertex *firstColocal() const
+ RadixSort &sort(const float *input, uint32_t count)
{
- 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();
+ 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;
- }
-
- Vertex *firstColocal()
- {
- 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 (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]);
}
- }
- 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;
+ 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) {}
-
- 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;
- }
+ Vector2 majorAxis() const { return m_majorAxis; }
+ Vector2 minorAxis() const { return m_minorAxis; }
+ Vector2 minCorner() const { return m_minCorner; }
+ Vector2 maxCorner() const { return m_maxCorner; }
- 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.size() > 0);
+ 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()) { }
-
- virtual void advance()
- {
- if (m_end == NULL) m_end = m_current;
- m_current = m_current->next;
- }
+ Array<float> m_coords;
+ Array<Vector2> m_top, m_bottom, m_hull;
+ Vector2 m_majorAxis, m_minorAxis, m_minCorner, m_maxCorner;
+};
- 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;
- }
+static uint32_t meshEdgeFace(uint32_t edge) { return edge / 3; }
+static uint32_t meshEdgeIndex0(uint32_t edge) { return edge; }
- 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()
+ 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)
{
- clear();
+ 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);
}
- 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();
- }
+ uint32_t flags() const { return m_flags; }
+ uint32_t id() const { return m_id; }
- Vertex *addVertex(const Vector3 &pos)
+ void addVertex(const Vector3 &pos, const Vector3 &normal = Vector3(0.0f), const Vector2 &texcoord = Vector2(0.0f))
{
- xaDebugAssert(isFinite(pos));
- Vertex *v = new Vertex(m_vertexArray.size());
- v->pos = pos;
- m_vertexArray.push_back(v);
- return v;
+ 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);
}
- /// Link colocal vertices based on geometric location only.
- void linkColocals()
+ struct AddFaceResult
{
- 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?
- }
-
- void linkColocalsWithCanonicalMap(const std::vector<uint32_t> &canonicalMap)
- {
- 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);
- }
-
- Face *addFace()
- {
- 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);
+ return addFace(indexArray, ignore, hashEdge);
}
- Face *addFace(uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3)
+ AddFaceResult::Enum addFace(const uint32_t *indices, bool ignore = false, bool hashEdge = true)
{
- uint32_t indexArray[4];
- indexArray[0] = v0;
- indexArray[1] = v1;
- indexArray[2] = v2;
- indexArray[3] = v3;
- return addFace(indexArray, 4, 0, 4);
- }
-
- Face *addFace(const std::vector<uint32_t> &indexArray)
- {
- 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);
+ }
+ }
+ 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);
+ for (uint32_t i = 0; i < vertexCount; i++)
+ m_nextColocalVertex[i] = 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> vertexToEdgeMap(MemTag::Mesh, edgeCount); // Edge is index / 2
+ for (uint32_t i = 0; i < edgeCount; i++) {
+ vertexToEdgeMap.add(m_indices[meshEdgeIndex0(i)]);
+ vertexToEdgeMap.add(m_indices[meshEdgeIndex1(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 mapIndex = vertexToEdgeMap.get(it.vertex());
+ while (mapIndex != UINT32_MAX) {
+ const uint32_t otherEdge = mapIndex / 2; // Two vertices added per edge.
+ 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:
+ mapIndex = vertexToEdgeMap.getNext(mapIndex);
+ }
+ }
+ 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 edge = m_edgeMap.get(key);
+ while (edge != UINT32_MAX) {
+ // 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
+ }
+ edge = m_edgeMap.getNext(edge);
+ }
+ } 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 edge = m_edgeMap.get(key);
+ while (edge != UINT32_MAX) {
+ // 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
+ }
+ edge = m_edgeMap.getNext(edge);
+ }
+ }
+ }
+ }
+ 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;
+ XA_INLINE float epsilon() const { return m_epsilon; }
+ XA_INLINE uint32_t edgeCount() const { return m_indices.size(); }
+ XA_INLINE uint32_t oppositeEdge(uint32_t edge) const { return m_oppositeEdges[edge]; }
+ XA_INLINE bool isBoundaryEdge(uint32_t edge) const { return m_oppositeEdges[edge] == UINT32_MAX; }
+ XA_INLINE bool isBoundaryVertex(uint32_t vertex) const { return m_boundaryVertices[vertex]; }
+ XA_INLINE uint32_t colocalVertexCount() const { return m_colocalVertexCount; }
+ XA_INLINE uint32_t vertexCount() const { return m_positions.size(); }
+ XA_INLINE uint32_t vertexAt(uint32_t i) const { return m_indices[i]; }
+ XA_INLINE const Vector3 &position(uint32_t vertex) const { return m_positions[vertex]; }
+ XA_INLINE const Vector3 &normal(uint32_t vertex) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasNormals); return m_normals[vertex]; }
+ XA_INLINE const Vector2 &texcoord(uint32_t vertex) const { return m_texcoords[vertex]; }
+ XA_INLINE Vector2 &texcoord(uint32_t vertex) { return m_texcoords[vertex]; }
+ XA_INLINE Vector2 *texcoords() { return m_texcoords.data(); }
+ XA_INLINE uint32_t faceCount() const { return m_indices.size() / 3; }
+ XA_INLINE uint32_t faceGroupCount() const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroups.size(); }
+ XA_INLINE uint32_t faceGroupAt(uint32_t face) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroups[face]; }
+ XA_INLINE const uint32_t *indices() const { return m_indices.data(); }
+ XA_INLINE 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.
- class VertexIterator
+ // 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.
+
+ 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()
+ void operator=(const EdgeKey &k)
{
- m_current++;
+ v0 = k.v0;
+ v1 = k.v1;
}
- virtual bool isDone() const
+ bool operator==(const EdgeKey &k) const
{
- return m_current == m_mesh->vertexCount();
- }
- virtual Vertex *current() 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> 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_current;
+ }
+
+ uint32_t nextEdge() const
{
- return m_mesh->vertexAt(m_current);
+ 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_edge == UINT32_MAX;
}
- virtual const Face *current() const
+
+ uint32_t edge() const
{
- return m_mesh->faceAt(m_current);
+ return m_edge;
}
private:
- const halfedge::Mesh *m_mesh;
- uint32_t m_current;
- };
- ConstFaceIterator faces() const
- {
- return ConstFaceIterator(this);
- }
-
- class ConstEdgeIterator;
+ void resetElement()
+ {
+ m_edge = m_mesh->m_edgeMap.get(Mesh::EdgeKey(m_vertex0It.vertex(), m_vertex1It.vertex()));
+ while (m_edge != UINT32_MAX) {
+ if (!isIgnoredFace())
+ break;
+ m_edge = m_mesh->m_edgeMap.getNext(m_edge);
+ }
+ if (m_edge == UINT32_MAX)
+ advanceVertex1();
+ }
- class EdgeIterator
- {
- friend class ConstEdgeIterator;
- public:
- EdgeIterator(Mesh *mesh) : m_mesh(mesh), m_current(0) { }
+ void advanceElement()
+ {
+ for (;;) {
+ m_edge = m_mesh->m_edgeMap.getNext(m_edge);
+ if (m_edge == UINT32_MAX)
+ break;
+ if (!isIgnoredFace())
+ break;
+ }
+ if (m_edge == 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);
+ return m_mesh->m_faceIgnore[meshEdgeFace(m_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_edge;
};
- 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;
+ }
- virtual void advance()
+ void advance()
{
- m_current++;
+ if (m_relativeEdge < 3) {
+ m_edge++;
+ m_relativeEdge++;
+ }
}
- virtual bool isDone() const
+
+ bool isDone() const
{
- return m_current == m_mesh->edgeCount();
+ 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
+ {
+ const uint32_t oedge = m_mesh->m_oppositeEdges[m_edge];
+ if (oedge == UINT32_MAX)
+ return UINT32_MAX;
+ return meshEdgeFace(oedge);
}
- virtual const Edge *current() const
+
+ uint32_t vertex0() const
{
- return m_mesh->edgeAt(m_current);
+ return m_mesh->m_indices[m_face * 3 + m_relativeEdge];
}
+ uint32_t vertex1() const
+ {
+ 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.
+
+*/
+struct SplitEdge
+{
+ uint32_t edge;
+ float t;
+ uint32_t vertex;
- Edge *addEdge(uint32_t i, uint32_t j)
+ 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_ARGS(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 +3405,323 @@ 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)
+struct Progress
{
- 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)
-{
- 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 )
- {
- seed((uint32_t )time(NULL));
- }
-
- /// Constructor that uses the given seed.
- MTRand( uint32_t s = 0 )
+ 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(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)
+struct Spinlock
{
- 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)
-{
- 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;
-}
+ void lock() { while(m_lock.test_and_set(std::memory_order_acquire)) {} }
+ void unlock() { m_lock.clear(std::memory_order_release); }
-uint32_t decodeMorton2X(uint32_t code)
-{
- return compact1By1(code >> 0);
-}
-
-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);
+public:
+ TaskScheduler() : m_shutdown(false)
+ {
+ // 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++) {
+ new (&m_workers[i]) Worker();
+ m_workers[i].wakeup = false;
+ m_workers[i].thread = XA_NEW_ARGS(MemTag::Default, std::thread, workerThread, this, &m_workers[i]);
+ }
+ }
+
+ ~TaskScheduler()
+ {
+ 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);
+ worker.~Worker();
+ }
+ for (uint32_t i = 0; i < m_maxGroups; i++)
+ m_groups[i].~TaskGroup();
+ XA_FREE(m_groups);
+ }
+
+ TaskGroupHandle createTaskGroup(uint32_t reserveSize = 0)
+ {
+ // 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;
}
- 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);
+ XA_DEBUG_ASSERT(false);
+ TaskGroupHandle handle;
+ handle.value = UINT32_MAX;
+ return handle;
}
- int index_y(float y) const
+ void run(TaskGroupHandle handle, Task task)
{
- return clamp(ftoi_floor((y - corner.y) * invCellSize.y), 0, sy - 1);
- }
-
- int index_z(float z) const
- {
- return clamp(ftoi_floor((z - corner.z) * invCellSize.z), 0, sz - 1);
- }
-
- int index(int x, int y, int z) const
- {
- 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;
- }
-
- uint32_t mortonCount() const
- {
- 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.
+ };
+
+ struct Worker
+ {
+ 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;
- // 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)
+ static void workerThread(TaskScheduler *scheduler, Worker *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::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
- {
- xaDebugAssert(m_validRanks);
- return m_ranks;
- }
- uint32_t *ranks()
+ void wait(TaskGroupHandle *handle)
{
- 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> faces;
+ 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 +3732,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,10 +3754,9 @@ 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 )
+ void clipVerticalPlane(float offset, float clipdirection)
{
Vector2 *v = m_vertexBuffers[m_activeVertexBuffer];
m_activeVertexBuffer ^= 1;
@@ -3608,7 +3780,7 @@ public:
m_numVertices = p;
}
- void computeAreaCentroid()
+ void computeArea()
{
Vector2 *v = m_vertexBuffers[m_activeVertexBuffer];
v[m_numVertices] = v[0];
@@ -3622,28 +3794,18 @@ 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();
+ clipVerticalPlane(x0, -1);
+ clipHorizontalPlane(y0, -1);
+ clipVerticalPlane(x1, 1);
+ clipHorizontalPlane(y1, 1);
+ computeArea();
}
- Vector2 centroid()
- {
- return m_centroid;
- }
-
- float area()
+ float area() const
{
return m_area;
}
@@ -3652,212 +3814,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,60 +3885,40 @@ 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;
- }
}
}
CX1 += n1.x;
CX2 += n2.x;
CX3 += n3.x;
- tex += dx;
}
CY1 += n1.y;
CY2 += n2.y;
CY3 += n3.y;
- texRow += dy;
}
}
}
@@ -3953,9 +3933,6 @@ struct Triangle
Vector2 hv = v1;
v1 = v2;
v2 = hv; // swap pos
- Vector3 ht = t1;
- t1 = t2;
- t2 = ht; // swap tex
}
}
@@ -3976,77 +3953,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
@@ -4066,18 +3990,28 @@ public:
float v; // value
};
- Matrix(uint32_t d) : m_width(d) { m_array.resize(d); }
- Matrix(uint32_t w, uint32_t h) : m_width(w) { m_array.resize(h); }
- Matrix(const Matrix &m) : m_width(m.m_width) { m_array = m.m_array; }
-
- const Matrix &operator=(const Matrix &m)
+ Matrix(uint32_t d) : m_width(d)
{
- xaAssert(width() == m.width());
- xaAssert(height() == m.height());
- m_array = m.m_array;
- return *this;
+ m_array.resize(d);
+ for (uint32_t i = 0; i < m_array.size(); i++)
+ new (&m_array[i]) Array<Coefficient>();
+ }
+
+ Matrix(uint32_t w, uint32_t h) : m_width(w)
+ {
+ m_array.resize(h);
+ for (uint32_t i = 0; i < m_array.size(); i++)
+ new (&m_array[i]) Array<Coefficient>();
+ }
+
+ ~Matrix()
+ {
+ for (uint32_t i = 0; i < m_array.size(); i++)
+ m_array[i].~Array();
}
+ Matrix(const Matrix &m) = delete;
+ const Matrix &operator=(const Matrix &m) = delete;
uint32_t width() const { return m_width; }
uint32_t height() const { return m_array.size(); }
bool isSquare() const { return width() == height(); }
@@ -4085,8 +4019,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 +4030,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 +4047,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 +4058,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 +4067,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 +4093,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 +4110,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 +4119,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,109 +4157,977 @@ 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
+namespace segment {
+
+// 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).
+// - Resorting is n*log(n)
+// @@ Number of elements in the queue is usually small, and we'd have to rebalance often. I'm not sure it's worth implementing a heap.
+// @@ Searcing at removal would remove the need for sorting when priorities change.
+struct PriorityQueue
+{
+ PriorityQueue(uint32_t size = UINT32_MAX) : maxSize(size) {}
+
+ void push(float priority, uint32_t face)
+ {
+ uint32_t i = 0;
+ const uint32_t count = pairs.size();
+ for (; i < count; i++) {
+ if (pairs[i].priority > priority) break;
+ }
+ Pair p = { priority, face };
+ pairs.insertAt(i, p);
+ if (pairs.size() > maxSize)
+ pairs.removeAt(0);
+ }
+
+ // push face out of order, to be sorted later.
+ void push(uint32_t face)
+ {
+ Pair p = { 0.0f, face };
+ pairs.push_back(p);
+ }
+
+ uint32_t pop()
+ {
+ XA_DEBUG_ASSERT(!pairs.isEmpty());
+ uint32_t f = pairs.back().face;
+ pairs.pop_back();
+ return f;
+ }
+
+ void sort()
+ {
+ //sort(pairs); // @@ My intro sort appears to be much slower than it should!
+ std::sort(pairs.begin(), pairs.end());
+ }
+
+ XA_INLINE void clear()
+ {
+ pairs.clear();
+ }
+
+ XA_INLINE uint32_t count() const
+ {
+ return pairs.size();
+ }
+
+ float firstPriority() const
+ {
+ return pairs.back().priority;
+ }
+
+ const uint32_t maxSize;
+
+ struct Pair
+ {
+ bool operator<(const Pair &p) const
+ {
+ return priority > p.priority; // !! Sort in inverse priority order!
+ }
+
+ float priority;
+ uint32_t face;
+ };
+
+ Array<Pair> pairs;
+};
+
+struct Chart
+{
+ 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 Atlas
+{
+ // @@ Hardcoded to 10?
+ Atlas(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)
+ {
+ XA_PROFILE_START(buildAtlasInit)
+ const uint32_t faceCount = m_mesh->faceCount();
+ if (meshFaces) {
+ m_ignoreFaces.resize(faceCount);
+ m_ignoreFaces.setAll(true);
+ for (uint32_t f = 0; f < meshFaces->size(); f++)
+ m_ignoreFaces[(*meshFaces)[f]] = false;
+ m_facesLeft = meshFaces->size();
+ } else {
+ m_ignoreFaces.resize(faceCount);
+ m_ignoreFaces.setAll(false);
+ }
+ m_faceChartArray.resize(faceCount);
+ m_faceChartArray.setAll(-1);
+ m_faceCandidateCharts.resize(faceCount);
+ m_faceCandidateCosts.resize(faceCount);
+ 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.
+ const uint32_t edgeCount = m_mesh->edgeCount();
+ m_edgeLengths.resize(edgeCount);
+ m_edgeLengths.zeroOutMemory();
+ m_faceAreas.resize(faceCount);
+ m_faceAreas.zeroOutMemory();
+ m_faceNormals.resize(faceCount);
+ m_faceTangents.resize(faceCount);
+ m_faceBitangents.resize(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);
+ m_faceTangents[f] = Basis::computeTangent(m_faceNormals[f]);
+ m_faceBitangents[f] = Basis::computeBitangent(m_faceNormals[f], m_faceTangents[f]);
+ }
+#if XA_GROW_CHARTS_COPLANAR
+ // Precompute regions of coplanar incident faces.
+ m_nextPlanarRegionFace.resize(faceCount);
+ for (uint32_t f = 0; f < faceCount; f++)
+ m_nextPlanarRegionFace[f] = f;
+ Array<uint32_t> faceStack;
+ faceStack.reserve(min(faceCount, 16u));
+ for (uint32_t f = 0; f < faceCount; f++) {
+ if (m_nextPlanarRegionFace[f] != f)
+ continue; // Already assigned.
+ if (m_ignoreFaces[f])
+ continue;
+ faceStack.clear();
+ faceStack.push_back(f);
+ for (;;) {
+ if (faceStack.isEmpty())
+ break;
+ const uint32_t face = faceStack.back();
+ faceStack.pop_back();
+ for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
+ const uint32_t oface = it.oppositeFace();
+ if (it.isBoundary() || m_ignoreFaces[oface])
+ continue;
+ if (m_nextPlanarRegionFace[oface] != oface)
+ continue; // Already assigned.
+ if (!equal(dot(m_faceNormals[face], m_faceNormals[oface]), 1.0f, kEpsilon))
+ continue; // Not coplanar.
+ const uint32_t next = m_nextPlanarRegionFace[face];
+ m_nextPlanarRegionFace[face] = oface;
+ m_nextPlanarRegionFace[oface] = next;
+ faceStack.push_back(oface);
+ }
+ }
+ }
+#endif
+ XA_PROFILE_END(buildAtlasInit)
+ }
+
+ ~Atlas()
+ {
+ const uint32_t chartCount = m_chartArray.size();
+ for (uint32_t i = 0; i < chartCount; i++) {
+ m_chartArray[i]->~Chart();
+ XA_FREE(m_chartArray[i]);
+ }
+ }
+
+ 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; }
+ const Vector2 *faceTexcoords(uint32_t face) const { return &m_texcoords[face * 3]; }
+
+ void placeSeeds(float threshold)
+ {
+ XA_PROFILE_START(buildAtlasPlaceSeeds)
+ // 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);
+ XA_PROFILE_END(buildAtlasPlaceSeeds)
+ }
+
+ // Returns true if any of the charts can grow more.
+ bool growCharts(float threshold)
+ {
+ XA_PROFILE_START(buildAtlasGrowCharts)
+ // Build global candidate list.
+ m_faceCandidateCharts.zeroOutMemory();
+ for (uint32_t i = 0; i < m_chartArray.size(); i++)
+ addChartCandidateToGlobalCandidates(m_chartArray[i]);
+ // Add one candidate face per chart (threshold permitting).
+ const uint32_t faceCount = m_mesh->faceCount();
+ bool canAddAny = false;
+ for (uint32_t f = 0; f < faceCount; f++) {
+ Chart *chart = m_faceCandidateCharts[f];
+ if (!chart || m_faceCandidateCosts[f] > threshold)
+ continue;
+ createFaceTexcoords(chart, f);
+ if (!canAddFaceToChart(chart, f))
+ continue;
+ addFaceToChart(chart, f);
+ canAddAny = true;
+ }
+ XA_PROFILE_END(buildAtlasGrowCharts)
+ return canAddAny && m_facesLeft != 0; // Can continue growing.
+ }
+
+ void resetCharts()
+ {
+ XA_PROFILE_START(buildAtlasResetCharts)
+ const uint32_t faceCount = m_mesh->faceCount();
+ for (uint32_t i = 0; i < faceCount; i++)
+ m_faceChartArray[i] = -1;
+ m_facesLeft = m_meshFaces ? m_meshFaces->size() : faceCount;
+ const uint32_t chartCount = m_chartArray.size();
+ for (uint32_t i = 0; i < chartCount; i++) {
+ Chart *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++) {
+ Chart *chart = m_chartArray[i];
+ growChartCoplanar(chart);
+ }
+#endif
+ XA_PROFILE_END(buildAtlasResetCharts)
+ }
+
+ void updateChartCandidates(Chart *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());
+ }
+ // Re-evaluate all candidate priorities.
+ uint32_t candidateCount = chart->candidates.count();
+ for (uint32_t i = 0; i < candidateCount; i++) {
+ PriorityQueue::Pair &pair = chart->candidates.pairs[i];
+ pair.priority = evaluateCost(chart, pair.face);
+ }
+ chart->candidates.sort();
+ }
+
+ bool relocateSeeds()
+ {
+ XA_PROFILE_START(buildAtlasRelocateSeeds)
+ 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;
+ }
+ }
+ XA_PROFILE_END(buildAtlasRelocateSeeds)
+ return anySeedChanged;
+ }
+
+ void fillHoles(float threshold)
+ {
+ XA_PROFILE_START(buildAtlasFillHoles)
+ while (m_facesLeft > 0)
+ createRandomChart(threshold);
+ XA_PROFILE_END(buildAtlasFillHoles)
+ }
+
+#if XA_MERGE_CHARTS
+ void mergeCharts()
+ {
+ XA_PROFILE_START(buildAtlasMergeCharts)
+ 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--) {
+ Chart *chart = m_chartArray[c];
+ if (chart == nullptr)
+ continue;
+ float externalBoundaryLength = 0.0f;
+ sharedBoundaryLengths.clear();
+ sharedBoundaryLengths.resize(chartCount);
+ sharedBoundaryLengths.zeroOutMemory();
+ sharedBoundaryLengthsNoSeams.clear();
+ sharedBoundaryLengthsNoSeams.resize(chartCount);
+ sharedBoundaryLengthsNoSeams.zeroOutMemory();
+ sharedBoundaryEdgeCountNoSeams.clear();
+ sharedBoundaryEdgeCountNoSeams.resize(chartCount);
+ sharedBoundaryEdgeCountNoSeams.zeroOutMemory();
+ 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;
+ Chart *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() * 3);
+ for (uint32_t i = 0; i < chart2->faces.size(); i++) {
+ const uint32_t face = chart2->faces[i];
+ for (uint32_t j = 0; j < 3; j++)
+ tempTexcoords[i * 3 + j] = m_texcoords[face * 3 + j];
+ createFaceTexcoords(chart, face);
+ }
+ if (!canMergeCharts(chart, chart2)) {
+ // Restore chart 2 texcoords.
+ for (uint32_t i = 0; i < chart2->faces.size(); i++) {
+ for (uint32_t j = 0; j < 3; j++)
+ m_texcoords[chart2->faces[i] * 3 + j] = tempTexcoords[i * 3 + j];
+ }
+ 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++;
+ }
+ }
+ XA_PROFILE_END(buildAtlasMergeCharts)
+ }
+#endif
+
+private:
+ void createRandomChart(float threshold)
+ {
+ Chart *chart = XA_NEW(MemTag::Default, Chart);
+ chart->id = (int)m_chartArray.size();
+ m_chartArray.push_back(chart);
+ // Pick random face that is not used by any chart yet.
+ 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);
+#if XA_GROW_CHARTS_COPLANAR
+ growChartCoplanar(chart);
+#endif
+ // Grow the chart as much as possible within the given threshold.
+ for (uint32_t i = 0; i < m_facesLeft; ) {
+ if (chart->candidates.count() == 0 || chart->candidates.firstPriority() > threshold)
+ break;
+ 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++;
+ }
+ }
+
+ void addChartCandidateToGlobalCandidates(Chart *chart)
+ {
+ if (chart->candidates.count() == 0)
+ return;
+ const float cost = chart->candidates.firstPriority();
+ const uint32_t face = chart->candidates.pop();
+ if (m_faceChartArray[face] != -1) {
+ addChartCandidateToGlobalCandidates(chart);
+ } else if (!m_faceCandidateCharts[face]) {
+ // No candidate assigned to this face yet.
+ m_faceCandidateCharts[face] = chart;
+ m_faceCandidateCosts[face] = cost;
+ } else {
+ if (cost < m_faceCandidateCosts[face]) {
+ // This is a better candidate for this face (lower cost). The other chart can choose another candidate.
+ Chart *otherChart = m_faceCandidateCharts[face];
+ m_faceCandidateCharts[face] = chart;
+ m_faceCandidateCosts[face] = cost;
+ addChartCandidateToGlobalCandidates(otherChart);
+ } else {
+ // Existing candidate is better. This chart can choose another candidate.
+ addChartCandidateToGlobalCandidates(chart);
+ }
+ }
+ }
+
+ void createFaceTexcoords(Chart *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(const Chart *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 edgeArraysIntersect(const uint32_t *edges1, uint32_t edges1Count, const uint32_t *edges2, uint32_t edges2Count)
+ {
+ for (uint32_t i = 0; i < edges1Count; i++) {
+ const uint32_t edge1 = edges1[i];
+ for (uint32_t j = 0; j < edges2Count; j++) {
+ const uint32_t edge2 = edges2[j];
+ const Vector2 &a1 = m_texcoords[meshEdgeIndex0(edge1)];
+ const Vector2 &a2 = m_texcoords[meshEdgeIndex1(edge1)];
+ const Vector2 &b1 = m_texcoords[meshEdgeIndex0(edge2)];
+ const Vector2 &b2 = m_texcoords[meshEdgeIndex1(edge2)];
+ if (linesIntersect(a1, a2, b1, b2, m_mesh->epsilon()))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool isFaceFlipped(uint32_t face) const
+ {
+ const float t1 = m_texcoords[face * 3 + 0].x;
+ const float s1 = m_texcoords[face * 3 + 0].y;
+ const float t2 = m_texcoords[face * 3 + 1].x;
+ const float s2 = m_texcoords[face * 3 + 1].y;
+ const float t3 = m_texcoords[face * 3 + 2].x;
+ const float s3 = m_texcoords[face * 3 + 2].y;
+ const float parametricArea = ((s2 - s1) * (t3 - t1) - (s3 - s1) * (t2 - t1)) / 2;
+ return parametricArea < 0.0f;
+ }
+
+ void computeChartBoundaryEdges(const Chart *chart, Array<uint32_t> *dest) const
+ {
+ dest->clear();
+ for (uint32_t f = 0; f < chart->faces.size(); f++) {
+ const uint32_t face = chart->faces[f];
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t edge = face * 3 + i;
+ if (isChartBoundaryEdge(chart, edge))
+ dest->push_back(edge);
+ }
+ }
+ }
+
+ bool canAddFaceToChart(Chart *chart, uint32_t face)
+ {
+ // Check for flipped triangles.
+ if (isFaceFlipped(face))
+ return false;
+ // Find face edges that don't border this chart.
+ m_tempEdges1.clear();
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t edge = face * 3 + i;
+ if (isChartBoundaryEdge(chart, edge))
+ m_tempEdges1.push_back(edge);
+ }
+ if (m_tempEdges1.isEmpty())
+ return true; // This can happen if the face is surrounded by the chart.
+ // Get chart boundary edges, except those that border the face.
+ m_tempEdges2.clear();
+ 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;
+ m_tempEdges2.push_back(chartEdge);
+ }
+ }
+ const bool intersect = edgeArraysIntersect(m_tempEdges1.data(), m_tempEdges1.size(), m_tempEdges2.data(), m_tempEdges2.size());
+#if 0
+ if (intersect) {
+ static std::atomic<uint32_t> count = 0;
+ char filename[256];
+ XA_SPRINTF(filename, sizeof(filename), "intersect%04u.obj", count.fetch_add(1));
+ FILE *file;
+ XA_FOPEN(file, filename, "w");
+ if (file) {
+ for (uint32_t i = 0; i < m_texcoords.size(); i++)
+ fprintf(file, "v %g %g 0.0\n", m_texcoords[i].x, m_texcoords[i].y);
+ fprintf(file, "s off\n");
+ fprintf(file, "o face\n");
+ {
+ fprintf(file, "f ");
+ for (uint32_t j = 0; j < 3; j++) {
+ const uint32_t index = face * 3 + j + 1; // 1-indexed
+ fprintf(file, "%d/%d/%d%c", index, index, index, j == 2 ? '\n' : ' ');
+ }
+ }
+ fprintf(file, "s off\n");
+ fprintf(file, "o chart\n");
+ for (uint32_t i = 0; i < chart->faces.size(); i++) {
+ const uint32_t chartFace = chart->faces[i];
+ fprintf(file, "f ");
+ for (uint32_t j = 0; j < 3; j++) {
+ const uint32_t index = chartFace * 3 + j + 1; // 1-indexed
+ fprintf(file, "%d/%d/%d%c", index, index, index, j == 2 ? '\n' : ' ');
+ }
+ }
+ fclose(file);
+ }
+ }
+#endif
+ return !intersect;
+ }
+
+ bool canMergeCharts(Chart *chart1, Chart *chart2)
+ {
+ for (uint32_t i = 0; i < chart2->faces.size(); i++) {
+ if (isFaceFlipped(chart2->faces[i]))
+ return false;
+ }
+ computeChartBoundaryEdges(chart1, &m_tempEdges1);
+ computeChartBoundaryEdges(chart2, &m_tempEdges2);
+ return !edgeArraysIntersect(m_tempEdges1.data(), m_tempEdges1.size(), m_tempEdges2.data(), m_tempEdges2.size());
+ }
+
+ void addFaceToChart(Chart *chart, uint32_t f)
+ {
+ const bool firstFace = chart->faces.isEmpty();
+ // Use the first face normal as the chart basis.
+ if (firstFace) {
+ chart->basis.normal = m_faceNormals[f];
+ chart->basis.tangent = m_faceTangents[f];
+ chart->basis.bitangent = m_faceBitangents[f];
+ createFaceTexcoords(chart, f);
+ }
+ // Add face to chart.
+ chart->faces.push_back(f);
+ XA_DEBUG_ASSERT(m_faceChartArray[f] == -1);
+ m_faceChartArray[f] = chart->id;
+ m_facesLeft--;
+ // Update area and boundary length.
+ chart->area = chart->area + m_faceAreas[f];
+ chart->boundaryLength = computeBoundaryLength(chart, f);
+ chart->normalSum += m_mesh->triangleNormalAreaScaled(f);
+ chart->averageNormal = normalizeSafe(chart->normalSum, Vector3(0), 0.0f);
+ chart->centroidSum += m_mesh->triangleCenter(f);
+ chart->centroid = chart->centroidSum / float(chart->faces.size());
+ // Update candidates.
+ updateChartCandidates(chart, f);
+ }
+
+#if XA_GROW_CHARTS_COPLANAR
+ void growChartCoplanar(Chart *chart)
+ {
+ XA_DEBUG_ASSERT(!chart->faces.isEmpty());
+ for (uint32_t i = 0; i < chart->faces.size(); i++) {
+ const uint32_t chartFace = chart->faces[i];
+ uint32_t face = m_nextPlanarRegionFace[chartFace];
+ while (face != chartFace) {
+ // Not assigned to a chart?
+ if (m_faceChartArray[face] == -1) {
+ createFaceTexcoords(chart, face);
+ addFaceToChart(chart, face);
+ }
+ face = m_nextPlanarRegionFace[face];
+ }
+ }
+ }
+#endif
+
+ bool relocateSeed(Chart *chart)
+ {
+ // 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]);
+ m_bestTriangles.push(priority, chart->faces[i]);
+ }
+ // Of those, choose the least central triangle.
+ uint32_t leastCentral = 0;
+ float maxDistance = -1;
+ const uint32_t bestCount = m_bestTriangles.count();
+ for (uint32_t i = 0; i < bestCount; i++) {
+ Vector3 faceCentroid = m_mesh->triangleCenter(m_bestTriangles.pairs[i].face);
+ float distance = length(chart->centroid - faceCentroid);
+ if (distance > maxDistance) {
+ maxDistance = distance;
+ leastCentral = m_bestTriangles.pairs[i].face;
+ }
+ }
+ XA_DEBUG_ASSERT(maxDistance >= 0);
+ // In order to prevent k-means cyles we record all the previously chosen seeds.
+ 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;
+ }
+
+ // Evaluate combined metric.
+ float evaluateCost(Chart *chart, uint32_t face) const
+ {
+ // Estimate boundary length and area:
+ const float newChartArea = chart->area + m_faceAreas[face];
+ const float newBoundaryLength = computeBoundaryLength(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.
+ // 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.
+ XA_DEBUG_ASSERT(isFinite(cost));
+ return cost;
+ }
+
+ // Returns a value in [0-1].
+ float evaluateProxyFitMetric(Chart *chart, uint32_t f) const
+ {
+ const Vector3 faceNormal = m_faceNormals[f];
+ // Use plane fitting metric for now:
+ return 1 - dot(faceNormal, chart->averageNormal); // @@ normal deviations should be weighted by face area
+ }
+
+ float evaluateRoundnessMetric(Chart *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.0f * kPi);
+ } else {
+ // Offer no impedance to faces that improve roundness.
+ return 0;
+ }
+ }
+
+ float evaluateStraightnessMetric(Chart *chart, uint32_t f) const
+ {
+ float l_out = 0.0f;
+ float l_in = 0.0f;
+ 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 {
+ if (m_faceChartArray[it.oppositeFace()] != chart->id) {
+ l_out += l;
+ } else {
+ l_in += l;
+ }
+ }
+ }
+ 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 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(Chart *chart, uint32_t f) const
+ {
+ float seamFactor = 0.0f;
+ float totalLength = 0.0f;
+ for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) {
+ if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()])
+ continue;
+ if (m_faceChartArray[it.oppositeFace()] != chart->id)
+ continue;
+ float l = m_edgeLengths[it.edge()];
+ totalLength += l;
+ if (!it.isSeam())
+ continue;
+ // Make sure it's a normal seam.
+ 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.0f)
+ return 0.0f;
+ return seamFactor / totalLength;
+ }
+
+ float evaluateTextureSeamMetric(Chart *chart, uint32_t f) const
+ {
+ float seamLength = 0.0f;
+ float totalLength = 0.0f;
+ for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) {
+ if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()])
+ continue;
+ if (m_faceChartArray[it.oppositeFace()] != chart->id)
+ continue;
+ float l = m_edgeLengths[it.edge()];
+ totalLength += l;
+ if (!it.isSeam())
+ continue;
+ // Make sure it's a texture seam.
+ if (it.isTextureSeam())
+ seamLength += l;
+ }
+ if (seamLength == 0.0f)
+ return 0.0f; // Avoid division by zero.
+ return seamLength / totalLength;
+ }
+
+ float computeBoundaryLength(Chart *chart, uint32_t f) const
+ {
+ float boundaryLength = chart->boundaryLength;
+ // Add new edges, subtract edges shared with the chart.
+ 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 {
+ if (m_faceChartArray[it.oppositeFace()] != chart->id)
+ boundaryLength += edgeLength;
+ else
+ boundaryLength -= edgeLength;
+ }
+ }
+ return max(0.0f, boundaryLength); // @@ Hack!
+ }
+
+ void mergeChart(Chart *owner, Chart *chart, float sharedBoundaryLength)
+ {
+ const uint32_t faceCount = chart->faces.size();
+ for (uint32_t i = 0; i < faceCount; i++) {
+ uint32_t f = chart->faces[i];
+ 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->averageNormal = normalizeSafe(owner->normalSum, Vector3(0), 0.0f);
+ // Delete chart.
+ m_chartArray[chart->id] = nullptr;
+ chart->~Chart();
+ 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<Vector3> m_faceTangents;
+ Array<Vector3> m_faceBitangents;
+ Array<Vector2> m_texcoords;
+ uint32_t m_facesLeft;
+ Array<int> m_faceChartArray;
+ Array<Chart *> m_chartArray;
+ PriorityQueue m_bestTriangles;
+ KISSRng m_rand;
+ ChartOptions m_options;
+ Array<Chart *> m_faceCandidateCharts;
+ Array<float> m_faceCandidateCosts;
+#if XA_GROW_CHARTS_COPLANAR
+ Array<uint32_t> m_nextPlanarRegionFace;
+#endif
+ Array<uint32_t> m_tempEdges1, m_tempEdges2;
+};
+
+} // namespace segment
+
+namespace param {
+
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 +5138,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 +5158,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 +5174,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 +5271,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,13 +5299,13 @@ 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
sparse::saxpy(alpha, p, x);
if ((i & 31) == 0) { // recompute r after 32 steps
- // r = b - A·x
+ // r = b - A·x
sparse::copy(b, r);
sparse::sgemv(-1, A, x, 1, r);
} else {
@@ -4609,59 +5326,57 @@ 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 +5393,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 +5424,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 +5464,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,1653 +5482,622 @@ 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).
-// - Resorting is n*log(n)
-// @@ Number of elements in the queue is usually small, and we'd have to rebalance often. I'm not sure it's worth implementing a heap.
-// @@ Searcing at removal would remove the need for sorting when priorities change.
-struct PriorityQueue
-{
- PriorityQueue(uint32_t size = UINT_MAX) : maxSize(size) {}
-
- void push(float priority, uint32_t face)
- {
- uint32_t i = 0;
- const uint32_t count = pairs.size();
- for (; i < count; i++) {
- if (pairs[i].priority > priority) break;
- }
- Pair p = { priority, face };
- pairs.insert(pairs.begin() + i, p);
- if (pairs.size() > maxSize) {
- pairs.erase(pairs.begin());
- }
- }
-
- // push face out of order, to be sorted later.
- void push(uint32_t face)
- {
- Pair p = { 0.0f, face };
- pairs.push_back(p);
- }
-
- uint32_t pop()
- {
- uint32_t f = pairs.back().face;
- pairs.pop_back();
- return f;
- }
-
- void sort()
- {
- //sort(pairs); // @@ My intro sort appears to be much slower than it should!
- std::sort(pairs.begin(), pairs.end());
- }
-
- void clear()
- {
- pairs.clear();
- }
-
- uint32_t count() const
- {
- return pairs.size();
- }
-
- float firstPriority() const
- {
- return pairs.back().priority;
- }
-
- const uint32_t maxSize;
-
- struct Pair
- {
- bool operator <(const Pair &p) const
- {
- return priority > p.priority; // !! Sort in inverse priority order!
- }
-
- float priority;
- uint32_t face;
- };
-
- std::vector<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;
- PriorityQueue candidates;
+// 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;
};
-struct AtlasBuilder
+static ParameterizationQuality calculateParameterizationQuality(const Mesh *mesh, uint32_t faceCount, Array<uint32_t> *flippedFaces)
{
- AtlasBuilder(const halfedge::Mesh *m) : mesh(m), facesLeft(m->faceCount())
- {
- const uint32_t faceCount = m->faceCount();
- faceChartArray.resize(faceCount, -1);
- faceCandidateArray.resize(faceCount, (uint32_t)-1);
- // @@ 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();
- }
- }
-
- ~AtlasBuilder()
- {
- const uint32_t chartCount = chartArray.size();
- for (uint32_t i = 0; i < chartCount; i++) {
- delete chartArray[i];
- }
- }
-
- void markUnchartedFaces(const std::vector<uint32_t> &unchartedFaces)
- {
- 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;
- }
-
- void computeShortestPaths()
- {
- const uint32_t faceCount = mesh->faceCount();
- shortestPaths.resize(faceCount * faceCount, FLT_MAX);
- // Fill edges:
- 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);
- }
- }
- }
- // 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]);
- }
- }
- }
- }
-
- void placeSeeds(float threshold, uint32_t maxSeedCount)
- {
- // 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.
- break;
- }
- createRandomChart(threshold);
- }
- }
-
- void createRandomChart(float threshold)
- {
- ChartBuildData *chart = new ChartBuildData(chartArray.size());
- 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);
- // Grow the chart as much as possible within the given threshold.
- growChart(chart, threshold * 0.5f, facesLeft);
- //growCharts(threshold - threshold * 0.75f / chartCount(), facesLeft);
- }
-
- void addFaceToChart(ChartBuildData *chart, uint32_t f, bool recomputeProxy = false)
- {
- // Add face to chart.
- chart->faces.push_back(f);
- xaDebugAssert(faceChartArray[f] == -1);
- faceChartArray[f] = chart->id;
- 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);
- if (recomputeProxy) {
- // Update proxy and candidate's priorities.
- updateProxy(chart);
- }
- // Update candidates.
- removeCandidate(f);
- updateCandidates(chart, f);
- 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) {
- return false;
- }
- uint32_t f = chart->candidates.pop();
- if (faceChartArray[f] == -1) {
- addFaceToChart(chart, f);
- i++;
- }
- }
- 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)
- {
- 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);
- }
- }
- }
- }
-
- void updateProxies()
- {
- const uint32_t chartCount = chartArray.size();
- for (uint32_t i = 0; i < chartCount; i++) {
- updateProxy(chartArray[i]);
- }
- }
-
- void updateProxy(ChartBuildData *chart)
- {
- //#pragma message(NV_FILE_LINE "TODO: Use best fit plane instead of average normal.")
- chart->planeNormal = 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();
- for (uint32_t i = 0; i < faceCount; i++) {
- float priority = evaluateProxyFitMetric(chart, chart->faces[i]);
- bestTriangles.push(priority, chart->faces[i]);
- }
- // Of those, choose the most central triangle.
- uint32_t mostCentral;
- float maxDistance = -1;
- const uint32_t bestCount = 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);
- if (distance > maxDistance) {
- maxDistance = distance;
- mostCentral = bestTriangles.pairs[i].face;
- }
- }
- xaDebugAssert(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;
- }
- }
-
- void updatePriorities(ChartBuildData *chart)
- {
- // 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);
- }
- }
- // Sort candidates.
- chart->candidates.sort();
- }
-
- // Evaluate combined metric.
- float evaluatePriority(ChartBuildData *chart, uint32_t face)
- {
- // 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);
- // Penalize faces that cross seams, reward faces that close seams or reach boundaries.
- float N = evaluateNormalSeamMetric(chart, face);
- float T = 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));
- return cost;
- }
-
- // Returns a value in [0-1].
- float evaluateProxyFitMetric(ChartBuildData *chart, uint32_t f)
- {
- const halfedge::Face *face = mesh->faceAt(f);
- Vector3 faceNormal = face->triangleNormal();
- // Use plane fitting metric for now:
- return 1 - dot(faceNormal, chart->planeNormal); // @@ normal deviations should be weighted by face area
- }
-
- float evaluateRoundnessMetric(ChartBuildData *chart, uint32_t /*face*/, float newBoundaryLength, float newChartArea)
- {
- float roundness = square(chart->boundaryLength) / chart->area;
- float newRoundness = square(newBoundaryLength) / newChartArea;
- if (newRoundness > roundness) {
- return square(newBoundaryLength) / (newChartArea * 4 * PI);
- } else {
- // Offer no impedance to faces that improve roundness.
- return 0;
- }
- }
-
- float evaluateStraightnessMetric(ChartBuildData *chart, uint32_t f)
- {
- 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()) {
- l_out += l;
- } else {
- uint32_t neighborFaceId = edge->pair->face->id;
- if (faceChartArray[neighborFaceId] != chart->id) {
- l_out += l;
- } else {
- l_in += l;
- }
- }
+ XA_DEBUG_ASSERT(mesh != nullptr);
+ ParameterizationQuality quality;
+ uint32_t firstBoundaryEdge = UINT32_MAX;
+ for (uint32_t e = 0; e < mesh->edgeCount(); e++) {
+ if (mesh->isBoundaryEdge(e)) {
+ firstBoundaryEdge = e;
+ break;
}
- xaDebugAssert(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.
}
-
- float evaluateNormalSeamMetric(ChartBuildData *chart, uint32_t f)
- {
- 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()) {
- continue;
- }
- const uint32_t neighborFaceId = edge->pair->face->id;
- if (faceChartArray[neighborFaceId] != chart->id) {
+ 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;
- }
- //float l = edge->length();
- float l = edgeLengths[edge->id / 2];
- totalLength += l;
- if (!edge->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;
- seamFactor += l;
+ 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 (seamFactor == 0) return 0.0f;
- return seamFactor / totalLength;
+ if (quality.boundaryIntersection)
+ break;
}
-
- float evaluateTextureSeamMetric(ChartBuildData *chart, uint32_t f)
- {
- 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()) {
- continue;
- }
- const uint32_t neighborFaceId = edge->pair->face->id;
- if (faceChartArray[neighborFaceId] != chart->id) {
- continue;
- }
- //float l = edge->length();
- float l = edgeLengths[edge->id / 2];
- totalLength += l;
- if (!edge->isSeam()) {
- continue;
- }
- // Make sure it's a texture seam.
- if (edge->isTextureSeam()) {
- seamLength += l;
- }
+ 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);
}
- if (seamLength == 0.0f) {
- return 0.0f; // Avoid division by zero.
+ 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;
}
- return seamLength / totalLength;
- }
-
- float evaluateChartArea(ChartBuildData *chart, uint32_t f)
- {
- const halfedge::Face *face = mesh->faceAt(f);
- return chart->area + faceAreas[face->id];
- }
-
- float evaluateBoundaryLength(ChartBuildData *chart, uint32_t f)
- {
- 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()) {
- boundaryLength += edgeLength;
- } else {
- uint32_t neighborFaceId = edge->pair->face->id;
- if (faceChartArray[neighborFaceId] != chart->id) {
- boundaryLength += edgeLength;
- } else {
- boundaryLength -= edgeLength;
- }
- }
+ if (parametricArea < 0.0f) {
+ // Count flipped triangles.
+ quality.flippedTriangleCount++;
+ if (flippedFaces)
+ flippedFaces->push_back(f);
+ parametricArea = fabsf(parametricArea);
}
- 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();
- }
-
- Vector3 evaluateChartCentroidSum(ChartBuildData *chart, uint32_t f)
- {
- 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();
+ 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;
}
- return centroid / float(faceCount);
+ quality.authalicMetric += (sigma1 * sigma2) * geometricArea;
+ // Accumulate total areas.
+ quality.geometricArea += geometricArea;
+ quality.parametricArea += parametricArea;
+ //triangleConformalEnergy(q, p);
}
-
- void fillHoles(float threshold)
- {
- while (facesLeft > 0)
- createRandomChart(threshold);
+ if (quality.flippedTriangleCount + quality.zeroAreaTriangleCount == quality.totalTriangleCount) {
+ // If all triangles are flipped, then none are.
+ if (flippedFaces)
+ flippedFaces->clear();
+ quality.flippedTriangleCount = 0;
}
-
- void mergeCharts()
+ if (quality.flippedTriangleCount > quality.totalTriangleCount / 2)
{
- 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;
+ // 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->copyTo(temp);
+ 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;
}
}
- }
- }
- // 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++;
- }
- }
- }
-
- // @@ Cleanup.
- struct Candidate {
- uint32_t face;
- ChartBuildData *chart;
- float metric;
- };
-
- // @@ Get N best candidates in one pass.
- const Candidate &getBestCandidate() const
- {
- uint32_t best = 0;
- float bestCandidateMetric = FLT_MAX;
- const uint32_t candidateCount = candidateArray.size();
- xaAssert(candidateCount > 0);
- for (uint32_t i = 0; i < candidateCount; i++) {
- const Candidate &candidate = candidateArray[i];
- if (candidate.metric < bestCandidateMetric) {
- bestCandidateMetric = candidate.metric;
- best = i;
- }
- }
- return candidateArray[best];
- }
-
- void removeCandidate(uint32_t f)
- {
- int c = faceCandidateArray[f];
- if (c != -1) {
- faceCandidateArray[f] = (uint32_t)-1;
- if (c == int(candidateArray.size() - 1)) {
- candidateArray.pop_back();
- } else {
- // Replace with last.
- candidateArray[c] = candidateArray[candidateArray.size() - 1];
- candidateArray.pop_back();
- faceCandidateArray[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;
- } else {
- int c = faceCandidateArray[f];
- xaDebugAssert(c != -1);
- Candidate &candidate = candidateArray[c];
- xaDebugAssert(candidate.face == f);
- if (metric < candidate.metric || chart == candidate.chart) {
- candidate.metric = metric;
- candidate.chart = chart;
- }
- }
+ 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;
+}
- void mergeChart(ChartBuildData *owner, ChartBuildData *chart, float sharedBoundaryLength)
+struct ChartWarningFlags
+{
+ enum Enum
{
- 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;
- 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);
- }
-
-
- uint32_t chartCount() const { return chartArray.size(); }
- const std::vector<uint32_t> &chartFaces(uint32_t i) const { return chartArray[i]->faces; }
-
- 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;
+ 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 segment::Atlas *atlas, const Mesh *originalMesh, uint32_t chartIndex, uint32_t meshId, uint32_t chartGroupId, uint32_t chartId) : m_mesh(nullptr), m_unifiedMesh(nullptr), m_isDisk(false), m_isOrtho(false), m_isPlanar(false), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0)
{
+ XA_UNUSED(meshId);
+ XA_UNUSED(chartGroupId);
+ XA_UNUSED(chartId);
+ m_basis = atlas->chartBasis(chartIndex);
+ atlas->chartFaces(chartIndex).copyTo(m_faceArray);
// 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_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
+ m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
+ Array<uint32_t> chartMeshIndices;
+ chartMeshIndices.resize(originalMesh->vertexCount());
+ chartMeshIndices.setAll(UINT32_MAX);
+ Array<uint32_t> unifiedMeshIndices;
+ unifiedMeshIndices.resize(originalMesh->vertexCount());
+ unifiedMeshIndices.setAll(UINT32_MAX);
// Add vertices.
- const uint32_t faceCount = faceArray.size();
+ const uint32_t faceCount = m_initialFaceCount = m_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(m_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()));
+#if XA_SKIP_PARAMETERIZATION
+ m_unifiedMesh->addVertex(originalMesh->position(vertex), Vector3(0.0f), atlas->faceTexcoords(m_faceArray[f])[i]);
+#else
+ m_unifiedMesh->addVertex(originalMesh->position(vertex));
+#endif
}
- 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(m_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();
+ m_initialFaceCount = m_unifiedMesh->faceCount(); // Fixing t-junctions rewrites faces.
+ }
+ // 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, m_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
+ ~Chart()
{
- 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
- {
- 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 &paramQuality() const { return m_paramQuality; }
+#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION
+ const Array<uint32_t> &paramFlippedFaces() 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
+ void evaluateOrthoParameterizationQuality()
{
- return m_chartToOriginalMap[i];
- }
- uint32_t mapChartVertexToUnifiedVertex(uint32_t i) const
- {
- return m_chartToUnifiedMap[i];
+ XA_PROFILE_START(parameterizeChartsEvaluateQuality)
+ m_paramQuality = calculateParameterizationQuality(m_unifiedMesh, m_initialFaceCount, 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_initialFaceCount, &m_paramFlippedFaces);
+#else
+ m_paramQuality = calculateParameterizationQuality(m_unifiedMesh, m_initialFaceCount, 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;
- }
+ Basis m_basis;
+ Mesh *m_mesh;
+ Mesh *m_unifiedMesh;
+ bool m_isDisk, m_isOrtho, m_isPlanar;
+ uint32_t m_warningFlags;
+ uint32_t m_initialFaceCount; // Before fixing T-junctions and/or closing holes.
+ uint32_t m_closedHolesCount, m_fixedTJunctionsCount;
- 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;
-
- 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 segment::Atlas *atlas;
+ const Mesh *mesh;
+ uint32_t chartIndex; // In the atlas.
+ 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_ARGS(MemTag::Default, Chart, args->atlas, args->mesh, args->chartIndex, 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_ARGS(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());
+ meshIndices.setAll((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,1327 +6158,2530 @@ 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_ARGS(MemTag::Default, Chart, m_mesh, chartFaces, m_sourceId, m_id, 0);
+ m_chartArray.push_back(chart);
+#else
+ XA_PROFILE_START(buildAtlas)
+ segment::Atlas atlas(m_mesh, nullptr, options);
+ buildAtlas(atlas, options);
+ XA_PROFILE_END(buildAtlas)
+ const uint32_t chartCount = atlas.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.atlas = &atlas;
+ args.mesh = m_mesh;
+ args.chartIndex = 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++)
- {
+#if XA_SKIP_PARAMETERIZATION
+ XA_UNUSED(taskScheduler);
+ XA_UNUSED(func);
+ 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");
+ chart->evaluateOrthoParameterizationQuality();
+ chart->evaluateParameterizationQuality();
+ chart->transferParameterization();
+ }
+#else
+ 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];
+ 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;
+ segment::Atlas atlas(m_mesh, &meshFaces, options);
+ buildAtlas(atlas, options);
+ for (uint32_t j = 0; j < atlas.chartCount(); j++) {
+ Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, &atlas, m_mesh, 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
}
- 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());
+ // 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++;
+ }
+#endif // XA_RECOMPUTE_CHARTS
+#endif // XA_SKIP_PARAMETERIZATION
}
- uint32_t faceChartAt(uint32_t i) const
- {
- return m_faceChart[i];
- }
- uint32_t faceIndexWithinChartAt(uint32_t i) const
+private:
+ void buildAtlas(segment::Atlas &atlas, const ChartOptions &options)
{
- return m_faceIndex[i];
+ if (atlas.facesLeft() == 0)
+ return;
+ // Create initial charts greedely.
+ atlas.placeSeeds(options.maxThreshold * 0.5f);
+ if (options.maxIterations == 0) {
+ XA_DEBUG_ASSERT(atlas.facesLeft() == 0);
+ return;
+ }
+ atlas.relocateSeeds();
+ atlas.resetCharts();
+ // Restart process growing charts in parallel.
+ uint32_t iteration = 0;
+ while (true) {
+ if (!atlas.growCharts(options.maxThreshold)) {
+ // If charts cannot grow more: fill holes, merge charts, relocate seeds and start new iteration.
+ atlas.fillHoles(options.maxThreshold * 0.5f);
+#if XA_MERGE_CHARTS
+ atlas.mergeCharts();
+#endif
+ if (++iteration == options.maxIterations)
+ break;
+ if (!atlas.relocateSeeds())
+ break;
+ atlas.resetCharts();
+ }
+ }
+ // Make sure no holes are left!
+ XA_DEBUG_ASSERT(atlas.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;
+};
+
+static void runCreateChartGroupTask(void *userData)
+{
+ XA_PROFILE_START(addMeshCreateChartGroupsThread)
+ auto args = (CreateChartGroupTaskArgs *)userData;
+ *(args->chartGroup) = XA_NEW_ARGS(MemTag::Default, ChartGroup, args->groupId, args->mesh, args->faceGroup);
+ XA_PROFILE_END(addMeshCreateChartGroupsThread)
+}
- std::vector<Chart *> m_chartArray;
+struct ComputeChartsTaskArgs
+{
+ TaskScheduler *taskScheduler;
+ ChartGroup *chartGroup;
+ const ChartOptions *options;
+ Progress *progress;
+};
- std::vector<uint32_t> m_chartVertexCountPrefixSum;
- uint32_t m_totalVertexCount;
+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();
+}
- 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.
+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()
- {
- for (size_t i = 0; i < m_meshChartsArray.size(); i++)
- delete m_meshChartsArray[i];
- }
-
- uint32_t meshCount() const
- {
- return m_meshChartsArray.size();
- }
+ Atlas() : m_meshCount(0), m_chartsComputed(false), m_chartsParameterized(false) {}
- const MeshCharts *meshAt(uint32_t i) const
+ ~Atlas()
{
- return m_meshChartsArray[i];
+ for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
+ m_chartGroups[i]->~ChartGroup();
+ XA_FREE(m_chartGroups[i]);
+ }
}
- MeshCharts *meshAt(uint32_t i)
- {
- return m_meshChartsArray[i];
- }
+ bool chartsComputed() const { return m_chartsComputed; }
+ bool chartsParameterized() const { return m_chartsParameterized; }
+ uint32_t chartGroupCount() const { return m_chartGroups.size(); }
+ const ChartGroup *chartGroupAt(uint32_t index) const { return m_chartGroups[index]; }
- uint32_t chartCount() const
+ uint32_t chartGroupCount(uint32_t mesh) 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++) {
+ if (m_chartGroupSourceMeshes[i] == mesh)
+ count++;
}
return count;
}
- const Chart *chartAt(uint32_t i) const
+ const ChartGroup *chartGroupAt(uint32_t mesh, uint32_t group) const
{
- 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);
- }
- i -= count;
+ 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 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;
+ }
+ }
+ 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_meshCount++;
+ m_addMeshMutex.unlock();
+ }
+
+ // Chart id/index is determined by depth-first hierarchy of mesh -> chart group -> chart.
+ // For chart index to be consistent here, chart groups needs to sorted by mesh index. Since addMesh is called by multithreaded tasks, order is indeterminate, so chart groups need to be explicitly sorted after all meshes are added.
+ void sortChartGroups()
+ {
+ Array<ChartGroup *> oldChartGroups;
+ oldChartGroups.resize(m_chartGroups.size());
+ memcpy(oldChartGroups.data(), m_chartGroups.data(), sizeof(ChartGroup *) * m_chartGroups.size());
+ Array<uint32_t> oldChartGroupSourceMeshes;
+ oldChartGroupSourceMeshes.resize(m_chartGroupSourceMeshes.size());
+ memcpy(oldChartGroupSourceMeshes.data(), m_chartGroupSourceMeshes.data(), sizeof(uint32_t) * m_chartGroupSourceMeshes.size());
+ uint32_t current = 0;
+ for (uint32_t i = 0; i < m_meshCount; i++) {
+ for (uint32_t j = 0; j < oldChartGroups.size(); j++) {
+ if (oldChartGroupSourceMeshes[j] == i) {
+ m_chartGroups[current] = oldChartGroups[j];
+ m_chartGroupSourceMeshes[current] = oldChartGroupSourceMeshes[j];
+ current++;
+ }
}
- i -= count;
}
- return NULL;
}
- // Add mesh charts and takes ownership.
- // Extract the charts and add to this atlas.
- void addMeshCharts(MeshCharts *meshCharts)
+ 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;
+ m_chartsParameterized = true;
+ return true;
+ }
+
+private:
+ std::mutex m_addMeshMutex;
+ uint32_t m_meshCount;
+ bool m_chartsComputed;
+ bool m_chartsParameterized;
+ Array<ChartGroup *> m_chartGroups;
+ RadixSort m_chartGroupsRadix; // By mesh indexCount.
+ Array<uint32_t> m_chartGroupSourceMeshes;
+};
+
+} // 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)
+ {
+ m_data.resize(m_width * m_height);
+ memset(m_data.data(), 0, sizeof(uint32_t) * m_data.size());
+ }
+
+ void resize(uint32_t width, uint32_t height)
{
- m_meshChartsArray.push_back(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;
+ data.moveTo(m_data);
}
- void extractCharts(const halfedge::Mesh *mesh)
+ void addChart(uint32_t chartIndex, const BitImage *image, const BitImage *imageBilinear, const BitImage *imagePadding, int atlas_w, int atlas_h, int offset_x, int offset_y)
{
- MeshCharts *meshCharts = new MeshCharts(mesh);
- meshCharts->extractCharts();
- addMeshCharts(meshCharts);
+ 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) {
+ const uint32_t dataOffset = xx + yy * m_width;
+ if (image->bitAt(x, y)) {
+ XA_DEBUG_ASSERT(m_data[dataOffset] == 0);
+ m_data[dataOffset] = chartIndex | kImageHasChartIndexBit;
+ } else if (imageBilinear && imageBilinear->bitAt(x, y)) {
+ XA_DEBUG_ASSERT(m_data[dataOffset] == 0);
+ m_data[dataOffset] = chartIndex | kImageHasChartIndexBit | kImageIsBilinearBit;
+ } else if (imagePadding && imagePadding->bitAt(x, y)) {
+ XA_DEBUG_ASSERT(m_data[dataOffset] == 0);
+ m_data[dataOffset] = chartIndex | kImageHasChartIndexBit | kImageIsPaddingBit;
+ }
+ }
+ }
+ }
}
- void computeCharts(const halfedge::Mesh *mesh, const CharterOptions &options, const std::vector<uint32_t> &unchartedMaterialArray)
+ void copyTo(uint32_t *dest, uint32_t destWidth, uint32_t destHeight, int padding) const
{
- MeshCharts *meshCharts = new MeshCharts(mesh);
- meshCharts->computeCharts(options, unchartedMaterialArray);
- addMeshCharts(meshCharts);
+ for (uint32_t y = 0; y < destHeight; y++)
+ memcpy(&dest[y * destWidth], &m_data[padding + (y + padding) * m_width], destWidth * sizeof(uint32_t));
}
- void parameterizeCharts()
+#if XA_DEBUG_EXPORT_ATLAS_IMAGES
+ void writeTga(const char *filename, uint32_t width, uint32_t height) const
{
- for (uint32_t i = 0; i < m_meshChartsArray.size(); i++) {
- m_meshChartsArray[i]->parameterizeCharts();
+ 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];
+ uint8_t *bgr = &image[(x + y * width) * 3];
+ if (data == 0) {
+ bgr[0] = bgr[1] = bgr[2] = 0;
+ continue;
+ }
+ const uint32_t chartIndex = data & kImageChartIndexMask;
+ if (data & kImageIsPaddingBit) {
+ bgr[0] = 0;
+ bgr[1] = 0;
+ bgr[2] = 255;
+ } else if (data & kImageIsBilinearBit) {
+ bgr[0] = 0;
+ bgr[1] = 255;
+ bgr[2] = 0;
+ } else {
+ const int mix = 192;
+ srand((unsigned int)chartIndex);
+ bgr[0] = uint8_t((rand() % 255 + mix) * 0.5f);
+ bgr[1] = uint8_t((rand() % 255 + mix) * 0.5f);
+ bgr[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 AtlasPacker
+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;
+ // UvMeshChart only
+ Array<uint32_t> faces;
+
+ Vector2 &uniqueVertexAt(uint32_t v) { return uniqueVertices.isEmpty() ? vertices[v] : vertices[uniqueVertices[v]]; }
+ uint32_t uniqueVertexCount() const { return uniqueVertices.isEmpty() ? vertexCount : uniqueVertices.size(); }
+};
+
+struct AddChartTaskArgs
+{
+ param::Chart *paramChart;
+ Chart *chart; // out
+};
+
+static void runAddChartTask(void *userData)
+{
+ XA_PROFILE_START(packChartsAddChartsThread)
+ auto args = (AddChartTaskArgs *)userData;
+ param::Chart *paramChart = args->paramChart;
+ XA_PROFILE_START(packChartsAddChartsRestoreTexcoords)
+ paramChart->transferParameterization();
+ XA_PROFILE_END(packChartsAddChartsRestoreTexcoords)
+ Mesh *mesh = paramChart->mesh();
+ Chart *chart = args->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.
+ static thread_local BoundingBox2D boundingBox;
+ boundingBox.compute(boundary.data(), boundary.size(), mesh->texcoords(), mesh->vertexCount());
+ chart->majorAxis = boundingBox.majorAxis();
+ chart->minorAxis = boundingBox.minorAxis();
+ chart->minCorner = boundingBox.minCorner();
+ chart->maxCorner = boundingBox.maxCorner();
+ XA_PROFILE_END(packChartsAddChartsThread)
+}
+
+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, allowRotate;
+ uint32_t maxResolution;
+ // out
+ bool best_insideAtlas;
+ int best_metric, best_x, best_y, best_w, best_h, best_r;
+};
+
+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++) {
+ if (args->finished->load())
+ break;
+ 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) {
+ if (args->maxResolution > 0 && (x > (int)args->maxResolution - cw || y > (int)args->maxResolution - 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_atlasImages.size(); i++) {
+ m_atlasImages[i]->~AtlasImage();
+ XA_FREE(m_atlasImages[i]);
+ }
+ 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 addCharts(TaskScheduler *taskScheduler, param::Atlas *paramAtlas)
+ {
+ // Count charts.
+ uint32_t chartCount = 0;
+ const uint32_t chartGroupsCount = paramAtlas->chartGroupCount();
+ for (uint32_t i = 0; i < chartGroupsCount; i++) {
+ const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i);
+ if (chartGroup->isVertexMap())
+ continue;
+ chartCount += chartGroup->chartCount();
+ }
+ if (chartCount == 0)
+ return;
+ // Run one task per chart.
+ Array<AddChartTaskArgs> taskArgs;
+ taskArgs.resize(chartCount);
+ TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount);
+ uint32_t chartIndex = 0;
+ for (uint32_t i = 0; i < chartGroupsCount; i++) {
+ const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i);
+ if (chartGroup->isVertexMap())
+ continue;
+ const uint32_t count = chartGroup->chartCount();
+ for (uint32_t j = 0; j < count; j++) {
+ AddChartTaskArgs &args = taskArgs[chartIndex];
+ args.paramChart = chartGroup->chartAt(j);
+ Task task;
+ task.userData = &taskArgs[chartIndex];
+ task.func = runAddChartTask;
+ taskScheduler->run(taskGroup, task);
+ chartIndex++;
+ }
+ }
+ taskScheduler->wait(&taskGroup);
+ // Get task output.
+ m_charts.resize(chartCount);
+ for (uint32_t i = 0; i < chartCount; i++)
+ m_charts[i] = taskArgs[i].chart;
+ }
+
+ void addUvMeshCharts(UvMeshInstance *mesh)
+ {
+ BitArray vertexUsed(mesh->texcoords.size());
+ Array<Vector2> boundary;
+ boundary.reserve(16);
+ BoundingBox2D boundingBox;
+ 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;
+ chart->faces.resize(uvChart->faces.size());
+ memcpy(chart->faces.data(), uvChart->faces.data(), sizeof(uint32_t) * uvChart->faces.size());
+ // 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.
+ boundingBox.compute(boundary.data(), boundary.size(), boundary.data(), boundary.size());
+ chart->majorAxis = boundingBox.majorAxis();
+ chart->minorAxis = boundingBox.minorAxis();
+ chart->minCorner = boundingBox.minCorner();
+ chart->maxCorner = 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;
+ }
+ // Estimate resolution and/or texels per unit if not specified.
+ m_texelsPerUnit = options.texelsPerUnit;
+ uint32_t resolution = options.resolution > 0 ? options.resolution + options.padding * 2 : 0;
+ const uint32_t maxResolution = m_texelsPerUnit > 0.0f ? resolution : 0;
+ 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];
+ // Compute chart scale
+ float scale = (chart->surfaceArea / chart->parametricArea) * m_texelsPerUnit;
+ if (chart->parametricArea == 0.0f)
+ scale = 0;
+ XA_ASSERT(isFinite(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.0f && texcoord.y >= 0.0f);
+ XA_DEBUG_ASSERT(isFinite(texcoord.x) && isFinite(texcoord.y));
+ extents = max(extents, texcoord);
+ }
+ XA_DEBUG_ASSERT(extents.x >= 0 && extents.y >= 0);
+ // 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.
+ if (extents.x > 0.0f && extents.y > 0.0f) {
+ // Block align: align all chart extents to 4x4 blocks, but taking padding and texel center offset into account.
+ const int blockAlignSizeOffset = options.padding * 2 + 1;
+ int width = ftoi_ceil(extents.x);
+ if (options.blockAlign)
+ width = align(width + blockAlignSizeOffset, 4) - blockAlignSizeOffset;
+ int height = ftoi_ceil(extents.y);
+ if (options.blockAlign)
+ height = align(height + blockAlignSizeOffset, 4) - blockAlignSizeOffset;
+ for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) {
+ Vector2 &texcoord = chart->uniqueVertexAt(v);
+ texcoord.x = texcoord.x / extents.x * (float)width;
+ texcoord.y = texcoord.y / extents.y * (float)height;
+ }
+ extents.x = (float)width;
+ extents.y = (float)height;
+ }
+ // Limit chart size, either to PackOptions::maxChartSize or maxResolution (if set), whichever is smaller.
+ // If limiting chart size to maxResolution, print a warning, since that may not be desirable to the user.
+ uint32_t maxChartSize = options.maxChartSize;
+ bool warnChartResized = false;
+ if (maxResolution > 0 && (maxChartSize == 0 || maxResolution < maxChartSize)) {
+ maxChartSize = maxResolution - options.padding * 2; // Don't include padding.
+ warnChartResized = true;
+ }
+ if (maxChartSize > 0) {
+ const float realMaxChartSize = (float)maxChartSize - 1.0f; // Aligning to texel centers increases texel footprint by 1.
+ if (extents.x > realMaxChartSize || extents.y > realMaxChartSize) {
+ if (warnChartResized)
+ XA_PRINT(" Resizing chart %u from %gx%g to %ux%u to fit atlas\n", c, extents.x, extents.y, maxChartSize, maxChartSize);
+ scale = realMaxChartSize / max(extents.x, extents.y);
+ for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) {
+ Vector2 &texcoord = chart->uniqueVertexAt(i);
+ texcoord = min(texcoord * scale, Vector2(realMaxChartSize));
}
}
- 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));
- }
+ // Align to texel centers and add padding offset.
+ extents.x = extents.y = 0.0f;
+ for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) {
+ Vector2 &texcoord = chart->uniqueVertexAt(v);
+ texcoord.x += 0.5f + options.padding;
+ texcoord.y += 0.5f + options.padding;
+ extents = max(extents, texcoord);
+ }
+ chartExtents[c] = extents;
+ chartOrderArray[c] = extents.x + extents.y; // Use perimeter for chart sort key.
+ 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
+ // chartImage: result from conservative rasterization
+ // chartImageBilinear: chartImage plus any texels that would be sampled by bilinear filtering.
+ // chartImagePadding: either chartImage or chartImageBilinear depending on options, with a dilate filter applied options.padding times.
+ // Rotated versions swap x and y.
+ BitImage chartImage, chartImageBilinear, chartImagePadding;
+ BitImage chartImageRotated, chartImageBilinearRotated, chartImagePaddingRotated;
+ Array<Vector2i> atlasSizes;
+ atlasSizes.push_back(Vector2i(0, 0));
+ 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)
+ // Resize and clear (discard = true) chart images.
+ // Leave room for padding at extents.
+ chartImage.resize(ftoi_ceil(chartExtents[c].x) + options.padding, ftoi_ceil(chartExtents[c].y) + options.padding, true);
+ if (chart->allowRotate)
+ chartImageRotated.resize(chartImage.height(), chartImage.width(), true);
+ if (options.bilinear) {
+ chartImageBilinear.resize(chartImage.width(), chartImage.height(), true);
+ if (chart->allowRotate)
+ chartImageBilinearRotated.resize(chartImage.height(), chartImage.width(), true);
+ }
+ // Rasterize chart faces.
+ const uint32_t faceCount = chart->indexCount / 3;
+ for (uint32_t f = 0; f < faceCount; f++) {
+ Vector2 vertices[3];
+ for (uint32_t v = 0; v < 3; v++)
+ vertices[v] = chart->vertices[chart->indices[f * 3 + v]];
+ DrawTriangleCallbackArgs args;
+ args.chartBitImage = &chartImage;
+ args.chartBitImageRotated = chart->allowRotate ? &chartImageRotated : nullptr;
+ raster::drawTriangle(Vector2((float)chartImage.width(), (float)chartImage.height()), vertices, drawTriangleCallback, &args);
+ }
+ // Expand chart by pixels sampled by bilinear interpolation.
+ if (options.bilinear)
+ bilinearExpand(chart, &chartImage, &chartImageBilinear, chart->allowRotate ? &chartImageBilinearRotated : nullptr);
+ // Expand chart by padding pixels (dilation).
+ if (options.padding > 0) {
+ // Copy into the same BitImage instances for every chart to avoid reallocating BitImage buffers (largest chart is packed first).
+ XA_PROFILE_START(packChartsDilate)
+ if (options.bilinear)
+ chartImageBilinear.copyTo(chartImagePadding);
+ else
+ chartImage.copyTo(chartImagePadding);
+ chartImagePadding.dilate(options.padding);
+ if (chart->allowRotate) {
+ if (options.bilinear)
+ chartImageBilinearRotated.copyTo(chartImagePaddingRotated);
+ else
+ chartImageRotated.copyTo(chartImagePaddingRotated);
+ chartImagePaddingRotated.dilate(options.padding);
}
- 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_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++;
+ }
+ }
+ // Find a location to place the chart in the atlas.
+ BitImage *chartImageToPack, *chartImageToPackRotated;
+ if (options.padding > 0) {
+ chartImageToPack = &chartImagePadding;
+ chartImageToPackRotated = &chartImagePaddingRotated;
+ } else if (options.bilinear) {
+ chartImageToPack = &chartImageBilinear;
+ chartImageToPackRotated = &chartImageBilinearRotated;
+ } else {
+ chartImageToPack = &chartImage;
+ chartImageToPackRotated = &chartImageRotated;
+ }
+ 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;
+ XA_UNUSED(firstChartInBitImage);
+ if (currentAtlas + 1 > m_bitImages.size()) {
+ // Chart doesn't fit in the current bitImage, create a new one.
+ BitImage *bi = XA_NEW_ARGS(MemTag::Default, BitImage, resolution, resolution);
+ m_bitImages.push_back(bi);
+ atlasSizes.push_back(Vector2i(0, 0));
+ firstChartInBitImage = true;
+ if (createImage)
+ m_atlasImages.push_back(XA_NEW_ARGS(MemTag::Default, AtlasImage, resolution, resolution));
+ // Start positions are per-atlas, so create a new one of those too.
+ chartStartPositions.push_back(Vector2i(0, 0));
+ }
+ XA_PROFILE_START(packChartsFindLocation)
+ const bool foundLocation = findChartLocation(taskScheduler, chartStartPositions[currentAtlas], options.bruteForce, m_bitImages[currentAtlas], chartImageToPack, chartImageToPackRotated, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, &best_x, &best_y, &best_cw, &best_ch, &best_r, options.blockAlign, maxResolution, chart->allowRotate);
+ XA_PROFILE_END(packChartsFindLocation)
+ XA_DEBUG_ASSERT(!(firstChartInBitImage && !foundLocation)); // Chart doesn't fit in an empty, newly allocated bitImage. Shouldn't happen, since charts are resized if they are too big to fit in the atlas.
+ if (maxResolution == 0) {
+ XA_DEBUG_ASSERT(foundLocation); // The atlas isn't limited to a fixed resolution, a chart location should be found on the first attempt.
+ 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 > atlasSizes[currentAtlas].x || best_y + best_ch > atlasSizes[currentAtlas].y) {
+ 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.
+ atlasSizes[currentAtlas].x = max(atlasSizes[currentAtlas].x, best_x + best_cw);
+ atlasSizes[currentAtlas].y = max(atlasSizes[currentAtlas].y, best_y + best_ch);
+ // Resize bitImage if necessary.
+ // If maxResolution > 0, the bitImage is always set to maxResolutionIncludingPadding on creation and doesn't need to be dynamically resized.
+ if (maxResolution == 0) {
+ const uint32_t w = (uint32_t)atlasSizes[currentAtlas].x;
+ const uint32_t h = (uint32_t)atlasSizes[currentAtlas].y;
+ if (w > m_bitImages[0]->width() || h > m_bitImages[0]->height()) {
+ m_bitImages[0]->resize(nextPowerOfTwo(w), nextPowerOfTwo(h), false);
+ if (createImage)
+ m_atlasImages[0]->resize(m_bitImages[0]->width(), m_bitImages[0]->height());
}
- resetUvs();
} else {
- return;
+ XA_DEBUG_ASSERT(atlasSizes[currentAtlas].x <= (int)maxResolution);
+ XA_DEBUG_ASSERT(atlasSizes[currentAtlas].y <= (int)maxResolution);
+ }
+ XA_PROFILE_START(packChartsBlit)
+ addChart(m_bitImages[currentAtlas], chartImageToPack, chartImageToPackRotated, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, best_x, best_y, best_r);
+ XA_PROFILE_END(packChartsBlit)
+ if (createImage) {
+ if (best_r == 0) {
+ m_atlasImages[currentAtlas]->addChart(c, &chartImage, options.bilinear ? &chartImageBilinear : nullptr, options.padding > 0 ? &chartImagePadding : nullptr, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, best_x, best_y);
+ } else {
+ m_atlasImages[currentAtlas]->addChart(c, &chartImageRotated, options.bilinear ? &chartImageBilinearRotated : nullptr, options.padding > 0 ? &chartImagePaddingRotated : nullptr, atlasSizes[currentAtlas].x, atlasSizes[currentAtlas].y, best_x, best_y);
+ }
+ }
+ chart->atlasIndex = (int32_t)currentAtlas;
+ // Modify texture coordinates:
+ // - rotate if the chart should be rotated
+ // - translate to chart location
+ // - translate to remove padding from top and left atlas edges (unless block aligned)
+ 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;
+ texcoord.y = best_y + t.y;
+ if (!options.blockAlign) {
+ texcoord.x -= (float)options.padding;
+ texcoord.y -= (float)options.padding;
+ }
+ 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 (options.blockAlign) {
+ if (maxResolution == 0) {
+ m_width = max(0, atlasSizes[0].x);
+ m_height = max(0, atlasSizes[0].y);
+ } else {
+ m_width = m_height = maxResolution;
+ }
+ } else {
+ // Remove padding from outer edges.
+ if (maxResolution == 0) {
+ m_width = max(0, atlasSizes[0].x - (int)options.padding * 2);
+ m_height = max(0, atlasSizes[0].y - (int)options.padding * 2);
+ } else {
+ m_width = m_height = maxResolution - (int)options.padding * 2;
+ }
+ }
+ 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++) {
+ if (m_width == 0 || m_height == 0)
+ m_utilization[i] = 0.0f;
+ else {
+ 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, uint32_t maxResolution, 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, maxResolution, allowRotate);
+ return findChartLocation_random(atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, attempts, blockAligned, maxResolution, 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, uint32_t maxResolution, bool allowRotate)
{
- const int BLOCK_SIZE = 4;
+ const int stepSize = blockAligned ? 4 : 1;
+ const int chartMinHeight = min(chartBitImage->height(), chartBitImageRotated->height());
+ uint32_t taskCount = 0;
+ for (int y = startPosition.y; y <= h + stepSize; y += stepSize) {
+ if (maxResolution > 0 && y > (int)maxResolution - chartMinHeight)
+ break;
+ taskCount++;
+ }
+ m_bruteForceTaskArgs.clear();
+ m_bruteForceTaskArgs.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) {
+ if (maxResolution > 0 && y > (int)maxResolution - chartMinHeight)
+ break;
+ FindChartLocationBruteForceTaskArgs &args = m_bruteForceTaskArgs[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.allowRotate = allowRotate;
+ args.maxResolution = maxResolution;
+ Task task;
+ task.userData = &m_bruteForceTaskArgs[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 = m_bruteForceTaskArgs[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, uint32_t maxResolution, 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;
+ // Clamp to max resolution.
+ if (maxResolution > 0) {
+ xRange = min(xRange, (int)maxResolution - cw);
+ yRange = min(yRange, (int)maxResolution - 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 (maxResolution > 0 && (x > (int)maxResolution - cw || y > (int)maxResolution - 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)
+ 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));
- // 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++) {
+ 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++) {
+ int yy = y + offset_y;
+ if (yy >= 0) {
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);
+ 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);
+ }
}
}
- if (b) tmp.setBitAt(x, y);
}
}
- std::swap(tmp, *bitmap);
}
}
- void drawChartBitmap(const Chart *chart, BitMap *bitmap, const Vector2 &scale, const Vector2 &offset)
+ void bilinearExpand(const Chart *chart, BitImage *source, BitImage *dest, BitImage *destRotated) const
{
- 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();
- 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;
- }
- }
- }
+ const int xOffsets[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
+ const int yOffsets[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
+ for (uint32_t y = 0; y < source->height(); y++) {
+ for (uint32_t x = 0; x < source->width(); x++) {
+ // Copy pixels from source.
+ if (source->bitAt(x, y))
+ goto setPixel;
+ // Empty pixel. If none of of the surrounding pixels are set, this pixel can't be sampled by bilinear interpolation.
+ {
+ uint32_t s = 0;
+ for (; s < 8; s++) {
+ const int sx = (int)x + xOffsets[s];
+ const int sy = (int)y + yOffsets[s];
+ if (sx < 0 || sy < 0 || sx >= (int)source->width() || sy >= (int)source->height())
+ continue;
+ if (source->bitAt((uint32_t)sx, (uint32_t)sy))
+ break;
}
+ if (s == 8)
+ continue;
}
- }
- }
- 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);
- }
- }
- }
+ // If a 2x2 square centered on the pixels centroid intersects the triangle, this pixel will be sampled by bilinear interpolation.
+ // See "Precomputed Global Illumination in Frostbite (GDC 2018)" page 95
+ for (uint32_t f = 0; f < chart->indexCount / 3; f++) {
+ const Vector2 centroid((float)x + 0.5f, (float)y + 0.5f);
+ Vector2 vertices[3];
+ for (uint32_t i = 0; i < 3; i++)
+ vertices[i] = chart->vertices[chart->indices[f * 3 + i]];
+ // Test for triangle vertex in square bounds.
+ for (uint32_t i = 0; i < 3; i++) {
+ const Vector2 &v = vertices[i];
+ if (v.x > centroid.x - 1.0f && v.x < centroid.x + 1.0f && v.y > centroid.y - 1.0f && v.y < centroid.y + 1.0f)
+ goto setPixel;
}
- }
- }
- } 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);
- }
- }
+ // Test for triangle edge intersection with square edge.
+ const Vector2 squareVertices[4] = {
+ Vector2(centroid.x - 1.0f, centroid.y - 1.0f),
+ Vector2(centroid.x + 1.0f, centroid.y - 1.0f),
+ Vector2(centroid.x + 1.0f, centroid.y + 1.0f),
+ Vector2(centroid.x - 1.0f, centroid.y + 1.0f)
+ };
+ for (uint32_t i = 0; i < 3; i++) {
+ for (uint32_t j = 0; j < 4; j++) {
+ if (linesIntersect(vertices[i], vertices[(i + 1) % 3], squareVertices[j], squareVertices[(j + 1) % 4], 0.0f))
+ goto setPixel;
}
}
}
+ continue;
+ setPixel:
+ dest->setBitAt(x, y);
+ if (destRotated)
+ destRotated->setBitAt(y, x);
}
}
}
- 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, *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;
+ Array<Chart *> m_charts;
+ Array<FindChartLocationBruteForceTaskArgs> m_bruteForceTaskArgs;
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].faceArray)
+ XA_FREE(mesh.chartArray[j].faceArray);
+ }
+ 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_ARGS(internal::MemTag::Default, internal::Progress, ProgressCategory::AddMesh, ctx->progressFunc, ctx->progressUserData, 1);
}
- heMesh->linkColocalsWithCanonicalMap(canonicalMap);
- for (uint32_t i = 0; i < mesh.indexCount / 3; i++) {
+ else {
+ ctx->addMeshProgress->setMaxValue(internal::max(ctx->meshCount + 1, meshCountHint));
+ }
+ XA_PROFILE_START(addMeshCopyData)
+ const bool hasIndices = meshDecl.indexCount > 0;
+ const uint32_t indexCount = hasIndices ? meshDecl.indexCount : meshDecl.vertexCount;
+ 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 (hasIndices) {
+ // 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_ARGS(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] = hasIndices ? DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, i * 3 + j) : 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;
+ 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;
}
}
+ // Ignore faces with any nan vertex attributes.
+ if (!ignore) {
+ for (int j = 0; j < 3; j++) {
+ const internal::Vector3 &pos = mesh->position(tri[j]);
+ if (internal::isNan(pos.x) || internal::isNan(pos.y) || internal::isNan(pos.z)) {
+ XA_PRINT(" NAN position in face: %d\n", i);
+ ignore = true;
+ break;
+ }
+ if (meshDecl.vertexNormalData) {
+ const internal::Vector3 &normal = mesh->normal(tri[j]);
+ if (internal::isNan(normal.x) || internal::isNan(normal.y) || internal::isNan(normal.z)) {
+ XA_PRINT(" NAN normal in face: %d\n", i);
+ ignore = true;
+ break;
+ }
+ }
+ if (meshDecl.vertexUvData) {
+ const internal::Vector2 &uv = mesh->texcoord(tri[j]);
+ if (internal::isNan(uv.x) || internal::isNan(uv.y)) {
+ XA_PRINT(" NAN texture coordinate in face: %d\n", i);
+ ignore = true;
+ 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.
- {
- 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;
+ 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);
+ }
+ XA_PROFILE_END(addMeshCopyData)
+ 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 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;
+ ctx->paramAtlas.sortChartGroups();
+#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(" Copy data: ", addMeshCopyData)
+ 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++) {
+ internal::Vector2 texcoord = *((const internal::Vector2 *)&((const uint8_t *)decl.vertexUvData)[decl.vertexStride * i]);
+ // Set nan values to 0.
+ if (internal::isNan(texcoord.x) || internal::isNan(texcoord.y))
+ texcoord.x = texcoord.y = 0.0f;
+ meshInstance->texcoords[i] = texcoord;
+ }
+ 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> vertexToFaceMap(internal::MemTag::Default, indexCount); // Face is index / 3
+ const uint32_t faceCount = indexCount / 3;
+ for (uint32_t i = 0; i < indexCount; i++)
+ vertexToFaceMap.add(meshInstance->texcoords[mesh->indices[i]]);
+ internal::BitArray faceAssigned(faceCount);
+ faceAssigned.clearAll();
+ 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);
+ chart->faces.push_back(f);
+ for (;;) {
+ bool newFaceAssigned = false;
+ const uint32_t faceCount2 = chart->faces.size();
+ for (uint32_t f2 = 0; f2 < faceCount2; f2++) {
+ const uint32_t face = chart->faces[f2];
+ for (uint32_t i = 0; i < 3; i++) {
+ const internal::Vector2 &texcoord = meshInstance->texcoords[meshInstance->mesh->indices[face * 3 + i]];
+ uint32_t mapIndex = vertexToFaceMap.get(texcoord);
+ while (mapIndex != UINT32_MAX) {
+ const uint32_t face2 = mapIndex / 3; // 3 vertices added per face.
+ // Materials must match.
+ if (!faceAssigned.bitAt(face2) && (!decl.faceMaterialData || decl.faceMaterialData[face] == decl.faceMaterialData[face2])) {
+ faceAssigned.setBitAt(face2);
+ chart->faces.push_back(face2);
+ newFaceAssigned = true;
+ }
+ mapIndex = vertexToFaceMap.getNext(mapIndex);
+ }
+ }
+ }
+ if (!newFaceAssigned)
+ break;
+ }
+ for (uint32_t i = 0; i < chart->faces.size(); i++) {
+ for (uint32_t j = 0; j < 3; j++) {
+ const uint32_t vertex = meshInstance->mesh->indices[chart->faces[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(" Build atlas: ", buildAtlas)
+ XA_PROFILE_PRINT_AND_RESET(" Init: ", buildAtlasInit)
+ XA_PROFILE_PRINT_AND_RESET(" Place seeds: ", buildAtlasPlaceSeeds)
+ XA_PROFILE_PRINT_AND_RESET(" Relocate seeds: ", buildAtlasRelocateSeeds)
+ XA_PROFILE_PRINT_AND_RESET(" Reset charts: ", buildAtlasResetCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Grow charts: ", buildAtlasGrowCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Merge charts: ", buildAtlasMergeCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Fill holes: ", buildAtlasFillHoles)
+ 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", 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
}
-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 PackCharts(Atlas *atlas, PackOptions packOptions)
+{
+ // 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.
+ XA_PROFILE_START(packChartsAddCharts)
+ internal::pack::Atlas packAtlas;
+ if (!ctx->uvMeshInstances.isEmpty()) {
+ for (uint32_t i = 0; i < ctx->uvMeshInstances.size(); i++)
+ packAtlas.addUvMeshCharts(ctx->uvMeshInstances[i]);
+ }
+ else
+ packAtlas.addCharts(ctx->taskScheduler, &ctx->paramAtlas);
+ XA_PROFILE_END(packChartsAddCharts)
+ 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, packOptions.blockAlign ? 0 : packOptions.padding);
+ }
+ XA_PROFILE_PRINT_AND_RESET(" Total: ", packCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Add charts (real): ", packChartsAddCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Add charts (thread): ", packChartsAddChartsThread)
+ XA_PROFILE_PRINT_AND_RESET(" Restore texcoords: ", packChartsAddChartsRestoreTexcoords)
+ 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");
+ XA_PROFILE_START(buildOutputMeshes)
+ 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, 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->faceCount = mesh->faceCount();
+ outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount);
+ for (uint32_t f = 0; f < outputChart->faceCount; f++)
+ outputChart->faceArray[f] = chartGroup->mapFaceToSourceFace(chart->mapFaceToSourceFace(f));
+ outputChart->material = 0;
+ meshChartIndex++;
+ chartIndex++;
+ firstVertex += 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->faceCount = chart->faces.size();
+ outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount);
+ outputChart->material = chart->material;
+ for (uint32_t f = 0; f < outputChart->faceCount; f++)
+ outputChart->faceArray[f] = chart->faces[f];
+ 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_PROFILE_END(buildOutputMeshes)
+ XA_PROFILE_PRINT_AND_RESET(" Total: ", buildOutputMeshes)
+ 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 GetWidth(const Atlas *atlas)
+void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc, void *progressUserData)
{
- xaAssert(atlas);
- return atlas->width;
+ if (!atlas) {
+ XA_PRINT_WARNING("SetProgressCallback: atlas is null.\n");
+ return;
+ }
+ Context *ctx = (Context *)atlas;
+ ctx->progressFunc = progressFunc;
+ ctx->progressUserData = progressUserData;
}
-uint32_t GetHeight(const Atlas *atlas)
+void SetAlloc(ReallocFunc reallocFunc, FreeFunc freeFunc)
{
- xaAssert(atlas);
- return atlas->height;
+ internal::s_realloc = reallocFunc;
+ internal::s_free = freeFunc;
}
-uint32_t GetNumCharts(const Atlas *atlas)
+void SetPrint(PrintFunc print, bool verbose)
{
- xaAssert(atlas);
- return atlas->atlas.chartCount();
+ 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..7be165e7e5 100644
--- a/thirdparty/xatlas/xatlas.h
+++ b/thirdparty/xatlas/xatlas.h
@@ -1,176 +1,258 @@
-// 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 *faceArray;
+ uint32_t faceCount;
+ 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 = 0x1FFFFFFF;
+static const uint32_t kImageHasChartIndexBit = 0x80000000;
+static const uint32_t kImageIsBilinearBit = 0x40000000;
+static const uint32_t kImageIsPaddingBit = 0x20000000;
+
+// 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 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.
+ // Leave space around charts for texels that would be sampled by bilinear filtering.
+ bool bilinear = true;
+
+ // Align charts to 4x4 blocks. Also improves packing speed, since there are fewer possible chart locations to consider.
+ bool blockAlign = false;
+
+ // Slower, but gives the best result. If false, use random chart placement.
+ bool bruteForce = false;
+
+ // Create Atlas::image
+ bool createImage = false;
+
+ // Charts larger than this will be scaled down. 0 means no limit.
+ uint32_t maxChartSize = 0;
+
+ // Number of pixels to pad charts with.
+ uint32_t padding = 0;
+
+ // 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;
};
-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);
+typedef void (*FreeFunc)(void *);
+void SetAlloc(ReallocFunc reallocFunc, FreeFunc freeFunc = nullptr);
+
+// 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
diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h
index 0836e3ed27..87bf51ae8c 100644
--- a/thirdparty/zstd/common/compiler.h
+++ b/thirdparty/zstd/common/compiler.h
@@ -127,6 +127,13 @@
} \
}
+/* vectorization */
+#if !defined(__clang__) && defined(__GNUC__)
+# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
+#else
+# define DONT_VECTORIZE
+#endif
+
/* disable warnings */
#ifdef _MSC_VER /* Visual Studio */
# include <intrin.h> /* For Visual 2005 */
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
index 31f756ab58..81b16eac2e 100644
--- a/thirdparty/zstd/common/zstd_internal.h
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -34,7 +34,6 @@
#endif
#include "xxhash.h" /* XXH_reset, update, digest */
-
#if defined (__cplusplus)
extern "C" {
#endif
@@ -193,19 +192,72 @@ static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
* Shared functions to include for inlining
*********************************************/
static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
+
#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
+static void ZSTD_copy16(void* dst, const void* src) { memcpy(dst, src, 16); }
+#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
+
+#define WILDCOPY_OVERLENGTH 8
+#define VECLEN 16
+
+typedef enum {
+ ZSTD_no_overlap,
+ ZSTD_overlap_src_before_dst,
+ /* ZSTD_overlap_dst_before_src, */
+} ZSTD_overlap_e;
/*! ZSTD_wildcopy() :
* custom version of memcpy(), can overwrite up to WILDCOPY_OVERLENGTH bytes (if length==0) */
-#define WILDCOPY_OVERLENGTH 8
-MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
+MEM_STATIC FORCE_INLINE_ATTR DONT_VECTORIZE
+void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e ovtype)
{
+ ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
BYTE* const oend = op + length;
- do
- COPY8(op, ip)
- while (op < oend);
+
+ assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff < -8));
+ if (length < VECLEN || (ovtype == ZSTD_overlap_src_before_dst && diff < VECLEN)) {
+ do
+ COPY8(op, ip)
+ while (op < oend);
+ }
+ else {
+ if ((length & 8) == 0)
+ COPY8(op, ip);
+ do {
+ COPY16(op, ip);
+ }
+ while (op < oend);
+ }
+}
+
+/*! ZSTD_wildcopy_16min() :
+ * same semantics as ZSTD_wilcopy() except guaranteed to be able to copy 16 bytes at the start */
+MEM_STATIC FORCE_INLINE_ATTR DONT_VECTORIZE
+void ZSTD_wildcopy_16min(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e ovtype)
+{
+ ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
+ const BYTE* ip = (const BYTE*)src;
+ BYTE* op = (BYTE*)dst;
+ BYTE* const oend = op + length;
+
+ assert(length >= 8);
+ assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff < -8));
+
+ if (ovtype == ZSTD_overlap_src_before_dst && diff < VECLEN) {
+ do
+ COPY8(op, ip)
+ while (op < oend);
+ }
+ else {
+ if ((length & 8) == 0)
+ COPY8(op, ip);
+ do {
+ COPY16(op, ip);
+ }
+ while (op < oend);
+ }
}
MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
index 2e163c8bf3..1476512580 100644
--- a/thirdparty/zstd/compress/zstd_compress.c
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -385,6 +385,11 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
bounds.upperBound = ZSTD_lcm_uncompressed;
return bounds;
+ case ZSTD_c_targetCBlockSize:
+ bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN;
+ bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;
+ return bounds;
+
default:
{ ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
return boundError;
@@ -452,6 +457,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_ldmHashRateLog:
case ZSTD_c_forceAttachDict:
case ZSTD_c_literalCompressionMode:
+ case ZSTD_c_targetCBlockSize:
default:
return 0;
}
@@ -497,6 +503,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_ldmHashLog:
case ZSTD_c_ldmMinMatch:
case ZSTD_c_ldmBucketSizeLog:
+ case ZSTD_c_targetCBlockSize:
break;
default: RETURN_ERROR(parameter_unsupported);
@@ -671,6 +678,12 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
CCtxParams->ldmParams.hashRateLog = value;
return CCtxParams->ldmParams.hashRateLog;
+ case ZSTD_c_targetCBlockSize :
+ if (value!=0) /* 0 ==> default */
+ BOUNDCHECK(ZSTD_c_targetCBlockSize, value);
+ CCtxParams->targetCBlockSize = value;
+ return CCtxParams->targetCBlockSize;
+
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
}
}
@@ -692,13 +705,13 @@ size_t ZSTD_CCtxParams_getParameter(
*value = CCtxParams->compressionLevel;
break;
case ZSTD_c_windowLog :
- *value = CCtxParams->cParams.windowLog;
+ *value = (int)CCtxParams->cParams.windowLog;
break;
case ZSTD_c_hashLog :
- *value = CCtxParams->cParams.hashLog;
+ *value = (int)CCtxParams->cParams.hashLog;
break;
case ZSTD_c_chainLog :
- *value = CCtxParams->cParams.chainLog;
+ *value = (int)CCtxParams->cParams.chainLog;
break;
case ZSTD_c_searchLog :
*value = CCtxParams->cParams.searchLog;
@@ -773,6 +786,9 @@ size_t ZSTD_CCtxParams_getParameter(
case ZSTD_c_ldmHashRateLog :
*value = CCtxParams->ldmParams.hashRateLog;
break;
+ case ZSTD_c_targetCBlockSize :
+ *value = (int)CCtxParams->targetCBlockSize;
+ break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
}
return 0;
@@ -930,12 +946,12 @@ size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
@return : 0, or an error code if one value is beyond authorized range */
size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
{
- BOUNDCHECK(ZSTD_c_windowLog, cParams.windowLog);
- BOUNDCHECK(ZSTD_c_chainLog, cParams.chainLog);
- BOUNDCHECK(ZSTD_c_hashLog, cParams.hashLog);
- BOUNDCHECK(ZSTD_c_searchLog, cParams.searchLog);
- BOUNDCHECK(ZSTD_c_minMatch, cParams.minMatch);
- BOUNDCHECK(ZSTD_c_targetLength,cParams.targetLength);
+ BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog);
+ BOUNDCHECK(ZSTD_c_chainLog, (int)cParams.chainLog);
+ BOUNDCHECK(ZSTD_c_hashLog, (int)cParams.hashLog);
+ BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
+ BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch);
+ BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
BOUNDCHECK(ZSTD_c_strategy, cParams.strategy);
return 0;
}
@@ -951,7 +967,7 @@ ZSTD_clampCParams(ZSTD_compressionParameters cParams)
if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound; \
else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \
}
-# define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, int)
+# define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned)
CLAMP(ZSTD_c_windowLog, cParams.windowLog);
CLAMP(ZSTD_c_chainLog, cParams.chainLog);
CLAMP(ZSTD_c_hashLog, cParams.hashLog);
@@ -1282,15 +1298,14 @@ static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
}
/*! ZSTD_invalidateMatchState()
- * Invalidate all the matches in the match finder tables.
- * Requires nextSrc and base to be set (can be NULL).
+ * Invalidate all the matches in the match finder tables.
+ * Requires nextSrc and base to be set (can be NULL).
*/
static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
{
ZSTD_window_clear(&ms->window);
ms->nextToUpdate = ms->window.dictLimit;
- ms->nextToUpdate3 = ms->window.dictLimit;
ms->loadedDictEnd = 0;
ms->opt.litLengthSum = 0; /* force reset of btopt stats */
ms->dictMatchState = NULL;
@@ -1327,15 +1342,17 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
+typedef enum { ZSTD_resetTarget_CDict, ZSTD_resetTarget_CCtx } ZSTD_resetTarget_e;
+
static void*
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
void* ptr,
const ZSTD_compressionParameters* cParams,
- ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
+ ZSTD_compResetPolicy_e const crp, ZSTD_resetTarget_e const forWho)
{
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
size_t const hSize = ((size_t)1) << cParams->hashLog;
- U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
+ U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
size_t const h3Size = ((size_t)1) << hashLog3;
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
@@ -1349,7 +1366,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
ZSTD_invalidateMatchState(ms);
/* opt parser space */
- if (forCCtx && (cParams->strategy >= ZSTD_btopt)) {
+ if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
DEBUGLOG(4, "reserving optimal parser space");
ms->opt.litFreq = (unsigned*)ptr;
ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
@@ -1377,6 +1394,19 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
return ptr;
}
+/* ZSTD_indexTooCloseToMax() :
+ * minor optimization : prefer memset() rather than reduceIndex()
+ * which is measurably slow in some circumstances (reported for Visual Studio).
+ * Works when re-using a context for a lot of smallish inputs :
+ * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN,
+ * memset() will be triggered before reduceIndex().
+ */
+#define ZSTD_INDEXOVERFLOW_MARGIN (16 MB)
+static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
+{
+ return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
+}
+
#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 /* when workspace is continuously too large
* during at least this number of times,
@@ -1388,7 +1418,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
note : `params` are assumed fully validated at this stage */
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_CCtx_params params,
- U64 pledgedSrcSize,
+ U64 const pledgedSrcSize,
ZSTD_compResetPolicy_e const crp,
ZSTD_buffered_policy_e const zbuff)
{
@@ -1400,13 +1430,21 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
if (ZSTD_equivalentParams(zc->appliedParams, params,
zc->inBuffSize,
zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
- zbuff, pledgedSrcSize)) {
- DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
- zc->appliedParams.cParams.windowLog, zc->blockSize);
+ zbuff, pledgedSrcSize) ) {
+ DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> consider continue mode");
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
- if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
+ if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION) {
+ DEBUGLOG(4, "continue mode confirmed (wLog1=%u, blockSize1=%zu)",
+ zc->appliedParams.cParams.windowLog, zc->blockSize);
+ if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
+ /* prefer a reset, faster than a rescale */
+ ZSTD_reset_matchState(&zc->blockState.matchState,
+ zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
+ &params.cParams,
+ crp, ZSTD_resetTarget_CCtx);
+ }
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
- } }
+ } } }
DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
if (params.ldmParams.enableLdm) {
@@ -1449,7 +1487,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
if (workSpaceTooSmall || workSpaceWasteful) {
- DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB",
+ DEBUGLOG(4, "Resize workSpaceSize from %zuKB to %zuKB",
zc->workSpaceSize >> 10,
neededSpace >> 10);
@@ -1491,7 +1529,10 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
- ptr = zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32;
+ ptr = ZSTD_reset_matchState(&zc->blockState.matchState,
+ zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
+ &params.cParams,
+ crp, ZSTD_resetTarget_CCtx);
/* ldm hash table */
/* initialize bucketOffsets table later for pointer alignment */
@@ -1509,8 +1550,6 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
}
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
- ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, &params.cParams, crp, /* forCCtx */ 1);
-
/* sequences storage */
zc->seqStore.maxNbSeq = maxNbSeq;
zc->seqStore.sequencesStart = (seqDef*)ptr;
@@ -1587,15 +1626,14 @@ static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
* handled in _enforceMaxDist */
}
-static size_t ZSTD_resetCCtx_byAttachingCDict(
- ZSTD_CCtx* cctx,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params,
- U64 pledgedSrcSize,
- ZSTD_buffered_policy_e zbuff)
+static size_t
+ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params,
+ U64 pledgedSrcSize,
+ ZSTD_buffered_policy_e zbuff)
{
- {
- const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
+ { const ZSTD_compressionParameters* const cdict_cParams = &cdict->matchState.cParams;
unsigned const windowLog = params.cParams.windowLog;
assert(windowLog != 0);
/* Resize working context table params for input only, since the dict
@@ -1607,8 +1645,7 @@ static size_t ZSTD_resetCCtx_byAttachingCDict(
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
}
- {
- const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
+ { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
- cdict->matchState.window.base);
const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
if (cdictLen == 0) {
@@ -1625,9 +1662,9 @@ static size_t ZSTD_resetCCtx_byAttachingCDict(
cctx->blockState.matchState.window.base + cdictEnd;
ZSTD_window_clear(&cctx->blockState.matchState.window);
}
+ /* loadedDictEnd is expressed within the referential of the active context */
cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
- }
- }
+ } }
cctx->dictID = cdict->dictID;
@@ -1681,7 +1718,6 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
dstMatchState->window = srcMatchState->window;
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
- dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
}
@@ -1761,7 +1797,6 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
dstMatchState->window = srcMatchState->window;
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
- dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
}
dstCCtx->dictID = srcCCtx->dictID;
@@ -1831,16 +1866,15 @@ static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const
/*! ZSTD_reduceIndex() :
* rescale all indexes to avoid future overflow (indexes are U32) */
-static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
+static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
{
- ZSTD_matchState_t* const ms = &zc->blockState.matchState;
- { U32 const hSize = (U32)1 << zc->appliedParams.cParams.hashLog;
+ { U32 const hSize = (U32)1 << params->cParams.hashLog;
ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
}
- if (zc->appliedParams.cParams.strategy != ZSTD_fast) {
- U32 const chainSize = (U32)1 << zc->appliedParams.cParams.chainLog;
- if (zc->appliedParams.cParams.strategy == ZSTD_btlazy2)
+ if (params->cParams.strategy != ZSTD_fast) {
+ U32 const chainSize = (U32)1 << params->cParams.chainLog;
+ if (params->cParams.strategy == ZSTD_btlazy2)
ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
else
ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);
@@ -2524,6 +2558,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
else
op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
+ assert(op <= oend);
if (nbSeq==0) {
/* Copy the old tables over as if we repeated them */
memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
@@ -2532,6 +2567,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
/* seqHead : flags for FSE encoding type */
seqHead = op++;
+ assert(op <= oend);
/* convert length/distances into codes */
ZSTD_seqToCodes(seqStorePtr);
@@ -2555,6 +2591,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
if (LLtype == set_compressed)
lastNCount = op;
op += countSize;
+ assert(op <= oend);
} }
/* build CTable for Offsets */
{ unsigned max = MaxOff;
@@ -2577,6 +2614,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
if (Offtype == set_compressed)
lastNCount = op;
op += countSize;
+ assert(op <= oend);
} }
/* build CTable for MatchLengths */
{ unsigned max = MaxML;
@@ -2597,6 +2635,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
if (MLtype == set_compressed)
lastNCount = op;
op += countSize;
+ assert(op <= oend);
} }
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
@@ -2610,6 +2649,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
longOffsets, bmi2);
FORWARD_IF_ERROR(bitstreamSize);
op += bitstreamSize;
+ assert(op <= oend);
/* zstd versions <= 1.3.4 mistakenly report corruption when
* FSE_readNCount() receives a buffer < 4 bytes.
* Fixed by https://github.com/facebook/zstd/pull/1146.
@@ -2721,30 +2761,24 @@ void ZSTD_resetSeqStore(seqStore_t* ssPtr)
ssPtr->longLengthID = 0;
}
-static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize)
+typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;
+
+static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
{
ZSTD_matchState_t* const ms = &zc->blockState.matchState;
- size_t cSize;
- DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
- (unsigned)dstCapacity, (unsigned)ms->window.dictLimit, (unsigned)ms->nextToUpdate);
+ DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
-
/* Assert that we have correctly flushed the ctx params into the ms's copy */
ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
-
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
- cSize = 0;
- goto out; /* don't even attempt compression below a certain srcSize */
+ return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */
}
ZSTD_resetSeqStore(&(zc->seqStore));
/* required for optimal parser to read stats from dictionary */
ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;
/* tell the optimal parser how we expect to compress literals */
ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode;
-
/* a gap between an attached dict and the current window is not safe,
* they must remain adjacent,
* and when that stops being the case, the dict must be unset */
@@ -2798,6 +2832,21 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
} }
+ return ZSTDbss_compress;
+}
+
+static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ size_t cSize;
+ DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
+ (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate);
+
+ { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
+ FORWARD_IF_ERROR(bss);
+ if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
+ }
/* encode sequences and literals */
cSize = ZSTD_compressSequences(&zc->seqStore,
@@ -2826,6 +2875,25 @@ out:
}
+static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, void const* ip, void const* iend)
+{
+ if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {
+ U32 const maxDist = (U32)1 << params->cParams.windowLog;
+ U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy);
+ U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
+ ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
+ ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
+ ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
+ ZSTD_reduceIndex(ms, params, correction);
+ if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
+ else ms->nextToUpdate -= correction;
+ /* invalidate dictionaries on overflow correction */
+ ms->loadedDictEnd = 0;
+ ms->dictMatchState = NULL;
+ }
+}
+
+
/*! ZSTD_compress_frameChunk() :
* Compress a chunk of data into one or multiple blocks.
* All blocks will be terminated, all input will be consumed.
@@ -2844,7 +2912,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
BYTE* const ostart = (BYTE*)dst;
BYTE* op = ostart;
U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
- assert(cctx->appliedParams.cParams.windowLog <= 31);
+ assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
if (cctx->appliedParams.fParams.checksumFlag && srcSize)
@@ -2859,19 +2927,10 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
"not enough space to store compressed block");
if (remaining < blockSize) blockSize = remaining;
- if (ZSTD_window_needOverflowCorrection(ms->window, ip + blockSize)) {
- U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
- U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
- ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
- ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
- ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
- ZSTD_reduceIndex(cctx, correction);
- if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
- else ms->nextToUpdate -= correction;
- ms->loadedDictEnd = 0;
- ms->dictMatchState = NULL;
- }
- ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
+ ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, ip, ip + blockSize);
+ ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
+
+ /* Ensure hash/chain table insertion resumes no sooner than lowlimit */
if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
{ size_t cSize = ZSTD_compressBlock_internal(cctx,
@@ -2899,7 +2958,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
} }
if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
- return op-ostart;
+ return (size_t)(op-ostart);
}
@@ -2991,6 +3050,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
FORWARD_IF_ERROR(fhSize);
+ assert(fhSize <= dstCapacity);
dstCapacity -= fhSize;
dst = (char*)dst + fhSize;
cctx->stage = ZSTDcs_ongoing;
@@ -3007,18 +3067,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (!frame) {
/* overflow check and correction for block mode */
- if (ZSTD_window_needOverflowCorrection(ms->window, (const char*)src + srcSize)) {
- U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
- U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, 1 << cctx->appliedParams.cParams.windowLog, src);
- ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
- ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
- ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
- ZSTD_reduceIndex(cctx, correction);
- if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
- else ms->nextToUpdate -= correction;
- ms->loadedDictEnd = 0;
- ms->dictMatchState = NULL;
- }
+ ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, src, (BYTE const*)src + srcSize);
}
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
@@ -3074,7 +3123,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
const void* src, size_t srcSize,
ZSTD_dictTableLoadMethod_e dtlm)
{
- const BYTE* const ip = (const BYTE*) src;
+ const BYTE* ip = (const BYTE*) src;
const BYTE* const iend = ip + srcSize;
ZSTD_window_update(&ms->window, src, srcSize);
@@ -3085,32 +3134,42 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
if (srcSize <= HASH_READ_SIZE) return 0;
- switch(params->cParams.strategy)
- {
- case ZSTD_fast:
- ZSTD_fillHashTable(ms, iend, dtlm);
- break;
- case ZSTD_dfast:
- ZSTD_fillDoubleHashTable(ms, iend, dtlm);
- break;
+ while (iend - ip > HASH_READ_SIZE) {
+ size_t const remaining = iend - ip;
+ size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
+ const BYTE* const ichunk = ip + chunk;
- case ZSTD_greedy:
- case ZSTD_lazy:
- case ZSTD_lazy2:
- if (srcSize >= HASH_READ_SIZE)
- ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE);
- break;
+ ZSTD_overflowCorrectIfNeeded(ms, params, ip, ichunk);
- case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
- case ZSTD_btopt:
- case ZSTD_btultra:
- case ZSTD_btultra2:
- if (srcSize >= HASH_READ_SIZE)
- ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
- break;
+ switch(params->cParams.strategy)
+ {
+ case ZSTD_fast:
+ ZSTD_fillHashTable(ms, ichunk, dtlm);
+ break;
+ case ZSTD_dfast:
+ ZSTD_fillDoubleHashTable(ms, ichunk, dtlm);
+ break;
- default:
- assert(0); /* not possible : not a valid strategy id */
+ case ZSTD_greedy:
+ case ZSTD_lazy:
+ case ZSTD_lazy2:
+ if (chunk >= HASH_READ_SIZE)
+ ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);
+ break;
+
+ case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
+ case ZSTD_btopt:
+ case ZSTD_btultra:
+ case ZSTD_btultra2:
+ if (chunk >= HASH_READ_SIZE)
+ ZSTD_updateTree(ms, ichunk-HASH_READ_SIZE, ichunk);
+ break;
+
+ default:
+ assert(0); /* not possible : not a valid strategy id */
+ }
+
+ ip = ichunk;
}
ms->nextToUpdate = (U32)(iend - ms->window.base);
@@ -3297,12 +3356,11 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
ZSTDcrp_continue, zbuff) );
- {
- size_t const dictID = ZSTD_compress_insertDictionary(
+ { size_t const dictID = ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
&params, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
FORWARD_IF_ERROR(dictID);
- assert(dictID <= (size_t)(U32)-1);
+ assert(dictID <= UINT_MAX);
cctx->dictID = (U32)dictID;
}
return 0;
@@ -3555,10 +3613,10 @@ static size_t ZSTD_initCDict_internal(
/* Reset the state to no dictionary */
ZSTD_reset_compressedBlockState(&cdict->cBlockState);
- { void* const end = ZSTD_reset_matchState(
- &cdict->matchState,
- (U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
- &cParams, ZSTDcrp_continue, /* forCCtx */ 0);
+ { void* const end = ZSTD_reset_matchState(&cdict->matchState,
+ (U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
+ &cParams,
+ ZSTDcrp_continue, ZSTD_resetTarget_CDict);
assert(end == (char*)cdict->workspace + cdict->workspaceSize);
(void)end;
}
@@ -4068,7 +4126,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
case zcss_flush:
DEBUGLOG(5, "flush stage");
{ size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
- size_t const flushed = ZSTD_limitCopy(op, oend-op,
+ size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),
zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
(unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
@@ -4262,7 +4320,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush; /* minimal estimation */
/* single thread mode : attempt to calculate remaining to flush more precisely */
{ size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
- size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4;
+ size_t const checksumSize = (size_t)(zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4);
size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;
DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush);
return toFlush;
diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h
index cc3cbb9da9..5495899be3 100644
--- a/thirdparty/zstd/compress/zstd_compress_internal.h
+++ b/thirdparty/zstd/compress/zstd_compress_internal.h
@@ -33,13 +33,13 @@ extern "C" {
***************************************/
#define kSearchStrength 8
#define HASH_READ_SIZE 8
-#define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index 1 now means "unsorted".
+#define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted".
It could be confused for a real successor at index "1", if sorted as larger than its predecessor.
It's not a big deal though : candidate will just be sorted again.
Additionally, candidate position 1 will be lost.
But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
- The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy
- Constant required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
+ The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.
+ This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
/*-*************************************
@@ -128,21 +128,20 @@ typedef struct {
BYTE const* base; /* All regular indexes relative to this position */
BYTE const* dictBase; /* extDict indexes relative to this position */
U32 dictLimit; /* below that point, need extDict */
- U32 lowLimit; /* below that point, no more data */
+ U32 lowLimit; /* below that point, no more valid data */
} ZSTD_window_t;
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
struct ZSTD_matchState_t {
ZSTD_window_t window; /* State for window round buffer management */
- U32 loadedDictEnd; /* index of end of dictionary */
+ U32 loadedDictEnd; /* index of end of dictionary, within context's referential. When dict referential is copied into active context (i.e. not attached), effectively same value as dictSize, since referential starts from zero */
U32 nextToUpdate; /* index from which to continue table update */
- U32 nextToUpdate3; /* index from which to continue table update */
U32 hashLog3; /* dispatch table : larger == faster, more memory */
U32* hashTable;
U32* hashTable3;
U32* chainTable;
optState_t opt; /* optimal parser state */
- const ZSTD_matchState_t * dictMatchState;
+ const ZSTD_matchState_t* dictMatchState;
ZSTD_compressionParameters cParams;
};
@@ -195,6 +194,9 @@ struct ZSTD_CCtx_params_s {
int compressionLevel;
int forceWindow; /* force back-references to respect limit of
* 1<<wLog, even for dictionary */
+ size_t targetCBlockSize; /* Tries to fit compressed block size to be around targetCBlockSize.
+ * No target when targetCBlockSize == 0.
+ * There is no guarantee on compressed block size */
ZSTD_dictAttachPref_e attachDictPref;
ZSTD_literalCompressionMode_e literalCompressionMode;
@@ -324,7 +326,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
/* copy Literals */
assert(seqStorePtr->maxNbLit <= 128 KB);
assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
- ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
+ ZSTD_wildcopy(seqStorePtr->lit, literals, litLength, ZSTD_no_overlap);
seqStorePtr->lit += litLength;
/* literal Length */
@@ -564,6 +566,9 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64
/*-*************************************
* Round buffer management
***************************************/
+#if (ZSTD_WINDOWLOG_MAX_64 > 31)
+# error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
+#endif
/* Max current allowed */
#define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
/* Maximum chunk size before overflow correction needs to be called again */
@@ -675,31 +680,49 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
* Updates lowLimit so that:
* (srcEnd - base) - lowLimit == maxDist + loadedDictEnd
*
- * This allows a simple check that index >= lowLimit to see if index is valid.
- * This must be called before a block compression call, with srcEnd as the block
- * source end.
+ * It ensures index is valid as long as index >= lowLimit.
+ * This must be called before a block compression call.
+ *
+ * loadedDictEnd is only defined if a dictionary is in use for current compression.
+ * As the name implies, loadedDictEnd represents the index at end of dictionary.
+ * The value lies within context's referential, it can be directly compared to blockEndIdx.
*
- * If loadedDictEndPtr is not NULL, we set it to zero once we update lowLimit.
- * This is because dictionaries are allowed to be referenced as long as the last
- * byte of the dictionary is in the window, but once they are out of range,
- * they cannot be referenced. If loadedDictEndPtr is NULL, we use
- * loadedDictEnd == 0.
+ * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0.
+ * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit.
+ * This is because dictionaries are allowed to be referenced fully
+ * as long as the last byte of the dictionary is in the window.
+ * Once input has progressed beyond window size, dictionary cannot be referenced anymore.
*
- * In normal dict mode, the dict is between lowLimit and dictLimit. In
- * dictMatchState mode, lowLimit and dictLimit are the same, and the dictionary
- * is below them. forceWindow and dictMatchState are therefore incompatible.
+ * In normal dict mode, the dictionary lies between lowLimit and dictLimit.
+ * In dictMatchState mode, lowLimit and dictLimit are the same,
+ * and the dictionary is below them.
+ * forceWindow and dictMatchState are therefore incompatible.
*/
MEM_STATIC void
ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
- void const* srcEnd,
- U32 maxDist,
- U32* loadedDictEndPtr,
+ const void* blockEnd,
+ U32 maxDist,
+ U32* loadedDictEndPtr,
const ZSTD_matchState_t** dictMatchStatePtr)
{
- U32 const blockEndIdx = (U32)((BYTE const*)srcEnd - window->base);
- U32 loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
- DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u",
- (unsigned)blockEndIdx, (unsigned)maxDist);
+ U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
+ U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
+ DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
+ (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
+
+ /* - When there is no dictionary : loadedDictEnd == 0.
+ In which case, the test (blockEndIdx > maxDist) is merely to avoid
+ overflowing next operation `newLowLimit = blockEndIdx - maxDist`.
+ - When there is a standard dictionary :
+ Index referential is copied from the dictionary,
+ which means it starts from 0.
+ In which case, loadedDictEnd == dictSize,
+ and it makes sense to compare `blockEndIdx > maxDist + dictSize`
+ since `blockEndIdx` also starts from zero.
+ - When there is an attached dictionary :
+ loadedDictEnd is expressed within the referential of the context,
+ so it can be directly compared against blockEndIdx.
+ */
if (blockEndIdx > maxDist + loadedDictEnd) {
U32 const newLowLimit = blockEndIdx - maxDist;
if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
@@ -708,10 +731,31 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
(unsigned)window->dictLimit, (unsigned)window->lowLimit);
window->dictLimit = window->lowLimit;
}
- if (loadedDictEndPtr)
- *loadedDictEndPtr = 0;
- if (dictMatchStatePtr)
- *dictMatchStatePtr = NULL;
+ /* On reaching window size, dictionaries are invalidated */
+ if (loadedDictEndPtr) *loadedDictEndPtr = 0;
+ if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
+ }
+}
+
+/* Similar to ZSTD_window_enforceMaxDist(),
+ * but only invalidates dictionary
+ * when input progresses beyond window size. */
+MEM_STATIC void
+ZSTD_checkDictValidity(ZSTD_window_t* window,
+ const void* blockEnd,
+ U32 maxDist,
+ U32* loadedDictEndPtr,
+ const ZSTD_matchState_t** dictMatchStatePtr)
+{
+ U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
+ U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
+ DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
+ (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
+
+ if (loadedDictEnd && (blockEndIdx > maxDist + loadedDictEnd)) {
+ /* On reaching window size, dictionaries are invalidated */
+ if (loadedDictEndPtr) *loadedDictEndPtr = 0;
+ if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
}
}
diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c
index 47faf6d641..5957255d90 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.c
+++ b/thirdparty/zstd/compress/zstd_double_fast.c
@@ -43,8 +43,7 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
/* Only load extra positions for ZSTD_dtlm_full */
if (dtlm == ZSTD_dtlm_fast)
break;
- }
- }
+ } }
}
@@ -63,7 +62,10 @@ size_t ZSTD_compressBlock_doubleFast_generic(
const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart;
const BYTE* anchor = istart;
- const U32 prefixLowestIndex = ms->window.dictLimit;
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
+ const U32 lowestValid = ms->window.dictLimit;
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
const BYTE* const prefixLowest = base + prefixLowestIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - HASH_READ_SIZE;
@@ -95,8 +97,15 @@ size_t ZSTD_compressBlock_doubleFast_generic(
dictCParams->chainLog : hBitsS;
const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictStart);
+ DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_generic");
+
assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);
+ /* if a dictionary is attached, it must be within window range */
+ if (dictMode == ZSTD_dictMatchState) {
+ assert(lowestValid + maxDistance >= endIndex);
+ }
+
/* init */
ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) {
@@ -138,7 +147,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
ip++;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
goto _match_stored;
}
@@ -147,7 +156,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
&& ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
ip++;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
goto _match_stored;
}
@@ -170,8 +179,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
offset = (U32)(current - dictMatchIndexL - dictIndexDelta);
while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
goto _match_found;
- }
- }
+ } }
if (matchIndexS > prefixLowestIndex) {
/* check prefix short match */
@@ -186,16 +194,14 @@ size_t ZSTD_compressBlock_doubleFast_generic(
if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) {
goto _search_next_long;
- }
- }
+ } }
ip += ((ip-anchor) >> kSearchStrength) + 1;
continue;
_search_next_long:
- {
- size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
+ { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
U32 const matchIndexL3 = hashLong[hl3];
const BYTE* matchL3 = base + matchIndexL3;
@@ -221,9 +227,7 @@ _search_next_long:
offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta);
while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
goto _match_found;
- }
- }
- }
+ } } }
/* if no long +1 match, explore the short match we found */
if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
@@ -242,7 +246,7 @@ _match_found:
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
_match_stored:
/* match found */
@@ -250,11 +254,14 @@ _match_stored:
anchor = ip;
if (ip <= ilimit) {
- /* Fill Table */
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
+ /* Complementary insertion */
+ /* done after iLimit test, as candidates could be > iend-8 */
+ { U32 const indexToInsert = current+2;
+ hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
+ hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
+ }
/* check immediate repcode */
if (dictMode == ZSTD_dictMatchState) {
@@ -278,8 +285,7 @@ _match_stored:
continue;
}
break;
- }
- }
+ } }
if (dictMode == ZSTD_noDict) {
while ( (ip <= ilimit)
@@ -294,14 +300,15 @@ _match_stored:
ip += rLength;
anchor = ip;
continue; /* faster when present ... (?) */
- } } } }
+ } } }
+ } /* while (ip < ilimit) */
/* save reps for next block */
rep[0] = offset_1 ? offset_1 : offsetSaved;
rep[1] = offset_2 ? offset_2 : offsetSaved;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
@@ -360,10 +367,15 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - 8;
- const U32 prefixStartIndex = ms->window.dictLimit;
const BYTE* const base = ms->window.base;
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 lowestValid = ms->window.lowLimit;
+ const U32 lowLimit = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
+ const U32 dictStartIndex = lowLimit;
+ const U32 dictLimit = ms->window.dictLimit;
+ const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;
const BYTE* const prefixStart = base + prefixStartIndex;
- const U32 dictStartIndex = ms->window.lowLimit;
const BYTE* const dictBase = ms->window.dictBase;
const BYTE* const dictStart = dictBase + dictStartIndex;
const BYTE* const dictEnd = dictBase + prefixStartIndex;
@@ -371,6 +383,10 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize);
+ /* if extDict is invalidated due to maxDistance, switch to "regular" variant */
+ if (prefixStartIndex == dictStartIndex)
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_noDict);
+
/* Search Loop */
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
@@ -396,7 +412,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
} else {
if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
@@ -407,7 +423,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
} else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
@@ -432,23 +448,27 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
}
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
} else {
ip += ((ip-anchor) >> kSearchStrength) + 1;
continue;
} }
- /* found a match : store it */
+ /* move to next sequence start */
ip += mLength;
anchor = ip;
if (ip <= ilimit) {
- /* Fill Table */
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ /* Complementary insertion */
+ /* done after iLimit test, as candidates could be > iend-8 */
+ { U32 const indexToInsert = current+2;
+ hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
+ hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
+ }
+
/* check immediate repcode */
while (ip <= ilimit) {
U32 const current2 = (U32)(ip-base);
@@ -475,7 +495,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
rep[1] = offset_2;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c
index ed997b441c..a05b8a47f1 100644
--- a/thirdparty/zstd/compress/zstd_fast.c
+++ b/thirdparty/zstd/compress/zstd_fast.c
@@ -13,7 +13,8 @@
void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
- void const* end, ZSTD_dictTableLoadMethod_e dtlm)
+ const void* const end,
+ ZSTD_dictTableLoadMethod_e dtlm)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32* const hashTable = ms->hashTable;
@@ -41,6 +42,7 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
} } } }
}
+
FORCE_INLINE_TEMPLATE
size_t ZSTD_compressBlock_fast_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -58,7 +60,10 @@ size_t ZSTD_compressBlock_fast_generic(
const BYTE* ip0 = istart;
const BYTE* ip1;
const BYTE* anchor = istart;
- const U32 prefixStartIndex = ms->window.dictLimit;
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 validStartIndex = ms->window.dictLimit;
+ const U32 prefixStartIndex = (endIndex - validStartIndex > maxDistance) ? endIndex - maxDistance : validStartIndex;
const BYTE* const prefixStart = base + prefixStartIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - HASH_READ_SIZE;
@@ -165,7 +170,7 @@ _match: /* Requires: ip0, match0, offcode */
rep[1] = offset_2 ? offset_2 : offsetSaved;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
@@ -222,8 +227,15 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
const U32 dictAndPrefixLength = (U32)(ip - prefixStart + dictEnd - dictStart);
const U32 dictHLog = dictCParams->hashLog;
- /* otherwise, we would get index underflow when translating a dict index
- * into a local index */
+ /* if a dictionary is still attached, it necessarily means that
+ * it is within window size. So we just check it. */
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 endIndex = (U32)((size_t)(ip - base) + srcSize);
+ assert(endIndex - prefixStartIndex <= maxDistance);
+ (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */
+
+ /* ensure there will be no no underflow
+ * when translating a dict index into a local index */
assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
/* init */
@@ -251,7 +263,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
} else if ( (matchIndex <= prefixStartIndex) ) {
size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);
U32 const dictMatchIndex = dictHashTable[dictHash];
@@ -271,7 +283,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
} /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
}
} else if (MEM_read32(match) != MEM_read32(ip)) {
/* it's not a match, and we're not going to check the dictionary */
@@ -286,7 +298,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
&& (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
}
/* match found */
@@ -327,7 +339,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
rep[1] = offset_2 ? offset_2 : offsetSaved;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
size_t ZSTD_compressBlock_fast_dictMatchState(
@@ -366,15 +378,24 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart;
const BYTE* anchor = istart;
- const U32 dictStartIndex = ms->window.lowLimit;
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 validLow = ms->window.lowLimit;
+ const U32 lowLimit = (endIndex - validLow > maxDistance) ? endIndex - maxDistance : validLow;
+ const U32 dictStartIndex = lowLimit;
const BYTE* const dictStart = dictBase + dictStartIndex;
- const U32 prefixStartIndex = ms->window.dictLimit;
+ const U32 dictLimit = ms->window.dictLimit;
+ const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit;
const BYTE* const prefixStart = base + prefixStartIndex;
const BYTE* const dictEnd = dictBase + prefixStartIndex;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - 8;
U32 offset_1=rep[0], offset_2=rep[1];
+ /* switch to "regular" variant if extDict is invalidated due to maxDistance */
+ if (prefixStartIndex == dictStartIndex)
+ return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);
+
/* Search Loop */
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
const size_t h = ZSTD_hashPtr(ip, hlog, mls);
@@ -394,7 +415,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
ip++;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
} else {
if ( (matchIndex < dictStartIndex) ||
(MEM_read32(match) != MEM_read32(ip)) ) {
@@ -410,7 +431,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
offset = current - matchIndex;
offset_2 = offset_1;
offset_1 = offset;
- ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
} }
/* found a match : store it */
@@ -445,7 +466,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
rep[1] = offset_2;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c
index 53f998a437..94d906c01f 100644
--- a/thirdparty/zstd/compress/zstd_lazy.c
+++ b/thirdparty/zstd/compress/zstd_lazy.c
@@ -83,7 +83,10 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
U32* largerPtr = smallerPtr + 1;
U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
U32 dummy32; /* to be nullified at the end */
- U32 const windowLow = ms->window.lowLimit;
+ U32 const windowValid = ms->window.lowLimit;
+ U32 const maxDistance = 1U << cParams->windowLog;
+ U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;
+
DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
current, dictLimit, windowLow);
@@ -239,7 +242,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
const BYTE* const base = ms->window.base;
U32 const current = (U32)(ip-base);
- U32 const windowLow = ms->window.lowLimit;
+ U32 const maxDistance = 1U << cParams->windowLog;
+ U32 const windowValid = ms->window.lowLimit;
+ U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;
U32* const bt = ms->chainTable;
U32 const btLog = cParams->chainLog - 1;
@@ -490,8 +495,10 @@ size_t ZSTD_HcFindBestMatch_generic (
const U32 dictLimit = ms->window.dictLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
- const U32 lowLimit = ms->window.lowLimit;
const U32 current = (U32)(ip-base);
+ const U32 maxDistance = 1U << cParams->windowLog;
+ const U32 lowValid = ms->window.lowLimit;
+ const U32 lowLimit = (current - lowValid > maxDistance) ? current - maxDistance : lowValid;
const U32 minChain = current > chainSize ? current - chainSize : 0;
U32 nbAttempts = 1U << cParams->searchLog;
size_t ml=4-1;
@@ -653,7 +660,6 @@ size_t ZSTD_compressBlock_lazy_generic(
/* init */
ip += (dictAndPrefixLength == 0);
- ms->nextToUpdate3 = ms->nextToUpdate;
if (dictMode == ZSTD_noDict) {
U32 const maxRep = (U32)(ip - prefixLowest);
if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
@@ -933,7 +939,6 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
U32 offset_1 = rep[0], offset_2 = rep[1];
/* init */
- ms->nextToUpdate3 = ms->nextToUpdate;
ip += (ip == prefixStart);
/* Match Loop */
diff --git a/thirdparty/zstd/compress/zstd_ldm.c b/thirdparty/zstd/compress/zstd_ldm.c
index 784d20f3ab..3dcf86e6e8 100644
--- a/thirdparty/zstd/compress/zstd_ldm.c
+++ b/thirdparty/zstd/compress/zstd_ldm.c
@@ -447,7 +447,7 @@ size_t ZSTD_ldm_generateSequences(
if (ZSTD_window_needOverflowCorrection(ldmState->window, chunkEnd)) {
U32 const ldmHSize = 1U << params->hashLog;
U32 const correction = ZSTD_window_correctOverflow(
- &ldmState->window, /* cycleLog */ 0, maxDist, src);
+ &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);
ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction);
}
/* 2. We enforce the maximum offset allowed.
diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c
index efb69d3267..e32e542e02 100644
--- a/thirdparty/zstd/compress/zstd_opt.c
+++ b/thirdparty/zstd/compress/zstd_opt.c
@@ -255,13 +255,13 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
* to provide a cost which is directly comparable to a match ending at same position */
static int ZSTD_litLengthContribution(U32 const litLength, const optState_t* const optPtr, int optLevel)
{
- if (optPtr->priceType >= zop_predef) return WEIGHT(litLength, optLevel);
+ if (optPtr->priceType >= zop_predef) return (int)WEIGHT(litLength, optLevel);
/* dynamic statistics */
{ U32 const llCode = ZSTD_LLcode(litLength);
- int const contribution = (LL_bits[llCode] * BITCOST_MULTIPLIER)
- + WEIGHT(optPtr->litLengthFreq[0], optLevel) /* note: log2litLengthSum cancel out */
- - WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
+ int const contribution = (int)(LL_bits[llCode] * BITCOST_MULTIPLIER)
+ + (int)WEIGHT(optPtr->litLengthFreq[0], optLevel) /* note: log2litLengthSum cancel out */
+ - (int)WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
#if 1
return contribution;
#else
@@ -278,7 +278,7 @@ static int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLe
const optState_t* const optPtr,
int optLevel)
{
- int const contribution = ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)
+ int const contribution = (int)ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)
+ ZSTD_litLengthContribution(litLength, optPtr, optLevel);
return contribution;
}
@@ -372,13 +372,15 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
/* Update hashTable3 up to ip (excluded)
Assumption : always within prefix (i.e. not within extDict) */
-static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE* const ip)
+static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
+ U32* nextToUpdate3,
+ const BYTE* const ip)
{
U32* const hashTable3 = ms->hashTable3;
U32 const hashLog3 = ms->hashLog3;
const BYTE* const base = ms->window.base;
- U32 idx = ms->nextToUpdate3;
- U32 const target = ms->nextToUpdate3 = (U32)(ip - base);
+ U32 idx = *nextToUpdate3;
+ U32 const target = (U32)(ip - base);
size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);
assert(hashLog3 > 0);
@@ -387,6 +389,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE*
idx++;
}
+ *nextToUpdate3 = target;
return hashTable3[hash3];
}
@@ -503,9 +506,11 @@ static U32 ZSTD_insertBt1(
} }
*smallerPtr = *largerPtr = 0;
- if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
- assert(matchEndIdx > current + 8);
- return matchEndIdx - (current + 8);
+ { U32 positions = 0;
+ if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */
+ assert(matchEndIdx > current + 8);
+ return MAX(positions, matchEndIdx - (current + 8));
+ }
}
FORCE_INLINE_TEMPLATE
@@ -520,8 +525,13 @@ void ZSTD_updateTree_internal(
DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)",
idx, target, dictMode);
- while(idx < target)
- idx += ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
+ while(idx < target) {
+ U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
+ assert(idx < (U32)(idx + forward));
+ idx += forward;
+ }
+ assert((size_t)(ip - base) <= (size_t)(U32)(-1));
+ assert((size_t)(iend - base) <= (size_t)(U32)(-1));
ms->nextToUpdate = target;
}
@@ -531,16 +541,18 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
FORCE_INLINE_TEMPLATE
U32 ZSTD_insertBtAndGetAllMatches (
+ ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */
ZSTD_matchState_t* ms,
+ U32* nextToUpdate3,
const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,
- U32 rep[ZSTD_REP_NUM],
+ const U32 rep[ZSTD_REP_NUM],
U32 const ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */
- ZSTD_match_t* matches,
const U32 lengthToBeat,
U32 const mls /* template */)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
+ U32 const maxDistance = 1U << cParams->windowLog;
const BYTE* const base = ms->window.base;
U32 const current = (U32)(ip-base);
U32 const hashLog = cParams->hashLog;
@@ -556,8 +568,9 @@ U32 ZSTD_insertBtAndGetAllMatches (
U32 const dictLimit = ms->window.dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
- U32 const btLow = btMask >= current ? 0 : current - btMask;
- U32 const windowLow = ms->window.lowLimit;
+ U32 const btLow = (btMask >= current) ? 0 : current - btMask;
+ U32 const windowValid = ms->window.lowLimit;
+ U32 const windowLow = ((current - windowValid) > maxDistance) ? current - maxDistance : windowValid;
U32 const matchLow = windowLow ? windowLow : 1;
U32* smallerPtr = bt + 2*(current&btMask);
U32* largerPtr = bt + 2*(current&btMask) + 1;
@@ -627,7 +640,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
/* HC3 match finder */
if ((mls == 3) /*static*/ && (bestLength < mls)) {
- U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, ip);
+ U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
if ((matchIndex3 >= matchLow)
& (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
size_t mlen;
@@ -653,9 +666,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
(ip+mlen == iLimit) ) { /* best possible length */
ms->nextToUpdate = current+1; /* skip insertion */
return 1;
- }
- }
- }
+ } } }
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
}
@@ -760,10 +771,13 @@ U32 ZSTD_insertBtAndGetAllMatches (
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
+ ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */
ZSTD_matchState_t* ms,
+ U32* nextToUpdate3,
const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
- U32 rep[ZSTD_REP_NUM], U32 const ll0,
- ZSTD_match_t* matches, U32 const lengthToBeat)
+ const U32 rep[ZSTD_REP_NUM],
+ U32 const ll0,
+ U32 const lengthToBeat)
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32 const matchLengthSearch = cParams->minMatch;
@@ -772,12 +786,12 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);
switch(matchLengthSearch)
{
- case 3 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 3);
+ case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3);
default :
- case 4 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 4);
- case 5 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 5);
+ case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4);
+ case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5);
case 7 :
- case 6 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 6);
+ case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6);
}
}
@@ -853,6 +867,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
+ U32 nextToUpdate3 = ms->nextToUpdate;
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
ZSTD_match_t* const matches = optStatePtr->matchTable;
@@ -862,7 +877,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
(U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);
assert(optLevel <= 2);
- ms->nextToUpdate3 = ms->nextToUpdate;
ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);
ip += (ip==prefixStart);
@@ -873,7 +887,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
/* find first match */
{ U32 const litlen = (U32)(ip - anchor);
U32 const ll0 = !litlen;
- U32 const nbMatches = ZSTD_BtGetAllMatches(ms, ip, iend, dictMode, rep, ll0, matches, minMatch);
+ U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
if (!nbMatches) { ip++; continue; }
/* initialize opt[0] */
@@ -970,7 +984,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
U32 const previousPrice = opt[cur].price;
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
- U32 const nbMatches = ZSTD_BtGetAllMatches(ms, inr, iend, dictMode, opt[cur].rep, ll0, matches, minMatch);
+ U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
U32 matchNb;
if (!nbMatches) {
DEBUGLOG(7, "rPos:%u : no match found", cur);
@@ -1094,7 +1108,7 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
} /* while (ip < ilimit) */
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
@@ -1158,7 +1172,6 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
ms->window.dictLimit += (U32)srcSize;
ms->window.lowLimit = ms->window.dictLimit;
ms->nextToUpdate = ms->window.dictLimit;
- ms->nextToUpdate3 = ms->window.dictLimit;
/* re-inforce weight of collected statistics */
ZSTD_upscaleStats(&ms->opt);
diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c
index 38fbb90768..9e537b8848 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.c
+++ b/thirdparty/zstd/compress/zstdmt_compress.c
@@ -1129,9 +1129,14 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
assert(flushed <= produced);
+ assert(jobPtr->consumed <= jobPtr->src.size);
toFlush = produced - flushed;
- if (toFlush==0 && (jobPtr->consumed >= jobPtr->src.size)) {
- /* doneJobID is not-fully-flushed, but toFlush==0 : doneJobID should be compressing some more data */
+ /* if toFlush==0, nothing is available to flush.
+ * However, jobID is expected to still be active:
+ * if jobID was already completed and fully flushed,
+ * ZSTDMT_flushProduced() should have already moved onto next job.
+ * Therefore, some input has not yet been consumed. */
+ if (toFlush==0) {
assert(jobPtr->consumed < jobPtr->src.size);
}
}
@@ -1148,12 +1153,16 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
static unsigned ZSTDMT_computeTargetJobLog(ZSTD_CCtx_params const params)
{
- if (params.ldmParams.enableLdm)
+ unsigned jobLog;
+ if (params.ldmParams.enableLdm) {
/* In Long Range Mode, the windowLog is typically oversized.
* In which case, it's preferable to determine the jobSize
* based on chainLog instead. */
- return MAX(21, params.cParams.chainLog + 4);
- return MAX(20, params.cParams.windowLog + 2);
+ jobLog = MAX(21, params.cParams.chainLog + 4);
+ } else {
+ jobLog = MAX(20, params.cParams.windowLog + 2);
+ }
+ return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX);
}
static int ZSTDMT_overlapLog_default(ZSTD_strategy strat)
@@ -1197,7 +1206,7 @@ static size_t ZSTDMT_computeOverlapSize(ZSTD_CCtx_params const params)
ovLog = MIN(params.cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2)
- overlapRLog;
}
- assert(0 <= ovLog && ovLog <= 30);
+ assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX);
DEBUGLOG(4, "overlapLog : %i", params.overlapLog);
DEBUGLOG(4, "overlap size : %i", 1 << ovLog);
return (ovLog==0) ? 0 : (size_t)1 << ovLog;
@@ -1391,7 +1400,7 @@ size_t ZSTDMT_initCStream_internal(
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) );
if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
- if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = ZSTDMT_JOBSIZE_MAX;
+ if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN); /* do not trigger multi-threading when srcSize is too small */
if (mtctx->singleBlockingThread) {
@@ -1432,6 +1441,8 @@ size_t ZSTDMT_initCStream_internal(
if (mtctx->targetSectionSize == 0) {
mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(params);
}
+ assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX);
+
if (params.rsyncable) {
/* Aim for the targetsectionSize as the average job size. */
U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);
diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h
index 12e6bcb3a3..12a526087d 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.h
+++ b/thirdparty/zstd/compress/zstdmt_compress.h
@@ -50,6 +50,7 @@
#ifndef ZSTDMT_JOBSIZE_MIN
# define ZSTDMT_JOBSIZE_MIN (1 MB)
#endif
+#define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30)
#define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
index 675596f5aa..e42872ad96 100644
--- a/thirdparty/zstd/decompress/zstd_decompress.c
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -360,8 +360,11 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
frameParameter_unsupported);
-
- return skippableHeaderSize + sizeU32;
+ {
+ size_t const skippableSize = skippableHeaderSize + sizeU32;
+ RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong);
+ return skippableSize;
+ }
}
/** ZSTD_findDecompressedSize() :
@@ -378,11 +381,10 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
size_t const skippableSize = readSkippableFrameSize(src, srcSize);
- if (ZSTD_isError(skippableSize))
- return skippableSize;
- if (srcSize < skippableSize) {
+ if (ZSTD_isError(skippableSize)) {
return ZSTD_CONTENTSIZE_ERROR;
}
+ assert(skippableSize <= srcSize);
src = (const BYTE *)src + skippableSize;
srcSize -= skippableSize;
@@ -467,6 +469,8 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
&& (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
+ assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
+ frameSizeInfo.compressedSize <= srcSize);
return frameSizeInfo;
} else {
const BYTE* ip = (const BYTE*)src;
@@ -529,7 +533,6 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
return frameSizeInfo.compressedSize;
}
-
/** ZSTD_decompressBound() :
* compatible with legacy mode
* `src` must point to the start of a ZSTD frame or a skippeable frame
@@ -546,6 +549,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
return ZSTD_CONTENTSIZE_ERROR;
+ assert(srcSize >= compressedSize);
src = (const BYTE*)src + compressedSize;
srcSize -= compressedSize;
bound += decompressedBound;
@@ -738,9 +742,8 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
(unsigned)magicNumber, ZSTD_MAGICNUMBER);
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
size_t const skippableSize = readSkippableFrameSize(src, srcSize);
- if (ZSTD_isError(skippableSize))
- return skippableSize;
- RETURN_ERROR_IF(srcSize < skippableSize, srcSize_wrong);
+ FORWARD_IF_ERROR(skippableSize);
+ assert(skippableSize <= srcSize);
src = (const BYTE *)src + skippableSize;
srcSize -= skippableSize;
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c
index a2a7eedcf2..24f4859c56 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.c
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.c
@@ -505,7 +505,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
*nbSeqPtr = nbSeq;
/* FSE table descriptors */
- RETURN_ERROR_IF(ip+4 > iend, srcSize_wrong); /* minimum possible size */
+ RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong); /* minimum possible size: 1 byte for symbol encoding types */
{ symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
@@ -637,9 +637,10 @@ size_t ZSTD_execSequence(BYTE* op,
if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
/* copy Literals */
- ZSTD_copy8(op, *litPtr);
if (sequence.litLength > 8)
- ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ ZSTD_wildcopy_16min(op, (*litPtr), sequence.litLength, ZSTD_no_overlap); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ else
+ ZSTD_copy8(op, *litPtr);
op = oLitEnd;
*litPtr = iLitEnd; /* update for next sequence */
@@ -686,13 +687,13 @@ size_t ZSTD_execSequence(BYTE* op,
if (oMatchEnd > oend-(16-MINMATCH)) {
if (op < oend_w) {
- ZSTD_wildcopy(op, match, oend_w - op);
+ ZSTD_wildcopy(op, match, oend_w - op, ZSTD_overlap_src_before_dst);
match += oend_w - op;
op = oend_w;
}
while (op < oMatchEnd) *op++ = *match++;
} else {
- ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst); /* works even if matchLength < 8 */
}
return sequenceLength;
}
@@ -717,9 +718,11 @@ size_t ZSTD_execSequenceLong(BYTE* op,
if (oLitEnd > oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, dictStart, dictEnd);
/* copy Literals */
- ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */
if (sequence.litLength > 8)
- ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ ZSTD_wildcopy_16min(op, *litPtr, sequence.litLength, ZSTD_no_overlap); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ else
+ ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */
+
op = oLitEnd;
*litPtr = iLitEnd; /* update for next sequence */
@@ -766,13 +769,13 @@ size_t ZSTD_execSequenceLong(BYTE* op,
if (oMatchEnd > oend-(16-MINMATCH)) {
if (op < oend_w) {
- ZSTD_wildcopy(op, match, oend_w - op);
+ ZSTD_wildcopy(op, match, oend_w - op, ZSTD_overlap_src_before_dst);
match += oend_w - op;
op = oend_w;
}
while (op < oMatchEnd) *op++ = *match++;
} else {
- ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst); /* works even if matchLength < 8 */
}
return sequenceLength;
}
@@ -889,6 +892,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
}
FORCE_INLINE_TEMPLATE size_t
+DONT_VECTORIZE
ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
@@ -918,6 +922,11 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
+ ZSTD_STATIC_ASSERT(
+ BIT_DStream_unfinished < BIT_DStream_completed &&
+ BIT_DStream_endOfBuffer < BIT_DStream_completed &&
+ BIT_DStream_completed < BIT_DStream_overflow);
+
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
nbSeq--;
{ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
@@ -930,6 +939,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
/* check if reached exact end */
DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
RETURN_ERROR_IF(nbSeq, corruption_detected);
+ RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected);
/* save reps for next block */
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
}
@@ -1131,6 +1141,7 @@ ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
static TARGET_ATTRIBUTE("bmi2") size_t
+DONT_VECTORIZE
ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
void* dst, size_t maxDstSize,
const void* seqStart, size_t seqSize, int nbSeq,
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
index 53470c18f3..a1910ee223 100644
--- a/thirdparty/zstd/zstd.h
+++ b/thirdparty/zstd/zstd.h
@@ -71,7 +71,7 @@ extern "C" {
/*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 4
-#define ZSTD_VERSION_RELEASE 0
+#define ZSTD_VERSION_RELEASE 1
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to check runtime library version */
@@ -82,16 +82,16 @@ ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to check runtime library v
#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
ZSTDLIB_API const char* ZSTD_versionString(void); /* requires v1.3.0+ */
-/***************************************
-* Default constant
-***************************************/
+/* *************************************
+ * Default constant
+ ***************************************/
#ifndef ZSTD_CLEVEL_DEFAULT
# define ZSTD_CLEVEL_DEFAULT 3
#endif
-/***************************************
-* Constants
-***************************************/
+/* *************************************
+ * Constants
+ ***************************************/
/* All magic numbers are supposed read/written to/from files/memory using little-endian convention */
#define ZSTD_MAGICNUMBER 0xFD2FB528 /* valid since v0.8.0 */
@@ -183,9 +183,14 @@ ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compres
***************************************/
/*= Compression context
* When compressing many times,
- * it is recommended to allocate a context just once, and re-use it for each successive compression operation.
+ * it is recommended to allocate a context just once,
+ * and re-use it for each successive compression operation.
* This will make workload friendlier for system's memory.
- * Use one context per thread for parallel execution in multi-threaded environments. */
+ * Note : re-using context is just a speed / resource optimization.
+ * It doesn't change the compression ratio, which remains identical.
+ * Note 2 : In multi-threaded environments,
+ * use one different context per thread for parallel execution.
+ */
typedef struct ZSTD_CCtx_s ZSTD_CCtx;
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
@@ -380,6 +385,7 @@ typedef enum {
* ZSTD_c_forceMaxWindow
* ZSTD_c_forceAttachDict
* ZSTD_c_literalCompressionMode
+ * ZSTD_c_targetCBlockSize
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly;
* also, the enums values themselves are unstable and can still change.
@@ -389,6 +395,7 @@ typedef enum {
ZSTD_c_experimentalParam3=1000,
ZSTD_c_experimentalParam4=1001,
ZSTD_c_experimentalParam5=1002,
+ ZSTD_c_experimentalParam6=1003,
} ZSTD_cParameter;
typedef struct {
@@ -657,17 +664,33 @@ ZSTDLIB_API size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
ZSTD_inBuffer* input,
ZSTD_EndDirective endOp);
+
+/* These buffer sizes are softly recommended.
+ * They are not required : ZSTD_compressStream*() happily accepts any buffer size, for both input and output.
+ * Respecting the recommended size just makes it a bit easier for ZSTD_compressStream*(),
+ * reducing the amount of memory shuffling and buffering, resulting in minor performance savings.
+ *
+ * However, note that these recommendations are from the perspective of a C caller program.
+ * If the streaming interface is invoked from some other language,
+ * especially managed ones such as Java or Go, through a foreign function interface such as jni or cgo,
+ * a major performance rule is to reduce crossing such interface to an absolute minimum.
+ * It's not rare that performance ends being spent more into the interface, rather than compression itself.
+ * In which cases, prefer using large buffers, as large as practical,
+ * for both input and output, to reduce the nb of roundtrips.
+ */
ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
-ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
+ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block. */
-/*******************************************************************************
- * This is a legacy streaming API, and can be replaced by ZSTD_CCtx_reset() and
- * ZSTD_compressStream2(). It is redundant, but is still fully supported.
+
+/* *****************************************************************************
+ * This following is a legacy streaming API.
+ * It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2().
+ * It is redundant, but remains fully supported.
* Advanced parameters and dictionary compression can only be used through the
* new API.
******************************************************************************/
-/**
+/*!
* Equivalent to:
*
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
@@ -675,16 +698,16 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output
* ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
*/
ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
-/**
+/*!
* Alternative for ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue).
* NOTE: The return value is different. ZSTD_compressStream() returns a hint for
* the next read size (if non-zero and not an error). ZSTD_compressStream2()
- * returns the number of bytes left to flush (if non-zero and not an error).
+ * returns the minimum nb of bytes left to flush (if non-zero and not an error).
*/
ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-/** Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_flush). */
+/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_flush). */
ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
-/** Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */
+/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */
ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
@@ -969,7 +992,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
#endif /* ZSTD_H_235446 */
-/****************************************************************************************
+/* **************************************************************************************
* ADVANCED AND EXPERIMENTAL FUNCTIONS
****************************************************************************************
* The definitions in the following section are considered experimental.
@@ -1037,6 +1060,10 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
#define ZSTD_LDM_HASHRATELOG_MIN 0
#define ZSTD_LDM_HASHRATELOG_MAX (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
+/* Advanced parameter bounds */
+#define ZSTD_TARGETCBLOCKSIZE_MIN 64
+#define ZSTD_TARGETCBLOCKSIZE_MAX ZSTD_BLOCKSIZE_MAX
+
/* internal */
#define ZSTD_HASHLOG3_MAX 17
@@ -1162,7 +1189,7 @@ typedef enum {
* however it does mean that all frame data must be present and valid. */
ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
-/** ZSTD_decompressBound() :
+/*! ZSTD_decompressBound() :
* `src` should point to the start of a series of ZSTD encoded and/or skippable frames
* `srcSize` must be the _exact_ size of this series
* (i.e. there should be a frame boundary at `src + srcSize`)
@@ -1409,6 +1436,11 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
*/
#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5
+/* Tries to fit compressed block size to be around targetCBlockSize.
+ * No target when targetCBlockSize == 0.
+ * There is no guarantee on compressed block size (default:0) */
+#define ZSTD_c_targetCBlockSize ZSTD_c_experimentalParam6
+
/*! ZSTD_CCtx_getParameter() :
* Get the requested compression parameter value, selected by enum ZSTD_cParameter,
* and store it into int* value.
@@ -1843,7 +1875,7 @@ typedef struct {
unsigned checksumFlag;
} ZSTD_frameHeader;
-/** ZSTD_getFrameHeader() :
+/*! ZSTD_getFrameHeader() :
* decode Frame Header, or requires larger `srcSize`.
* @return : 0, `zfhPtr` is correctly filled,
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
diff --git a/version.py b/version.py
index 09219f60ad..45817ed69f 100644
--- a/version.py
+++ b/version.py
@@ -2,7 +2,7 @@ short_name = "godot"
name = "Godot Engine"
major = 3
minor = 2
-status = "dev"
+status = "alpha"
module_config = ""
year = 2019
website = "https://godotengine.org"